STREAMS Modules pfmod(7M)
NAME
pfmod - STREAMS Packet Filter Module
SYNOPSIS
#include
ioctl(fd, IPUSH, "pfmod");
DESCRIPTION
pfmod is a STREAMS module that subjects messages arriving on
its read queue to a packet filter and passes only those mes-
sages that the filter accepts on to its upstream neighbor.
Such filtering can be very useful for user-level protocol
implementations and for networking monitoring programs that
wish to view only specific types of events.
Read-side Behavior
pfmod applies the current packet filter to all MDATA and
MPROTO messages arriving on its read queue. The module
prepares these messages for examination by first skipping
over all leading MPROTO message blocks to arrive at the
beginning of the message's data portion. If there is no data
portion, pfmod accepts the message and passes it along to
its upstream neighbor. Otherwise, the module ensures that
the part of the message's data that the packet filter might
examine lies in contiguous memory, calling the pullupmsg(9F)
utility routine if necessary to force contiguity. (Note:
this action destroys any sharing relationships that the sub-
ject message might have had with other messages.) Finally,
it applies the packet filter to the message's data, passing
the entire message upstream to the next module if the filter
accepts, and discarding the message otherwise. See PACKET
FILTERS below for details on how the filter works.
If there is no packet filter yet in effect, the module acts
as if the filter exists but does nothing, implying that all
incoming messages are accepted. The ioctls section below
describes how to associate a packet filter with an instance
of pfmod.
pfmod passes all other messages through unaltered to its
upper neighbor.
Write-side Behavior
pfmod intercepts MIOCTL messages for the ioctl described
below. The module passes all other messages through unal-
tered to its lower neighbor.
SunOS 5.11 Last change: 18 June 2006 1
STREAMS Modules pfmod(7M)
IOCTLS
pfmod responds to the following ioctl.
PFIOCSETF This ioctl directs the module to replace its
current packet filter, if any, with the filter
specified by the struct packetfilt pointer
named by its final argument. This structure is
defined in as:
struct packetfilt {
uchart PfPriority; /* priority of filter */
uchart PfFilterLen; /* length of filter cmd list */
ushortt PfFilter[ENMAXFILTERS]; /* filter command list */
};
The PfPriority field is included only for compatibility
with other packet filter implementations and is otherwise
ignored. The packet filter itself is specified in the
PfFilter array as a sequence of two-byte commands, with the
PfFilterLen field giving the number of commands in the
sequence. This implementation restricts the maximum number
of commands in a filter (ENMAXFILTERS) to 255. The next sec-
tion describes the available commands and their semantics.
PACKET FILTERS
A packet filter consists of the filter command list length
(in units of ushortts), and the filter command list itself.
(The priority field mentioned above is ignored in this
implementation.) Each filter command list specifies a
sequence of actions that operate on an internal stack of
ushortts ("shortwords") or an offset register. The offset
register is initially zero. Each shortword of the command
list specifies an action and a binary operator. Using n
as shorthand for the next shortword of the instruction
stream and %oreg for the offset register, the list of
actions is:
COMAND SHORTWORDS ACTION
ENFPUSHLIT 2 Push n on the stack.
ENFPUSHZERO 1 Push zero on the stack.
ENFPUSHONE 1 Push one on the stack.
ENFPUSHF 1 Push 0xF on the stack.
ENFPUSHF00 1 Push 0xF00 on the stack.
ENFPUSH00F 1 Push 0x00F on the stack.
ENFLOADOFSET 2 Load n into %oreg.
ENFBRTR 2 Branch forward n shortwords if
the top element of the stack is
non-zero.
ENFBRFL 2 Branch forward n shortwords if
SunOS 5.11 Last change: 18 June 2006 2
STREAMS Modules pfmod(7M)
the top element of the stack is zero.
ENFPOP 1 Pop the top element from the stack.
ENFPUSHWORD]m 1 Push the value of shortword (m ]
%oreg) of the packet onto the stack.
The binary operators can be from the set {ENFEQ, ENFNEQ,
ENFLT, ENFLE, ENFGT,ENFGE, ENFAND, ENFOR, ENFXOR}
which operate on the top two elements of the stack and
replace them with its result.
When both an action and operator are specified in the same
shortword, the action is performed followed by the opera-
tion.
The binary operator can also be from the set {ENFCOR,
ENFCAND, ENFCNOR, ENFCNAND}. These are "short-circuit"
operators, in that they terminate the execution of the
filter immediately if the condition they are checking for is
found, and continue otherwise. All pop two elements from the
stack and compare them for equality; ENFCAND returns false
if the result is false; ENFCOR returns true if the result
is true; ENFCNAND returns true if the result is false;
ENFCNOR returns false if the result is true. Unlike the
other binary operators, these four do not leave a result on
the stack, even if they continue.
The short-circuit operators should be used when possible, to
reduce the amount of time spent evaluating filters. When
they are used, you should also arrange the order of the
tests so that the filter will succeed or fail as soon as
possible; for example, checking the IP destination field of
a UDP packet is more likely to indicate failure than the
packet type field.
The special action ENFNOPUSH and the special operator
ENFNOP can be used to only perform the binary operation or
to only push a value on the stack. Since both are (con-
veniently) defined to be zero, indicating only an action
actually specifies the action followed by ENFNOP, and indi-
cating only an operation actually specifies ENFNOPUSH fol-
lowed by the operation.
After executing the filter command list, a non-zero value
(true) left on top of the stack (or an empty stack) causes
the incoming packet to be accepted and a zero value (false)
SunOS 5.11 Last change: 18 June 2006 3
STREAMS Modules pfmod(7M)
causes the packet to be rejected. (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 opera-
tion 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.
EXAMPLES
The packet filter module is not dependent on any particular
device driver or module but is commonly used with datalink
drivers such as the Ethernet driver. If the underlying
datalink driver supports the Data Link Provider Interface
(DLPI) message set, the appropriate STREAMS DLPI messages
must be issued to attach the stream to a particular hardware
device and bind a datalink address to the stream before the
underlying driver will route received packets upstream.
Refer to the DLPI Version 2 specification for details on
this interface.
The reverse ARP daemon program may use code similar to the
following fragment to construct a filter that rejects all
but RARP packets. That is, it accepts only packets whose
Ethernet type field has the value ETHERTYPEREVARP. The
filter works whether a VLAN is configured or not.
struct etherheader eh; /* used only for offset values */
struct packetfilt pf;
register ushortt *fwp = pf.PfFilter;
ushortt offset;
int fd;
/*
* Push packet filter streams module.
*/
if (ioctl(fd, IPUSH, "pfmod") < 0)
syserr("pfmod");
/*
* Set up filter. Offset is the displacement of the Ethernet
* type field from the beginning of the packet in units of
* ushortts.
*/
offset = ((uintt) &eh.ethertype - (uintt) &eh.etherdhost) /
sizeof (usshort);
*fwp] = ENFPUSHWORD ] offset;
*fwp] = ENFPUSHLIT;
*fwp] = htons(ETHERTYPEVLAN);
*fwp] = ENFEQ;
*fwp] = ENFBRFL;
*fwp] = 3; /* If this isn't ethertype VLAN, don't change oreg */
SunOS 5.11 Last change: 18 June 2006 4
STREAMS Modules pfmod(7M)
*fwp] = ENFLOADOFSET;
*fwp] = 2; /* size of the VLAN tag in words */
*fwp] = ENFPOP;
*fwp] = ENFPUSHWORD ] offset;
*fwp] = ENFPUSHLIT;
*fwp] = htons(ETHERTYPEREVARP);
*fwp] = ENFEQ;
pf.PfFilterLen = fwp - &pf.PFilter[0];
This filter can be abbreviated by taking advantage of the
ability to combine actions and operations:
*fwp] = ENFPUSHWORD ] offset;
*fwp] = ENFPUSHLIT ENFEQ;
*fwp] = htons(ETHERTYPEREVARP);
*fwp] = htons(ETHERTYPEVLAN);
*fwp] = ENFBRFL ENFNOP;
*fwp] = 3;
*fwp] = ENFLOADOFSET ENFNOP;
*fwp] = 2;
*fwp] = ENFPOP ENFNOP;
*fwp] = ENFPUSHWORD ] offset;
*fwp] = ENFPUSHLIT ENFEQ;
*fwp] = htons(ETHERTYPEREVARP);
SEE ALSO
bufmod(7M), dlpi(7P), pullupmsg(9F)
SunOS 5.11 Last change: 18 June 2006 5
|