1pfmod(7M)                       STREAMS Modules                      pfmod(7M)
2
3
4

NAME

6       pfmod - STREAMS Packet Filter Module
7

SYNOPSIS

9       #include <sys/pfmod.h>
10
11
12       ioctl(fd, IPUSH, "pfmod");
13
14

DESCRIPTION

16       pfmod  is  a STREAMS module that subjects messages arriving on its read
17       queue to a packet filter and passes only those messages that the filter
18       accepts  on to its upstream neighbor. Such filtering can be very useful
19       for user-level protocol implementations and for  networking  monitoring
20       programs that wish to view only specific types of events.
21
22   Read-side Behavior
23       pfmod  applies the current packet filter to all M_DATA and M_PROTO mes‐
24       sages arriving on its read queue. The module  prepares  these  messages
25       for  examination  by  first  skipping  over all leading M_PROTO message
26       blocks to arrive at the beginning of the  message's  data  portion.  If
27       there is no data portion, pfmod accepts the message and passes it along
28       to its upstream neighbor. Otherwise, the module ensures that  the  part
29       of the message's data that the packet filter might examine lies in con‐
30       tiguous memory, calling the pullupmsg(9F) utility routine if  necessary
31       to  force contiguity. (Note: this action destroys any sharing relation‐
32       ships that the subject message might have  had  with  other  messages.)
33       Finally,  it  applies  the packet filter to the message's data, passing
34       the entire message upstream to the next module if the  filter  accepts,
35       and  discarding  the  message  otherwise.  See PACKET FILTERS below for
36       details on how the filter works.
37
38
39       If there is no packet filter yet in effect, the module acts as  if  the
40       filter exists but does nothing, implying that all incoming messages are
41       accepted. The ioctls section below describes how to associate a  packet
42       filter with an instance of pfmod.
43
44
45       pfmod  passes  all other messages through unaltered to its upper neigh‐
46       bor.
47
48   Write-side Behavior
49       pfmod intercepts M_IOCTL messages for the ioctl  described  below.  The
50       module  passes all other messages through unaltered to its lower neigh‐
51       bor.
52

IOCTLS

54       pfmod responds to the following ioctl.
55
56       PFIOCSETF     This ioctl directs the  module  to  replace  its  current
57                     packet  filter,  if any, with the filter specified by the
58                     struct packetfilt pointer named by  its  final  argument.
59                     This structure is defined in <sys/pfmod.h> as:
60
61
62         struct packetfilt {
63          uchar_t  Pf_Priority;             /* priority of filter */
64          uchar_t  Pf_FilterLen;            /* length of filter cmd list */
65          ushort_t Pf_Filter[ENMAXFILTERS]; /* filter command list */
66         };
67
68
69
70       The  Pf_Priority  field  is  included only for compatibility with other
71       packet filter implementations and is otherwise ignored. The packet fil‐
72       ter  itself  is  specified in the Pf_Filter array as a sequence of two-
73       byte commands, with the Pf_FilterLen field giving the  number  of  com‐
74       mands in the sequence. This implementation restricts the maximum number
75       of commands in  a  filter  (ENMAXFILTERS)  to  255.  The  next  section
76       describes the available commands and their semantics.
77

PACKET FILTERS

79       A packet filter consists of the filter command list length (in units of
80       ushort_ts), and the filter command list  itself.  (The  priority  field
81       mentioned above is ignored in this implementation.) Each filter command
82       list specifies a sequence of actions that operate on an internal  stack
83       of ushort_ts  ("shortwords") or an offset register. The offset register
84       is  initially zero.  Each shortword of the command  list  specifies  an
85       action  and  a  binary  operator.   Using _n_ as shorthand for the next
86       shortword of the instruction stream and _%oreg_ for the  offset  regis‐
87       ter, the list of actions is:
88
89                COMMAND        SHORTWORDS  ACTION
90                ENF_PUSHLIT             2  Push _n_ on the stack.
91                ENF_PUSHZERO            1  Push zero on the stack.
92                ENF_PUSHONE             1  Push one on the stack.
93                ENF_PUSHFFFF            1  Push 0xFFFF on the stack.
94                ENF_PUSHFF00            1  Push 0xFF00 on the stack.
95                ENF_PUSH00FF            1  Push 0x00FF on the stack.
96                ENF_LOAD_OFFSET         2  Load _n_ into _%oreg_.
97                ENF_BRTR                2  Branch forward _n_ shortwords if
98                                           the top element of the stack is
99                                           non-zero.
100                ENF_BRFL                2  Branch forward _n_ shortwords if
101                                           the top element of the stack is zero.
102                ENF_POP                 1  Pop the top element from the stack.
103                ENF_PUSHWORD+m          1  Push the value of shortword (_m_ +
104                                           _%oreg_) of the packet onto the stack.
105
106
107
108       The  binary  operators  can  be  from the set {ENF_EQ, ENF_NEQ, ENF_LT,
109       ENF_LE, ENF_GT,ENF_GE, ENF_AND, ENF_OR, ENF_XOR} which operate  on  the
110       top two elements of the stack and replace them with its result.
111
112
113       When  both  an action and operator are specified in the same shortword,
114       the action is performed followed by the operation.
115
116
117       The binary operator can  also  be  from  the  set  {ENF_COR,  ENF_CAND,
118       ENF_CNOR, ENF_CNAND}. These are "short-circuit" operators, in that they
119       terminate the execution of the filter immediately if the condition they
120       are checking for is found, and continue otherwise. All pop two elements
121       from the stack and compare them for equality; ENF_CAND returns false if
122       the  result  is  false;  ENF_COR  returns  true  if the result is true;
123       ENF_CNAND returns true if the result is false; ENF_CNOR  returns  false
124       if the result is true. Unlike the other binary operators, these four do
125       not leave a result on the stack, even if they continue.
126
127
128       The short-circuit operators should be used when possible, to reduce the
129       amount of time spent evaluating filters. When they are used, you should
130       also arrange the order of the tests so that the filter will succeed  or
131       fail  as  soon  as  possible;  for example, checking the IP destination
132       field of a UDP packet is more  likely  to  indicate  failure  than  the
133       packet type field.
134
135
136       The  special  action ENF_NOPUSH and the special operator ENF_NOP can be
137       used to only perform the binary operation or to only push  a  value  on
138       the stack. Since both are (conveniently) defined to be zero, indicating
139       only an action actually specifies the action followed by  ENF_NOP,  and
140       indicating  only an operation actually specifies ENF_NOPUSH followed by
141       the operation.
142
143
144       After executing the filter command list, a non-zero value  (true)  left
145       on  top  of the stack (or an empty stack) causes the incoming packet to
146       be accepted and a zero value (false) causes the packet to be  rejected.
147       (If  the  filter  exits  as the result of a short-circuit operator, the
148       top-of-stack value is ignored.) Specifying an  undefined  operation  or
149       action in the command list or performing an illegal operation or action
150       (such as pushing a shortword offset past the end of the packet or  exe‐
151       cuting  a  binary operator with fewer than two shortwords on the stack)
152       causes a filter to reject the packet.
153

EXAMPLES

155       The packet filter module is not  dependent  on  any  particular  device
156       driver or module but is commonly used with datalink drivers such as the
157       Ethernet driver. If the underlying datalink driver  supports  the  Data
158       Link  Provider  Interface  (DLPI)  message set, the appropriate STREAMS
159       DLPI messages must be issued to attach the stream to a particular hard‐
160       ware device and bind a datalink address to the stream before the under‐
161       lying driver will route received packets upstream. Refer  to  the  DLPI
162       Version 2 specification for details on this interface.
163
164
165       The  reverse  ARP  daemon program may use code similar to the following
166       fragment  to construct a filter that rejects all but RARP packets. That
167       is,  it  accepts  only  packets whose Ethernet type field has the value
168       ETHERTYPE_REVARP. The filter works whether a VLAN is configured or not.
169
170         struct ether_header eh;       /* used only for offset values */
171         struct packetfilt pf;
172         register ushort_t *fwp = pf.Pf_Filter;
173         ushort_t offset;
174         int  fd;
175         /*
176          * Push packet filter streams module.
177          */
178         if (ioctl(fd, I_PUSH, "pfmod") < 0)
179              syserr("pfmod");
180
181         /*
182          * Set up filter.  Offset is the displacement of the Ethernet
183          * type field from the beginning of the packet in units of
184          * ushort_ts.
185          */
186         offset = ((uint_t) &eh.ether_type - (uint_t) &eh.ether_dhost) /
187                          sizeof (us_short);
188                *fwp++ = ENF_PUSHWORD + offset;
189                *fwp++ = ENF_PUSHLIT;
190                *fwp++ = htons(ETHERTYPE_VLAN);
191                *fwp++ = ENF_EQ;
192                *fwp++ = ENF_BRFL;
193                *fwp++ = 3;  /* If this isn't ethertype VLAN, don't change oreg */
194                *fwp++ = ENF_LOAD_OFFSET;
195                *fwp++ = 2;  /* size of the VLAN tag in words */
196                *fwp++ = ENF_POP;
197                *fwp++ = ENF_PUSHWORD + offset;
198                *fwp++ = ENF_PUSHLIT;
199                *fwp++ = htons(ETHERTYPE_REVARP);
200                *fwp++ = ENF_EQ;
201                pf.Pf_FilterLen = fwp - &pf.PF_Filter[0];
202
203
204
205       This filter can be abbreviated by taking advantage of  the  ability  to
206       combine actions and operations:
207
208                *fwp++ = ENF_PUSHWORD + offset;
209                *fwp++ = ENF_PUSHLIT | ENF_EQ;
210                *fwp++ = htons(ETHERTYPE_REVARP);
211                *fwp++ = htons(ETHERTYPE_VLAN);
212                *fwp++ = ENF_BRFL | ENF_NOP;
213                *fwp++ = 3;
214                *fwp++ = ENF_LOAD_OFFSET | ENF_NOP;
215                *fwp++ = 2;
216                *fwp++ = ENF_POP | ENF_NOP;
217                *fwp++ = ENF_PUSHWORD + offset;
218                *fwp++ = ENF_PUSHLIT | ENF_EQ;
219                *fwp++ = htons(ETHERTYPE_REVARP);
220
221

SEE ALSO

223       bufmod(7M), dlpi(7P), pullupmsg(9F)
224
225
226
227SunOS 5.11                       18 June 2006                        pfmod(7M)
Impressum