ns_add_filter Network Service

Purpose

Registers a receive filter to enable the reception of packets.

Syntax

#include <sys/cdli.h>
#include <sys/ndd.h>

int ns_add_filter (nddp, filter, len, ns_user)
       struct ndd * nddp;
       caddr_t  filter;
       int  len;
       struct ns_user * ns_user;

Parameters

Item Description
nddp Specifies the ndd structure to which this add request applies.
filter Specifies the pointer to the receive filter.
len Specifies the length in bytes of the receive filter to which the filter parameter points.
ns_user Specifies the pointer to a ns_user structure that defines the user.

Description

The ns_add_filter network service registers a receive filter for the reception of packets and enables a network demuxer to route packets to the appropriate users. The add request is passed on to the nd_add_filter function of the demuxer for the specified NDD. The caller of the ns_add_filter network service is responsible for relinquishing filters before calling the ns_free network service.

Examples

The following example illustrates the ns_add_filter network service:

struct ns_8022 dl;
struct ns_user ns_user;
 
dl.filtertype = NS_LLC_DSAP_SNAP;
dl.dsap = 0xaa;
dl.orgcode[0] = 0x0;
dl.orgcode[1] = 0x0;
dl.orgcode[2] = 0x0;
dl.ethertype = 0x0800;

ns_user.isr = NULL;
ns_user.isr_data = NULL;
ns_user.protoq = &ipintrq;
ns_user.netisr = NETISR_IP;
ns_user.ifp = ifp;
ns_user.pkt_format = NS_PROTO_SNAP;

ns_add_filter(nddp, &dl, sizeof(dl), &ns_user);

There are two ways a user (that is, the entity that is interested in receiving incoming packets) can be invoked when a packet arrives. In the first method, a protocol queue can be defined in which incoming packets are queued upon receipt, and the specified netisr is scheduled to let the user know that there are new packets in the queue. For example, the preceding code assumes a network interrupt service request (netisr) with the name NETISR_IP has been defined. When a packet arrives for the specified user, the packet is queued on the specified protocol queue (in this case, ipintrq) and the NETISR_IP request is scheduled to be executed. Because of its complexity, this mode is not currently being used by any network user.

The preferred way of receiving incoming packets is by registering an interrupt service request (isr) function that handles incoming packets; ns_user.isr points to the function that will get invoked whenever a packet that matches the specified filter arrives. This function should expect the following four arguments:

void isr (ndd_t *nddp, mbuf *m, caddr_t macp, caddr_t extp)

where

Item Description
nddp Pointer to the ndd structure representing the adapter where the packet was received.
m Pointer to the mbuf structure representing the packet that was received.
macp Pointer to the start of the MAC header of the packet that was received.
extp Pointer to the (optional) structure specified in ns_user.isr_data, or NULL if none was specified.

In the following code, the function bpf_cdli_tap will be called when a new packet arrives; a pointer to the bp structure will be passed as the fourth parameter when bpf_cdli_tap is called.

dl.filtertype = NS_TAP;

ns_user.isr = bpf_cdli_tap;
ns_user.isr_data = (caddr_t) bp;
ns_user.protoq = (struct ifqueue *) NULL;
ns_user.netisr = 0;
ns_user.ifp = (struct ifnet *) NULL;
ns_user.pkt_format = NS_INCLUDE_MAC;
Note: Both modes of receiving packets are mutually exclusive. In other words, if the ns_user.protoq member is non-null, the protocol queue method is used; otherwise, the direct isr function method is used, and the ns_user.isr function pointer must be a valid function pointer.

In both cases, ns_user.ifp can optionally point to the ifnet structure of the interface where the packets will be received. If it is non-null, the state of the interface will be verified when a packet is received. If the interface is not up, the packet will be dropped and it will not be delivered to the user. If the interface is up, the statistics for the number of received packets will be incremented, and the ifp will be saved in the packet's mbuf structure's m_pkthdr.rcvif field.

The ns_user.pkt_format member determines how much of the MAC header the user is interested in receiving. Its possible values are:

Item Description
NS_PROTO Do not include the LLC header (but include the SNAP header, if there is one).
NS_PROTO_SNAP Do not include the LLC SNAP header (that is, remove the entire MAC header and deliver only the data).
NS_INCLUDE_LLC Include the LLC header.
NS_INCLUDE_MAC Include the entire MAC header.
NS_HANDLE_HEADERS Instead of passing the specified ns_user.isr_data structure by itself, build an isr_data_ext structure containing header information, as well as a pointer to the specified ns_user.isr_data. These are the fields that will be set in the isr_data_ext structure:
isr_data_ext.isr_data
Pointer to the structure passed as ns_user.isr_data.
isr_data_ext.dstp
Pointer to the destination MAC address.
isr_data_ext.dstlen
Length of the destination MAC address.
isr_data_ext.srcp
Pointer to the source MAC address.
isr_data_ext.seclen
Length of the source MAC address.
isr_data_ext.segp
Pointer to the routing segment.
isr_data_ext.seglen
Length of the routing segment.
isr_data_ext.llcp
Pointer to the LLC.
isr_data_ext.llclen
Length of the LLC.
It is possible to combine NS_HANDLE_HEADERS with one of the other flags by means of a logical OR operator (for example, ns_user.pkt_format = NS_INCLUDE_MAC | NS_HANDLE_HEADERS). The other flags, however, are mutually exclusive.

Return Values

Item Description
0 Indicates the operation was successful.

The network demuxer may supply other return values.