Registers a receive filter to enable the reception of packets.
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. |
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.
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;
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:
|
Item | Description |
---|---|
0 | Indicates the operation was successful. |
The network demuxer may supply other return values.