2 .\" Copyright (C) 2006, Sun Microsystems, Inc. All Rights Reserved
3 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
4 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
5 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
6 .TH PFMOD 7M "Jun 18, 2006"
8 pfmod \- STREAMS Packet Filter Module
12 #include <sys/pfmod.h>
17 ioctl(\fIfd\fR, IPUSH, "pfmod");
23 \fBpfmod\fR is a \fBSTREAMS\fR module that subjects messages arriving on its
24 read queue to a packet filter and passes only those messages that the filter
25 accepts on to its upstream neighbor. Such filtering can be very useful for
26 user-level protocol implementations and for networking monitoring programs that
27 wish to view only specific types of events.
28 .SS "Read-side Behavior"
31 \fBpfmod\fR applies the current packet filter to all \fBM_DATA\fR and
32 \fBM_PROTO\fR messages arriving on its read queue. The module prepares these
33 messages for examination by first skipping over all leading \fBM_PROTO\fR
34 message blocks to arrive at the beginning of the message's data portion. If
35 there is no data portion, \fBpfmod\fR accepts the message and passes it along
36 to its upstream neighbor. Otherwise, the module ensures that the part of the
37 message's data that the packet filter might examine lies in contiguous memory,
38 calling the \fBpullupmsg\fR(9F) utility routine if necessary to force
39 contiguity. (Note: this action destroys any sharing relationships that the
40 subject message might have had with other messages.) Finally, it applies the
41 packet filter to the message's data, passing the entire message upstream to the
42 next module if the filter accepts, and discarding the message otherwise. See
43 PACKET FILTERS below for details on how the filter works.
46 If there is no packet filter yet in effect, the module acts as if the filter
47 exists but does nothing, implying that all incoming messages are accepted. The
48 ioctls section below describes how to associate a packet filter with an
49 instance of \fBpfmod\fR.
52 \fBpfmod\fR passes all other messages through unaltered to its upper neighbor.
53 .SS "Write-side Behavior"
56 \fBpfmod\fR intercepts \fBM_IOCTL\fR messages for the \fIioctl\fR described
57 below. The module passes all other messages through unaltered to its lower
62 \fBpfmod\fR responds to the following \fIioctl\fR.
66 \fB\fBPFIOCSETF\fR \fR
69 This \fIioctl\fR directs the module to replace its current packet filter, if
70 any, with the filter specified by the \fBstruct packetfilt\fR pointer named by
71 its final argument. This structure is defined in \fB<sys/pfmod.h>\fR as:
78 uchar_t Pf_Priority; /* priority of filter */
79 uchar_t Pf_FilterLen; /* length of filter cmd list */
80 ushort_t Pf_Filter[ENMAXFILTERS]; /* filter command list */
87 The \fBPf_Priority\fR field is included only for compatibility with other
88 packet filter implementations and is otherwise ignored. The packet filter
89 itself is specified in the \fBPf_Filter\fR array as a sequence of two-byte
90 commands, with the \fBPf_FilterLen\fR field giving the number of commands in
91 the sequence. This implementation restricts the maximum number of commands in a
92 filter (\fBENMAXFILTERS\fR) to 255. The next section describes the available
93 commands and their semantics.
97 A packet filter consists of the filter command list length (in units of
98 \fBushort_t\fRs), and the filter command list itself. (The priority field
99 mentioned above is ignored in this implementation.) Each filter command list
100 specifies a sequence of actions that operate on an internal stack of ushort_ts
101 ("shortwords") or an offset register. The offset register is initially zero.
102 Each shortword of the command list specifies an action and a binary operator.
103 Using _n_ as shorthand for the next shortword of the instruction stream and
104 _%oreg_ for the offset register, the list of actions is:
108 COMMAND SHORTWORDS ACTION
109 ENF_PUSHLIT 2 Push _n_ on the stack.
110 ENF_PUSHZERO 1 Push zero on the stack.
111 ENF_PUSHONE 1 Push one on the stack.
112 ENF_PUSHFFFF 1 Push 0xFFFF on the stack.
113 ENF_PUSHFF00 1 Push 0xFF00 on the stack.
114 ENF_PUSH00FF 1 Push 0x00FF on the stack.
115 ENF_LOAD_OFFSET 2 Load _n_ into _%oreg_.
116 ENF_BRTR 2 Branch forward _n_ shortwords if
117 the top element of the stack is
119 ENF_BRFL 2 Branch forward _n_ shortwords if
120 the top element of the stack is zero.
121 ENF_POP 1 Pop the top element from the stack.
122 ENF_PUSHWORD+m 1 Push the value of shortword (_m_ +
123 _%oreg_) of the packet onto the stack.
129 The binary operators can be from the set {\fBENF_EQ\fR, \fBENF_NEQ\fR,
130 \fBENF_LT\fR, \fBENF_LE\fR, \fBENF_GT\fR,\fBENF_GE\fR, \fBENF_AND\fR,
131 \fBENF_OR\fR, \fBENF_XOR\fR} which operate on the top two elements of the stack
132 and replace them with its result.
135 When both an action and operator are specified in the same shortword, the
136 action is performed followed by the operation.
139 The binary operator can also be from the set {\fBENF_COR\fR, \fBENF_CAND\fR,
140 \fBENF_CNOR\fR, \fBENF_CNAND\fR}. These are "short-circuit" operators, in that
141 they terminate the execution of the filter immediately if the condition they
142 are checking for is found, and continue otherwise. All pop two elements from
143 the stack and compare them for equality; \fBENF_CAND\fR returns false if the
144 result is false; \fBENF_COR\fR returns true if the result is true;
145 \fBENF_CNAND\fR returns true if the result is false; \fBENF_CNOR\fR returns
146 false if the result is true. Unlike the other binary operators, these four do
147 not leave a result on the stack, even if they continue.
150 The short-circuit operators should be used when possible, to reduce the amount
151 of time spent evaluating filters. When they are used, you should also arrange
152 the order of the tests so that the filter will succeed or fail as soon as
153 possible; for example, checking the \fBIP\fR destination field of a \fBUDP\fR
154 packet is more likely to indicate failure than the packet type field.
157 The special action \fBENF_NOPUSH\fR and the special operator \fBENF_NOP\fR can
158 be used to only perform the binary operation or to only push a value on the
159 stack. Since both are (conveniently) defined to be zero, indicating only an
160 action actually specifies the action followed by \fBENF_NOP\fR, and indicating
161 only an operation actually specifies \fBENF_NOPUSH\fR followed by the
165 After executing the filter command list, a non-zero value (true) left on top of
166 the stack (or an empty stack) causes the incoming packet to be accepted and a
167 zero value (false) causes the packet to be rejected. (If the filter exits as
168 the result of a short-circuit operator, the top-of-stack value is ignored.)
169 Specifying an undefined operation or action in the command list or performing
170 an illegal operation or action (such as pushing a shortword offset past the end
171 of the packet or executing a binary operator with fewer than two shortwords on
172 the stack) causes a filter to reject the packet.
176 The packet filter module is not dependent on any particular device driver or
177 module but is commonly used with datalink drivers such as the Ethernet driver.
178 If the underlying datalink driver supports the Data Link Provider Interface
179 (DLPI) message set, the appropriate \fBSTREAMS DLPI\fR messages must be issued
180 to attach the stream to a particular hardware device and bind a datalink
181 address to the stream before the underlying driver will route received packets
182 upstream. Refer to the \fBDLPI\fR Version 2 specification for details on this
186 The reverse \fBARP\fR daemon program may use code similar to the following
187 fragment to construct a filter that rejects all but \fBRARP\fR packets. That
188 is, it accepts only packets whose Ethernet type field has the value
189 \fBETHERTYPE_REVARP\fR. The filter works whether a VLAN is configured or not.
193 struct ether_header eh; /* used only for offset values */
194 struct packetfilt pf;
195 register ushort_t *fwp = pf.Pf_Filter;
199 * Push packet filter streams module.
201 if (ioctl(fd, I_PUSH, "pfmod") < 0)
205 * Set up filter. Offset is the displacement of the Ethernet
206 * type field from the beginning of the packet in units of
209 offset = ((uint_t) &eh.ether_type - (uint_t) &eh.ether_dhost) /
211 *fwp++ = ENF_PUSHWORD + offset;
212 *fwp++ = ENF_PUSHLIT;
213 *fwp++ = htons(ETHERTYPE_VLAN);
216 *fwp++ = 3; /* If this isn't ethertype VLAN, don't change oreg */
217 *fwp++ = ENF_LOAD_OFFSET;
218 *fwp++ = 2; /* size of the VLAN tag in words */
220 *fwp++ = ENF_PUSHWORD + offset;
221 *fwp++ = ENF_PUSHLIT;
222 *fwp++ = htons(ETHERTYPE_REVARP);
224 pf.Pf_FilterLen = fwp - &pf.PF_Filter[0];
230 This filter can be abbreviated by taking advantage of the ability to combine
231 actions and operations:
235 *fwp++ = ENF_PUSHWORD + offset;
236 *fwp++ = ENF_PUSHLIT | ENF_EQ;
237 *fwp++ = htons(ETHERTYPE_REVARP);
238 *fwp++ = htons(ETHERTYPE_VLAN);
239 *fwp++ = ENF_BRFL | ENF_NOP;
241 *fwp++ = ENF_LOAD_OFFSET | ENF_NOP;
243 *fwp++ = ENF_POP | ENF_NOP;
244 *fwp++ = ENF_PUSHWORD + offset;
245 *fwp++ = ENF_PUSHLIT | ENF_EQ;
246 *fwp++ = htons(ETHERTYPE_REVARP);
253 \fBbufmod\fR(7M), \fBdlpi\fR(7P), \fBpullupmsg\fR(9F)