Manual Page Result
0
Command: packetfilter | Section: 7 | Source: Digital UNIX | File: packetfilter.7.gz
packetfilter(7) Miscellaneous Information Manual packetfilter(7)
NAME
packetfilter - Ethernet packet filter
SYNOPSIS
options PACKETFILTER
DESCRIPTION
The packet filter pseudo-device driver provides a raw interface to Eth-
ernets and similar network data link layers. Packets received that are
not used by the kernel (for example, to support the IP and DECnet pro-
tocol families) are available through this mechanism. The packet fil-
ter driver is kernel-resident code provided by the DIGITAL UNIX operat-
ing system. The driver appears to applications as a set of character
special files, one for each open packet filter application. (Through-
out this reference page, the word file refers to such a character spe-
cial 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 ad-
ditional 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 mak-
ing 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 insuffi-
cient 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 speci-
fying the packet type. See <netinet/if_ether.h>. (802.3 pack-
ets 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 ad-
dress. 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 de-
claration 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 intel-
ligible on DIGITAL UNIX systems.
The packet filters treat the entire packet, including headers, as unin-
terpreted data. The user must supply the headers for transmitted pack-
ets (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) ref-
erence page), the application can apply several special ioctl requests
to an open packet filter file. The calls are divided into five cate-
gories: packet-filter specifying, packet handling, device configura-
tion, administrative, and miscellaneous.
The DIGITAL 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 in-
terface, 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[ENMAXFIL-
TERS]; };
A packet filter consists of a priority, the filter command list length
(in shortwords), and the filter command list itself. Each filter com-
mand 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 ex-
plicit literal.
Pushes a one. Is slightly faster than ENF_PUSHLIT with an ex-
plicit literal.
Pushes 0xFFFF. Is slightly faster than ENF_PUSHLIT with an ex-
plicit literal.
Pushes 0x00FF. Is slightly faster than ENF_PUSHLIT with an ex-
plicit literal.
Pushes 0xFF00. Is slightly faster than ENF_PUSHLIT with an ex-
plicit literal.
Defined as zero.
Binary Operators
When both an action and an operator are specified in the same short-
word, the action is performed, followed by the operation. You can com-
bine 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 Eth-
ernet 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 ac-
tion actually specifies the action followed by ENF_NOP, and specifying
only an operation actually specifies ENF_NOPUSH followed by the opera-
tion.
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 ac-
cording 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 ac-
cording 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 fol-
lowing 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 av-
erage 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 Reso-
lution 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 process-
ing 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 opera-
tion 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 EIOCALLOW-
PROMISC 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 de-
fined 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 fol-
lows 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 re-
arranged 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 be-
cause 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 in-
terface 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 en-
stamp structure begins is an integer multiple of the word-size of the
processor. For example, on a VAX, each enstamp is aligned on a long-
word 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 in-
teger 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 re-
quest 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 se-
lect(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 in-
put queue size to be set. If this is greater than the maximum
allowable size (see EIOCMAXBACKLOG later), it is set to the max-
imum. 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 trun-
cate received packets at a specified length. This action may im-
prove 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 ex-
ample, 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, stam-
plen; struct enstamp *stamp; int truncation = SIZE_OF_INTEREST-
ING_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 fol-
lowing 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 ap-
plications 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 des-
tination 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 su-
peruser with the /usr/sbin/ifconfig command, or the superuser
can configure an interface to go into promiscuous mode automati-
cally 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 ENCOPY-
ALL mode bit set. To do so, use EIOCSETIF to bind to the inter-
face, 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 indefi-
nitely 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 EIOCSR-
TIMEOUT and EIOCGRTIMEOUT.)
RESTRICTIONS
A previous restriction against accessing data words past approximately
the first hundred bytes in a packet has been removed. However, it be-
comes slightly more costly to examine words that are not near the be-
ginning 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
packetfilter(7)