Content-type: text/html Man page of packetfilter

packetfilter

Section: Environments, Tables, and Troff Macros (7)
Index Return to Main Contents
 

NAME

packetfilter - Ethernet packet filter  

SYNOPSIS

options PACKETFILTER  

DESCRIPTION

The packet filter pseudo-device driver provides a raw interface to Ethernets and similar network data link layers. Packets received that are not used by the kernel (for example, to support the IP and DECnet protocol families) are available through this mechanism. The packet filter driver is kernel-resident code provided by the Tru64 UNIX operating system. The driver appears to applications as a set of character special files, one for each open packet filter application. (Throughout this reference page, the word file refers to such a character special file.)

To include packet filter support in your kernel, you must include the following option in your configuration file: options PACKETFILTER You must then reconfigure and rebuild your kernel using the doconfig command. For more information see the System Administration.

You create the minor device files with the MAKEDEV(8) script using these commands: # cd /dev # MAKEDEV pfilt A single call to MAKEDEV with an argument of pfilt creates 64 character special files in /dev/pf, which are named pfiltnnn, where nnn is the unit number. Successive calls to MAKEDEV with arguments of pfilt1, pfilt2, and pfilt3 make additional sets of 64 sequentially numbered packet filters to a maximum of 256. The maximum number of packet filter special files is limited to 256, which is the maximum number of minor device numbers allowed for each major device number. (See MAKEDEV(8) for more information on making system special files.)

For opening these special files, the operating system provides the pfopen(3) library routine. For more information, see pfopen(3).

Associated with each open instance of a packet filter special file is a user-settable packet filter ``program'' that is used to select which incoming packets are delivered by that packet filter special file. Whenever a packet is received from the net, the packet filter driver successively applies the filter programs of each of the open packet filter files to the packet, until one filter program ``accepts'' the packet. When a filter accepts the packet, it is placed on the packet input queue of the associated special file. If no filters accept the packet, it is discarded. The format of a packet filter is described later.

Reads from these files return the next packet from a queue of packets that have matched the filter. If the read operation specifies insufficient buffer space to store the entire packet, the packet is truncated and the trailing contents lost. Writes to these files transmit packets on the network, with each write operation generating exactly one packet.

The packet filter supports a variety of different Ethernet data-link levels:

Packets consist of fourteen or more bytes, with the first six bytes specifying the destination Ethernet address, the next six bytes the source Ethernet address, and the next two bytes specifying the packet type. See <netinet/if_ether.h>. (802.3 packets follow the same format, except that the last field gives the packet length).
FDDI packets start with a 13-byte header; the first byte is the ``frame control'' field, which is normally followed by a 6-byte (Ethernet-style) destination address and a 6-byte source address. For alignment reasons, the packet filter prepends a 3-byte padding field to incoming packets, and expects to see a corresponding padding field on transmitted packets. See the declaration for "struct fddi_header" in <netinet/if_fddi.h>. FDDI headers are usually followed by 802.2 headers; see <net/if_llc.h>. The remaining words are interpreted according to the packet type. Note that 16-bit and 32-bit quantities may have to be byteswapped (and possibly short-swapped) to be intelligible on Tru64 UNIX systems.

The packet filters treat the entire packet, including headers, as uninterpreted data. The user must supply the headers for transmitted packets (although the system makes sure that the source address is correct) and the headers of received packets are delivered to the user. The packet filter mechanism does not know anything about the data portion of the packets it sends and receives.

In addition to the FIONREAD ioctl request (described in the tty(7) reference page), the application can apply several special ioctl requests to an open packet filter file. The calls are divided into five categories: packet-filter specifying, packet handling, device configuration, administrative, and miscellaneous.

The Tru64 UNIX packet filter also supports most of the BSD Packet Filter (BPF) ioctl commands. This provides nearly complete source-level compatibility with existing BPF application code. The BPF packet filter format is quite different from the format described in this reference page and may be far more efficient or flexible for many applications. For more information on the BSD Packet Filter Extensions, see bpf(7).  

Packet-filter Specification ioctl Request

The EIOCSETF ioctl is central to the operation of the packet filter interface, because it specifies which packets the application wishes to receive. It is used to set the packet filter ``program'' for an open packet filter file, and is of the form: ioctl(fildes, EIOCSETF, filter) struct enfilter *filter The enfilter structure is defined in <net/pfilt.h> as:

struct enfilter {        u_char   enf_Priority;
       u_char   enf_FilterLen;
       u_short  enf_Filter[ENMAXFILTERS];
};

A packet filter consists of a priority, the filter command list length (in shortwords), and the filter command list itself. Each filter command list specifies a sequence of actions that operate on an internal stack. Each shortword of the command list specifies an action and a binary operator.  

Command List Actions

The action can be one of the following:
Pushes the next shortword of the command list on the stack.
Pushes shortword N of the incoming packet on the stack.
Pushes a zero. Is slightly faster than ENF_PUSHLIT with an explicit literal.
Pushes a one. Is slightly faster than ENF_PUSHLIT with an explicit literal.
Pushes 0xFFFF. Is slightly faster than ENF_PUSHLIT with an explicit literal.
Pushes 0x00FF. Is slightly faster than ENF_PUSHLIT with an explicit literal.
Pushes 0xFF00. Is slightly faster than ENF_PUSHLIT with an explicit literal.
Defined as zero.
 

Binary Operators

When both an action and an operator are specified in the same shortword, the action is performed, followed by the operation. You can combine an action with an operator using bitwise OR; for example,

((ENF_PUSHWORD+3) | ENF_EQ)

The binary operator, which can be one of the following, operates on the top two elements of the stack and replaces them with its result:

Returns true if the result is equal.
Returns true if the result is not equal.
Returns true if the result is less than.
Returns true if the result is less than or equal.
Returns true if the result is greater than.
Returns true if the result is greater than or equal.
Returns the result of the binary AND operation.
Returns the result of the binary OR operation.
Returns the result of the binary XOR operation.
Defined as zero.
Returns false immediately if the result is false, and continues execution of the filter otherwise. (Short-circuit operator)
Returns true immediately if the result is true, and continues execution of the filter otherwise. (Short-circuit operator)
Returns true immediately if the result is false, and continues execution of the filter otherwise. (Short-circuit operator)
Returns false immediately if the result is true, and continues execution of the filter otherwise. (Short-circuit operator) The short-circuit operators are so called because they terminate the execution of the filter immediately if the condition they are checking for is found, and continue otherwise. All the short-circuit operators pop two elements from the stack and compare them for equality. Unlike the other binary operators, these four operators do not leave a result on the stack, even if they continue.

Use the short-circuit operators whenever possible, to reduce the amount of time spent evaluating filters. When you use them, you should also arrange the order of the tests so that the filter will succeed or fail as soon as possible. For example, checking a word in an address field of an Ethernet packet is more likely to indicate failure than the Ethernet type field.

The special action ENF_NOPUSH and the special operator ENF_NOP can be used to only perform the binary operation or to only push a value on the stack. Because both are defined to be zero, specifying only an action actually specifies the action followed by ENF_NOP, and specifying only an operation actually specifies ENF_NOPUSH followed by the operation.

After executing the filter command list, a nonzero value (true) left on top of the stack (or an empty stack) causes the incoming packet to be accepted for the corresponding packet filter file and a zero value (false) causes the packet to be passed through the next packet filter. If the filter exits as the result of a short-circuit operator, the top-of-stack value is ignored. Specifying an undefined operation or action in the command list or performing an illegal operation or action (such as pushing a shortword offset past the end of the packet or executing a binary operator with fewer than two shortwords on the stack) causes a filter to reject the packet.

To resolve problems with overlapping or conflicting packet filters, the filters for each open packet filter file are ordered by the driver according to their priority (lowest priority is 0, highest is 255). When processing incoming packets, filters are applied according to their priority (from highest to lowest) and for identical priority values according to their relative ``busyness'' (the filter that has previously matched the most packets is checked first), until one or more filters accept the packet or all filters reject it and it is discarded.

Normally once a packet is delivered to a filter, it is not presented to any other filters. However, if the packet is accepted by a filter in nonexclusive mode (ENNONEXCL set using EIOCMBIS, described in the following section), the packet is passed along to lower-priority filters and may be delivered more than once. The use of nonexclusive filters imposes an additional cost on the system, because it increases the average number of filters applied to each packet.

The packet filter for a packet filter file is initialized with length 0 at priority 0 by open(2), and hence, by default, accepts all packets in which no higher-priority filter is interested.

Priorities should be assigned so that, in general, the more packets a filter is expected to match, the higher its priority. This prevents a lot of checking of packets against filters that are unlikely to match them.

The filter in this example accepts incoming RARP (Reverse Address Resolution Protocol) broadcast packets.

The filter first checks the Ethernet type of the packet. If it is not a RARP (Reverse ARP) packet, it is discarded. Then, the RARP type field is checked for a reverse request (type 3), followed by a check for a broadcast destination address. Note that the packet type field is checked before the destination address, because the total number of broadcast packets on the network is larger than the number of RARP packets. Thus, the filter is ordered with a minimum amount of processing overhead.

struct enfilter f;

buildfilter() {
    f.enf_Priority = 36;       /* anything > 2 should work */
    f.enf_FilterLen = 0;


    /* packet type is last short in header */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 6;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT;
    f.enf_Filter[f.enf_FilterLen++] = 0x3580;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_CAND;  /* Ethernet type == 0x8035 (RARP) */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 10;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT;
    f.enf_Filter[f.enf_FilterLen++] = 0x0300;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_CAND;  /* reverse request type = 0003 */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 0;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT;
    f.enf_Filter[f.enf_FilterLen++] = 0xFFFF;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_CAND;       /* dest addr = FF-FF */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 1;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT;
    f.enf_Filter[f.enf_FilterLen++] = 0xFFFF;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_CAND;       /* dest addr = FF-FF */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 2;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT;
    f.enf_Filter[f.enf_FilterLen++] = 0xFFFF;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_CAND;       /* dest addr = FF-FF */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 2;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT;
    f.enf_Filter[f.enf_FilterLen++] = 0xFFFF;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_EQ;         /* dest addr = FF-FF */
    return; }

Note that shortwords, such as the packet type field, are in network byte-order. The literals you compare them to may have to be byte-swapped on machines like the VAX.

By taking advantage of the ability to specify both an action and operation in each word of the command list, you could abbreviate the filter to the following:

struct enfilter f;

buildfilter() {
    f.enf_Priority = 36; /* anything > 2 should work */
    f.enf_FilterLen = 0;


    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 6;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;
    f.enf_Filter[f.enf_FilterLen++] =
        0x3580;          /* Ethernet type == 0x8035 (RARP) */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 10;
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;
    f.enf_Filter[f.enf_FilterLen++] =
        0x0300;          /* reverse request type = 0003 */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 0;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_PUSHFFFF | ENF_CAND; /* dest addr = FF-FF */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 1;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_PUSHFFFF | ENF_CAND; /* dest addr = FF-FF */
    f.enf_Filter[f.enf_FilterLen++] = ENF_PUSHWORD + 2;
    f.enf_Filter[f.enf_FilterLen++] =
        ENF_PUSHFFFF | ENF_EQ;   /* dest addr = FF-FF */
        return; }

 

Packet-Handling ioctl Requests

These ioctl requests control how the packet filter processes input packets and returns them to the application process. The most useful of these requests set and clear so-called ``mode bits'' for the file and are of this form:

ioctl(fildes, code, bits) u_short *bits;

In these calls, bits is a bitmask specifying which bits to set or clear. The applicable codes are:

Sets the specified mode bits.
Clears the specified mode bits.

The bits are:

If set, a received packet is preceded by a header structure (see the description of enstamp following) that includes a time stamp and other information.
If clear, each read(2) system call returns at most one packet. If set, a read call might return more than one packet, each of which is preceded by an enstamp header.
If set, this filter will be applied to promiscuously-received packets. This puts the interface into ``promiscuous mode'' only if this has been allowed by the superuser using the EIOCALLOWPROMISC ioctl call (described later).
If set, this filter will see packets sent and received by the kernel-resident protocols of the local host. (Normally, these packets are not copied to the packet filter.) This mode takes effect only if this has been allowed by the superuser using the EIOCALLOWCOPYALL ioctl call (described later).
If set, packets accepted by this filter will be available to any lower-priority filters. If clear, no lower-priority filter will see packets accepted by this filter.
If clear, means that the driver should disable the effect of EIOCENBS (described later) once it has delivered a signal. If set (the default), the effect of EIOCENBS persists.
If set, a received packet is preceded by a BPF-style header (see bpf(7). The enstamp structure contains useful information about the packet that immediately follows it; in ENBATCH mode, it also allows the reader to separate the packets in a batch. It is defined in <net/pfilt.h> as:

struct enstamp {        u_short         ens_stamplen;
       u_short         ens_flags;
       u_short         ens_count;
       u_short         ens_dropped;
       u_int           ens_ifoverflows;
       struct          timevalens_tstamp;
};

The fields are:

The length of enstamp structure in bytes. The packet data follows immediately.
Indicates how the packet was received. The bits are:
Received promiscuously (unicast to some other host).
Received as a broadcast.
Received as a multicast.
Received in a trailer encapsulation. The packet has been rearranged into header format.
The length of the packet in bytes (does not include the enstamp header).
The number of packets accepted by this filter but dropped because the input queue was full; this is a cumulative count since the previous enstamp was read from this packet filter file. This count may be completely wrong if the ENNONEXCL mode bit is set for this filter.
The total number of input overflows reported by the network interface since the system was booted.
The approximate time the packet was received.

If the buffer returned by a batched read(2) contains more than one packet, the offset from the beginning of the buffer at which each enstamp structure begins is an integer multiple of the word-size of the processor. For example, on a VAX, each enstamp is aligned on a longword boundary (provided that the buffer address passed to the read(2) system call is aligned). The alignment (in units of bytes) is given by the constant ENALIGNMENT, defined in <net/pfilt.h>. If you have an integer x, you can use the macro ENALIGNx to get the least integer that is a multiple of ENALIGNMENT and not less than x. For example, this code fragment reads and processes one batch:

char *buffer = &(BigBuffer[0]); int buflen; int pktlen, stamplen; struct enstamp *stamp;

buflen = read(f, buffer, sizeof(BigBuffer)); while (buflen > 0) {
    stamp = (struct enstamp *)buffer;
    pktlen = stamp->ens_count;
    stamplen = stamp->ens_stamplen;
    ProcessPacket(&(buffer[stamplen]), pktlen);   /* your code here */
    if (buflen == (pktlen + stamplen))
        break;                             /* last packet in batch */
    pktlen = ENALIGN(pktlen);     /* account for alignment padding */
    buflen -= (pktlen + stamplen);
    buffer += (pktlen + stamplen);          /* move to next stamp */ }

If a buffer filled by a batched read contains more than one packet, the final packet is never truncated. If, however, the entire buffer is not big enough to contain a single packet, the packet will be truncated; this is also true for unbatched reads. Therefore, the buffer passed to the read(2) system call should always be big enough to hold the largest possible packet plus an enstamp structure. (See the EIOCDEVP ioctl request later in this reference page for information on how to determine the maximum packet size. See also the EIOCTRUNCATE ioctl request for an example that delivers only the desired number of bytes of a packet.)

Normally, a packet filter application blocks in the read system call until a received packet is available for reading. There are several ways to avoid blocking indefinitely: an application can use the select(2) system call, it can set a ``timeout'' for the packet filter file, or it can request the delivery of a signal (see sigvec(2)) when a packet matches the filter.

The packet filter interface limits the number of packets that can be queued for delivery for a specific packet filter file. Application programs can vary this ``backlog'', if necessary, using the following call:

ioctl(fildes, EIOCSETW, maxwaitingp) u_int *maxwaitingp;

The argument maxwaitingp points to an integer containing the input queue size to be set. If this is greater than the maximum allowable size (see EIOCMAXBACKLOG later), it is set to the maximum. If it is zero, it is set to a default value.

After changing the packet filter program, the input queue may contain packets that were accepted under the old filter. To flush the queue of incoming packets, use the following:

ioctl(fildes, EIOCFLUSH, 0)

An application, such as a network load monitor, that does not want to see the entire packet can ask the packet filter to truncate received packets at a specified length. This action may improve performance by reducing data movement.
To specify truncation, use:

ioctl(fildes, EIOCTRUNCATE, truncationp) u_int *truncationp;

The argument truncationp points to an integer specifying the truncation length, in bytes. Packets shorter than this length are passed intact. This example, a revision of the previous example, illustrates the use of EIOCTRUNCATE, which causes the packet filter to deliver only the first n bytes of a packet, not the entire packet.

char *buffer = &(BigBuffer[0]); int buflen; int pktlen, stamplen; struct enstamp *stamp; int truncation = SIZE_OF_INTERESTING_PART_OF_PACKET;

if (ioctl(f, EIOCTRUNCATE, &truncation) < 0)
    exit(1);

while (1) {
    buflen = read(f, buffer, sizeof(BigBuffer));
    while (buflen > 0) {
       stamp = (struct enstamp *)buffer;
       pktlen = stamp->ens_count; /* ens_count is untruncated length */
       stamplen = stamp->ens_stamplen;


       ProcessPacket(&(buffer[stamplen]), pktlen); /* your code here */


       if (pktlen > truncation)   /* truncated portion not in buffer */
           pktlen = truncation;
       if (buflen == (pktlen + stamplen))
           break;                            /* last packet in batch */
       pktlen = ENALIGN(pktlen);    /* account for alignment padding */
       buflen -= (pktlen + stamplen);
       buffer += (pktlen + stamplen);          /* move to next stamp */
   } }

Two calls control the timeout mechanism; they are of the following form:

#include <net/time.h>

ioctl(fildes, code, tvp)

struct timeval *tvp;

The tvp argument is the address of a struct timeval containing the timeout interval (this is a relative value, not an absolute time). The codes are:

Returns the current timeout value.
Sets the timeout value. When the value is positive, a read(2) call returns a 0 if no packet arrives during the period. When the timeout value is zero, reads block indefinitely (this is the default). When the value is negative, a read(2) call returns a 0 immediately if there are no queued packets. Note that the largest legal timeout value is a few million seconds. Two calls control the signal-on-reception mechanism; they are of the following form:

ioctl(fildes, code, signp) u_int *signp;

The argument signp is a pointer to an integer containing the number of the signal to be sent when an input packet arrives. The applicable codes are:

Enables the specified signal when an input packet is received for this file. If the ENHOLDSIG flag (see EIOCMBIS later) is not set, further signals are automatically disabled whenever a signal is sent to prevent nesting, and hence must be explicitly re-enabled after processing. When the signal number is 0, this call is equivalent to EIOCINHS.
Disables signaling on packet reception. The signp argument is ignored. This is the default when the file is first opened.
 

Device Configuration ioctl Requests

Each packet filter file is associated with a specific network interface. To find out the name of the interface underlying the packet filter file, use the following:

#include <net/socket.h> #include <net/if.h>

ioctl(fildes, EIOCIFNAME, ifr) struct ifreq *ifr;

The interface name (for example, ``ln0'') is returned in ifr->ifr_name; other fields of the struct ifreq are not set.

To set the interface associated with a packet filter file, use the following:

ioctl(fildes, EIOCSETIF, ifr) struct ifreq *ifr;

The interface name should be passed ifr->ifr_name; other fields of the struct ifreq are ignored. The name provided may be one of the actual interface names, such as ``ln0'' or ``xna1'', or it may be a pseudo-interface name of the form ``pfn'', used to specify the nth interface attached to the system. For example, ``pf0'' specifies the first interface. This is useful for applications that do not know the names of specific interfaces. Pseudo-interface names are never returned by EIOCIFNAME.

To get device parameters of the network interface underlying the packet filter file, use the following:

ioctl(fildes, EIOCDEVP, param) struct endevp *param;

The endevp structure is defined in <net/pfilt.h> as:

struct endevp {        u_char   end_dev_type;
       u_char   end_addr_len;
       u_short  end_hdr_len;
       u_short  end_MTU;
       u_char   end_addr[EN_MAX_ADDR_LEN];
       u_char   end_broadaddr[EN_MAX_ADDR_LEN];
};

The fields are: Specifies the device type: ENDT_10MB or ENDT_FDDI. (ENDT_3MB and ENDT_BS3MB are defined but no longer supported.)

end_addr_len
Specifies the address length in bytes (for example, 1 or 6).
end_hdr_len
Specifies the total header length in bytes (for example, 4 or 14). Specifies the maximum packet size, including header, in bytes. The address of this interface; aligned so that the low order byte of the address is in end_addr[0]. The hardware destination address for broadcasts on this network.
 

Administrative ioctl Requests

The maximum queue length that can be set using EIOCSETW depends on whether the process is running as the superuser or not. If so, the maximum is a kernel constant; otherwise, the maximum is a value that can be set, by the superuser, for each interface. To set the maximum non-superuser backlog for an interface, use EIOCSETIF to bind to the interface, and then use the following:

ioctl(fildes, EIOCMAXBACKLOG, maxbacklogp) int *maxbacklogp;

The argument maxbacklogp points to an integer containing the maximum value. (If maxbacklogp points to an integer containing a negative value, it is replaced with the current backlog value, and no action is taken.)

EIOCALLOWPROMISC
Certain kinds of network-monitoring applications need to place the interface in ``promiscuous mode'', where it receives all packets on the network. Promiscuous mode can be set by the superuser with the /usr/sbin/ifconfig command, or the superuser can configure an interface to go into promiscuous mode automatically if any packet filter applications have the ENPROMISC mode bit set. To do so, use EIOCSETIF to bind to the interface, and then use the following:

ioctl(fildes, EIOCALLOWPROMISC, allowp) int *allowp;

The argument allowp points to an integer containing a Boolean value (nonzero means promiscuous mode is set automatically). (If allowp points to an integer containing a negative value, it is replaced with the current Boolean value, and no action is taken.)

EIOCALLOWCOPYALL
Certain promiscuous-mode network-monitoring applications need to see unicast packets sent or received by the local host. For reasons of efficiency, these packets are not normally provided to the packet filter, but in ``copy all'' mode they are. The superuser can configure an interface to go into copy-all mode automatically if any packet filter applications have the ENCOPYALL mode bit set. To do so, use EIOCSETIF to bind to the interface, and then use the following:

ioctl(fildes, EIOCALLOWCOPYALL, allowp) int *allowp;

The argument allowp points to an integer containing a Boolean value (nonzero means copy-all mode is set automatically). (If allowp points to an integer containing a negative value, it is replaced with the current Boolean value, and no action is taken.)

EIOCMFREE
To find out how many packet filter files remain for opening, use this ioctl, which places the number in the integer pointed to by mfree:

ioctl(fildes, EIOCMFREE, mfree) int *mfree;

 

Miscellaneous ioctl Requests

Two calls are provided for backwards compatibility and should not be used in new code. These calls are used to set and fetch parameters of a packet filter file (not the underlying device; see EIOCDEVP). The form for these calls is:

#include <sys/types.h> #include <net/pfilt.h>

ioctl(fildes, code, param)

struct eniocb *param;

The structure eniocb is defined in <net/pfilt.h> as:

struct eniocb {        u_char   en_addr;
       u_char   en_maxfilters;
       u_char   en_maxwaiting;
       u_char   en_maxpriority;
       int      en_rtout;
};

The applicable codes are: Fetch the parameters for this file. Set the parameters for this file. All the fields, which are described later, except en_rtout, are read-only. No longer maintained; use EIOCDEVP. The maximum length of a filter command list; see EIOCSETF. The maximum number of packets that can be queued for reading on the packet filter file; use EIOCMAXBACKLOG. The highest allowable filter priority; see EIOCSETF. The number of clock ticks to wait before timing out on a read request and returning a zero length. If zero, reads block indefinitely until a packet arrives. If negative, read requests return a zero length immediately if there are no packets in the input queue. Initialized to zero by open(2), indicating no timeout. (Use EIOCSRTIMEOUT and EIOCGRTIMEOUT.)  

RESTRICTIONS

A previous restriction against accessing data words past approximately the first hundred bytes in a packet has been removed. However, it becomes slightly more costly to examine words that are not near the beginning of the packet.

Because packets are streams of bytes, yet the filters operate on short words, and standard network byte order is usually opposite from little-endian byte-order, the relational operators ENF_LT, ENF_LE, ENF_GT, and ENF_GE are not particularly useful. If this becomes a severe problem, a byte-swapping operator could be added.  

FILES

Packet filter special files. Example packet filter program.  

RELATED INFORMATION

Commands: ifconfig(8), MAKEDEV(8), nfswatch(8), pfconfig(8), pfstat(1), tcpdump(8)

Files: bpf(7), fta(7), fza(7), ln(7), tty(7), xna(7) Routines: pfopen(3) delim off


 

Index

NAME
SYNOPSIS
DESCRIPTION
Packet-filter Specification ioctl Request
Command List Actions
Binary Operators
Packet-Handling ioctl Requests
Device Configuration ioctl Requests
Administrative ioctl Requests
Miscellaneous ioctl Requests
RESTRICTIONS
FILES
RELATED INFORMATION

This document was created by man2html, using the manual pages.
Time: 02:40:26 GMT, October 02, 2010