Fix buildworld.
[dragonfly.git] / contrib / libpcap / grammar.y
1 %{
2 /*
3  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that: (1) source code distributions
8  * retain the above copyright notice and this paragraph in its entirety, (2)
9  * distributions including binary code include the above copyright notice and
10  * this paragraph in its entirety in the documentation or other materials
11  * provided with the distribution, and (3) all advertising materials mentioning
12  * features or use of this software display the following acknowledgement:
13  * ``This product includes software developed by the University of California,
14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15  * the University nor the names of its contributors may be used to endorse
16  * or promote products derived from this software without specific prior
17  * written permission.
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21  *
22  */
23 #ifndef lint
24 static const char rcsid[] _U_ =
25     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
26 #endif
27
28 #define _KERNEL_STRUCTURES
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #ifdef WIN32
35 #include <pcap-stdinc.h>
36 #else /* WIN32 */
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #endif /* WIN32 */
40
41 #include <stdlib.h>
42
43 #ifndef WIN32
44 #if __STDC__
45 struct mbuf;
46 struct rtentry;
47 #endif
48
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
51 #endif /* WIN32 */
52
53 #include <stdio.h>
54
55 #include "pcap-int.h"
56
57 #include "gencode.h"
58 #ifdef HAVE_NET_PFVAR_H
59 #include <net/if.h>
60 #include <net/if_var.h>
61 #include <net/pf/pfvar.h>
62 #include <net/pf/if_pflog.h>
63 #endif
64 #include "ieee80211.h"
65 #include <pcap/namedb.h>
66
67 #ifdef HAVE_OS_PROTO_H
68 #include "os-proto.h"
69 #endif
70
71 #define QSET(q, p, d, a) (q).proto = (p),\
72                          (q).dir = (d),\
73                          (q).addr = (a)
74
75 struct tok {
76         int v;                  /* value */
77         const char *s;          /* string */
78 };
79
80 static const struct tok ieee80211_types[] = {
81         { IEEE80211_FC0_TYPE_DATA, "data" },
82         { IEEE80211_FC0_TYPE_MGT, "mgt" },
83         { IEEE80211_FC0_TYPE_MGT, "management" },
84         { IEEE80211_FC0_TYPE_CTL, "ctl" },
85         { IEEE80211_FC0_TYPE_CTL, "control" },
86         { 0, NULL }
87 };
88 static const struct tok ieee80211_mgt_subtypes[] = {
89         { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
90         { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
91         { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
92         { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
93         { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
94         { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
95         { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
96         { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
97         { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
98         { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
99         { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
100         { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
101         { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
102         { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
103         { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
104         { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
105         { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
106         { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
107         { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
108         { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
109         { 0, NULL }
110 };
111 static const struct tok ieee80211_ctl_subtypes[] = {
112         { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
113         { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
114         { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
115         { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
116         { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
117         { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
118         { 0, NULL }
119 };
120 static const struct tok ieee80211_data_subtypes[] = {
121         { IEEE80211_FC0_SUBTYPE_DATA, "data" },
122         { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
123         { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
124         { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
125         { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
126         { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
127         { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
128         { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
129         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
130         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
131         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
132         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
133         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
134         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
135         { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
136         { 0, NULL }
137 };
138 struct type2tok {
139         int type;
140         const struct tok *tok;
141 };
142 static const struct type2tok ieee80211_type_subtypes[] = {
143         { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
144         { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
145         { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
146         { 0, NULL }
147 };
148
149 static int
150 str2tok(const char *str, const struct tok *toks)
151 {
152         int i;
153
154         for (i = 0; toks[i].s != NULL; i++) {
155                 if (pcap_strcasecmp(toks[i].s, str) == 0)
156                         return (toks[i].v);
157         }
158         return (-1);
159 }
160
161 int n_errors = 0;
162
163 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
164
165 static void
166 yyerror(const char *msg)
167 {
168         ++n_errors;
169         bpf_error("%s", msg);
170         /* NOTREACHED */
171 }
172
173 #ifdef NEED_YYPARSE_WRAPPER
174 int yyparse(void);
175
176 int
177 pcap_parse()
178 {
179         return (yyparse());
180 }
181 #endif
182
183 #ifdef HAVE_NET_PFVAR_H
184 static int
185 pfreason_to_num(const char *reason)
186 {
187         const char *reasons[] = PFRES_NAMES;
188         int i;
189
190         for (i = 0; reasons[i]; i++) {
191                 if (pcap_strcasecmp(reason, reasons[i]) == 0)
192                         return (i);
193         }
194         bpf_error("unknown PF reason");
195         /*NOTREACHED*/
196 }
197
198 static int
199 pfaction_to_num(const char *action)
200 {
201         if (pcap_strcasecmp(action, "pass") == 0 ||
202             pcap_strcasecmp(action, "accept") == 0)
203                 return (PF_PASS);
204         else if (pcap_strcasecmp(action, "drop") == 0 ||
205                 pcap_strcasecmp(action, "block") == 0)
206                 return (PF_DROP);
207 #if HAVE_PF_NAT_THROUGH_PF_NORDR
208         else if (pcap_strcasecmp(action, "rdr") == 0)
209                 return (PF_RDR);
210         else if (pcap_strcasecmp(action, "nat") == 0)
211                 return (PF_NAT);
212         else if (pcap_strcasecmp(action, "binat") == 0)
213                 return (PF_BINAT);
214         else if (pcap_strcasecmp(action, "nordr") == 0)
215                 return (PF_NORDR);
216 #endif
217         else {
218                 bpf_error("unknown PF action");
219                 /*NOTREACHED*/
220         }
221 }
222 #else /* !HAVE_NET_PFVAR_H */
223 static int
224 pfreason_to_num(const char *reason)
225 {
226         bpf_error("libpcap was compiled on a machine without pf support");
227         /*NOTREACHED*/
228
229         /* this is to make the VC compiler happy */
230         return -1;
231 }
232
233 static int
234 pfaction_to_num(const char *action)
235 {
236         bpf_error("libpcap was compiled on a machine without pf support");
237         /*NOTREACHED*/
238
239         /* this is to make the VC compiler happy */
240         return -1;
241 }
242 #endif /* HAVE_NET_PFVAR_H */
243 %}
244
245 %union {
246         int i;
247         bpf_u_int32 h;
248         u_char *e;
249         char *s;
250         struct stmt *stmt;
251         struct arth *a;
252         struct {
253                 struct qual q;
254                 int atmfieldtype;
255                 int mtp3fieldtype;
256                 struct block *b;
257         } blk;
258         struct block *rblk;
259 }
260
261 %type   <blk>   expr id nid pid term rterm qid
262 %type   <blk>   head
263 %type   <i>     pqual dqual aqual ndaqual
264 %type   <a>     arth narth
265 %type   <i>     byteop pname pnum relop irelop
266 %type   <blk>   and or paren not null prog
267 %type   <rblk>  other pfvar p80211
268 %type   <i>     atmtype atmmultitype
269 %type   <blk>   atmfield
270 %type   <blk>   atmfieldvalue atmvalue atmlistvalue
271 %type   <i>     mtp2type
272 %type   <blk>   mtp3field
273 %type   <blk>   mtp3fieldvalue mtp3value mtp3listvalue
274
275
276 %token  DST SRC HOST GATEWAY
277 %token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
278 %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
279 %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
280 %token  TK_BROADCAST TK_MULTICAST
281 %token  NUM INBOUND OUTBOUND
282 %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
283 %token  TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
284 %token  LINK
285 %token  GEQ LEQ NEQ
286 %token  ID EID HID HID6 AID
287 %token  LSH RSH
288 %token  LEN
289 %token  IPV6 ICMPV6 AH ESP
290 %token  VLAN MPLS
291 %token  PPPOED PPPOES
292 %token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP 
293 %token  STP
294 %token  IPX
295 %token  NETBEUI
296 %token  LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
297 %token  OAM OAMF4 CONNECTMSG METACONNECT
298 %token  VPI VCI
299 %token  RADIO
300 %token  FISU LSSU MSU
301 %token  SIO OPC DPC SLS
302
303 %type   <s> ID
304 %type   <e> EID
305 %type   <e> AID
306 %type   <s> HID HID6
307 %type   <i> NUM action reason type subtype type_subtype dir
308
309 %left OR AND
310 %nonassoc  '!'
311 %left '|'
312 %left '&'
313 %left LSH RSH
314 %left '+' '-'
315 %left '*' '/'
316 %nonassoc UMINUS
317 %%
318 prog:     null expr
319 {
320         finish_parse($2.b);
321 }
322         | null
323         ;
324 null:     /* null */            { $$.q = qerr; }
325         ;
326 expr:     term
327         | expr and term         { gen_and($1.b, $3.b); $$ = $3; }
328         | expr and id           { gen_and($1.b, $3.b); $$ = $3; }
329         | expr or term          { gen_or($1.b, $3.b); $$ = $3; }
330         | expr or id            { gen_or($1.b, $3.b); $$ = $3; }
331         ;
332 and:      AND                   { $$ = $<blk>0; }
333         ;
334 or:       OR                    { $$ = $<blk>0; }
335         ;
336 id:       nid
337         | pnum                  { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
338                                                    $$.q = $<blk>0.q); }
339         | paren pid ')'         { $$ = $2; }
340         ;
341 nid:      ID                    { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
342         | HID '/' NUM           { $$.b = gen_mcode($1, NULL, $3,
343                                     $$.q = $<blk>0.q); }
344         | HID NETMASK HID       { $$.b = gen_mcode($1, $3, 0,
345                                     $$.q = $<blk>0.q); }
346         | HID                   {
347                                   /* Decide how to parse HID based on proto */
348                                   $$.q = $<blk>0.q;
349                                   if ($$.q.addr == Q_PORT)
350                                         bpf_error("'port' modifier applied to ip host");
351                                   else if ($$.q.addr == Q_PORTRANGE)
352                                         bpf_error("'portrange' modifier applied to ip host");
353                                   else if ($$.q.addr == Q_PROTO)
354                                         bpf_error("'proto' modifier applied to ip host");
355                                   else if ($$.q.addr == Q_PROTOCHAIN)
356                                         bpf_error("'protochain' modifier applied to ip host");
357                                   $$.b = gen_ncode($1, 0, $$.q);
358                                 }
359         | HID6 '/' NUM          {
360 #ifdef INET6
361                                   $$.b = gen_mcode6($1, NULL, $3,
362                                     $$.q = $<blk>0.q);
363 #else
364                                   bpf_error("'ip6addr/prefixlen' not supported "
365                                         "in this configuration");
366 #endif /*INET6*/
367                                 }
368         | HID6                  {
369 #ifdef INET6
370                                   $$.b = gen_mcode6($1, 0, 128,
371                                     $$.q = $<blk>0.q);
372 #else
373                                   bpf_error("'ip6addr' not supported "
374                                         "in this configuration");
375 #endif /*INET6*/
376                                 }
377         | EID                   { 
378                                   $$.b = gen_ecode($1, $$.q = $<blk>0.q);
379                                   /*
380                                    * $1 was allocated by "pcap_ether_aton()",
381                                    * so we must free it now that we're done
382                                    * with it.
383                                    */
384                                   free($1);
385                                 }
386         | AID                   {
387                                   $$.b = gen_acode($1, $$.q = $<blk>0.q);
388                                   /*
389                                    * $1 was allocated by "pcap_ether_aton()",
390                                    * so we must free it now that we're done
391                                    * with it.
392                                    */
393                                   free($1);
394                                 }
395         | not id                { gen_not($2.b); $$ = $2; }
396         ;
397 not:      '!'                   { $$ = $<blk>0; }
398         ;
399 paren:    '('                   { $$ = $<blk>0; }
400         ;
401 pid:      nid
402         | qid and id            { gen_and($1.b, $3.b); $$ = $3; }
403         | qid or id             { gen_or($1.b, $3.b); $$ = $3; }
404         ;
405 qid:      pnum                  { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
406                                                    $$.q = $<blk>0.q); }
407         | pid
408         ;
409 term:     rterm
410         | not term              { gen_not($2.b); $$ = $2; }
411         ;
412 head:     pqual dqual aqual     { QSET($$.q, $1, $2, $3); }
413         | pqual dqual           { QSET($$.q, $1, $2, Q_DEFAULT); }
414         | pqual aqual           { QSET($$.q, $1, Q_DEFAULT, $2); }
415         | pqual PROTO           { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
416         | pqual PROTOCHAIN      { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
417         | pqual ndaqual         { QSET($$.q, $1, Q_DEFAULT, $2); }
418         ;
419 rterm:    head id               { $$ = $2; }
420         | paren expr ')'        { $$.b = $2.b; $$.q = $1.q; }
421         | pname                 { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
422         | arth relop arth       { $$.b = gen_relation($2, $1, $3, 0);
423                                   $$.q = qerr; }
424         | arth irelop arth      { $$.b = gen_relation($2, $1, $3, 1);
425                                   $$.q = qerr; }
426         | other                 { $$.b = $1; $$.q = qerr; }
427         | atmtype               { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
428         | atmmultitype          { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
429         | atmfield atmvalue     { $$.b = $2.b; $$.q = qerr; }
430         | mtp2type              { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
431         | mtp3field mtp3value   { $$.b = $2.b; $$.q = qerr; }
432         ;
433 /* protocol level qualifiers */
434 pqual:    pname
435         |                       { $$ = Q_DEFAULT; }
436         ;
437 /* 'direction' qualifiers */
438 dqual:    SRC                   { $$ = Q_SRC; }
439         | DST                   { $$ = Q_DST; }
440         | SRC OR DST            { $$ = Q_OR; }
441         | DST OR SRC            { $$ = Q_OR; }
442         | SRC AND DST           { $$ = Q_AND; }
443         | DST AND SRC           { $$ = Q_AND; }
444         | ADDR1                 { $$ = Q_ADDR1; }
445         | ADDR2                 { $$ = Q_ADDR2; }
446         | ADDR3                 { $$ = Q_ADDR3; }
447         | ADDR4                 { $$ = Q_ADDR4; }
448         | RA                    { $$ = Q_RA; }
449         | TA                    { $$ = Q_TA; }
450         ;
451 /* address type qualifiers */
452 aqual:    HOST                  { $$ = Q_HOST; }
453         | NET                   { $$ = Q_NET; }
454         | PORT                  { $$ = Q_PORT; }
455         | PORTRANGE             { $$ = Q_PORTRANGE; }
456         ;
457 /* non-directional address type qualifiers */
458 ndaqual:  GATEWAY               { $$ = Q_GATEWAY; }
459         ;
460 pname:    LINK                  { $$ = Q_LINK; }
461         | IP                    { $$ = Q_IP; }
462         | ARP                   { $$ = Q_ARP; }
463         | RARP                  { $$ = Q_RARP; }
464         | SCTP                  { $$ = Q_SCTP; }
465         | TCP                   { $$ = Q_TCP; }
466         | UDP                   { $$ = Q_UDP; }
467         | ICMP                  { $$ = Q_ICMP; }
468         | IGMP                  { $$ = Q_IGMP; }
469         | IGRP                  { $$ = Q_IGRP; }
470         | PIM                   { $$ = Q_PIM; }
471         | VRRP                  { $$ = Q_VRRP; }
472         | CARP                  { $$ = Q_CARP; }
473         | ATALK                 { $$ = Q_ATALK; }
474         | AARP                  { $$ = Q_AARP; }
475         | DECNET                { $$ = Q_DECNET; }
476         | LAT                   { $$ = Q_LAT; }
477         | SCA                   { $$ = Q_SCA; }
478         | MOPDL                 { $$ = Q_MOPDL; }
479         | MOPRC                 { $$ = Q_MOPRC; }
480         | IPV6                  { $$ = Q_IPV6; }
481         | ICMPV6                { $$ = Q_ICMPV6; }
482         | AH                    { $$ = Q_AH; }
483         | ESP                   { $$ = Q_ESP; }
484         | ISO                   { $$ = Q_ISO; }
485         | ESIS                  { $$ = Q_ESIS; }
486         | ISIS                  { $$ = Q_ISIS; }
487         | L1                    { $$ = Q_ISIS_L1; }
488         | L2                    { $$ = Q_ISIS_L2; }
489         | IIH                   { $$ = Q_ISIS_IIH; }
490         | LSP                   { $$ = Q_ISIS_LSP; }
491         | SNP                   { $$ = Q_ISIS_SNP; }
492         | PSNP                  { $$ = Q_ISIS_PSNP; }
493         | CSNP                  { $$ = Q_ISIS_CSNP; }
494         | CLNP                  { $$ = Q_CLNP; }
495         | STP                   { $$ = Q_STP; }
496         | IPX                   { $$ = Q_IPX; }
497         | NETBEUI               { $$ = Q_NETBEUI; }
498         | RADIO                 { $$ = Q_RADIO; }
499         ;
500 other:    pqual TK_BROADCAST    { $$ = gen_broadcast($1); }
501         | pqual TK_MULTICAST    { $$ = gen_multicast($1); }
502         | LESS NUM              { $$ = gen_less($2); }
503         | GREATER NUM           { $$ = gen_greater($2); }
504         | CBYTE NUM byteop NUM  { $$ = gen_byteop($3, $2, $4); }
505         | INBOUND               { $$ = gen_inbound(0); }
506         | OUTBOUND              { $$ = gen_inbound(1); }
507         | VLAN pnum             { $$ = gen_vlan($2); }
508         | VLAN                  { $$ = gen_vlan(-1); }
509         | MPLS pnum             { $$ = gen_mpls($2); }
510         | MPLS                  { $$ = gen_mpls(-1); }
511         | PPPOED                { $$ = gen_pppoed(); }
512         | PPPOES                { $$ = gen_pppoes(); }
513         | pfvar                 { $$ = $1; }
514         | pqual p80211          { $$ = $2; }
515         ;
516
517 pfvar:    PF_IFNAME ID          { $$ = gen_pf_ifname($2); }
518         | PF_RSET ID            { $$ = gen_pf_ruleset($2); }
519         | PF_RNR NUM            { $$ = gen_pf_rnr($2); }
520         | PF_SRNR NUM           { $$ = gen_pf_srnr($2); }
521         | PF_REASON reason      { $$ = gen_pf_reason($2); }
522         | PF_ACTION action      { $$ = gen_pf_action($2); }
523         ;
524
525 p80211:   TYPE type SUBTYPE subtype
526                                 { $$ = gen_p80211_type($2 | $4,
527                                         IEEE80211_FC0_TYPE_MASK |
528                                         IEEE80211_FC0_SUBTYPE_MASK);
529                                 }
530         | TYPE type             { $$ = gen_p80211_type($2,
531                                         IEEE80211_FC0_TYPE_MASK);
532                                 }
533         | SUBTYPE type_subtype  { $$ = gen_p80211_type($2,
534                                         IEEE80211_FC0_TYPE_MASK |
535                                         IEEE80211_FC0_SUBTYPE_MASK);
536                                 }
537         | DIR dir               { $$ = gen_p80211_fcdir($2); }
538         ;
539
540 type:     NUM
541         | ID                    { $$ = str2tok($1, ieee80211_types);
542                                   if ($$ == -1)
543                                         bpf_error("unknown 802.11 type name");
544                                 }
545         ;
546
547 subtype:  NUM
548         | ID                    { const struct tok *types = NULL;
549                                   int i;
550                                   for (i = 0;; i++) {
551                                         if (ieee80211_type_subtypes[i].tok == NULL) {
552                                                 /* Ran out of types */
553                                                 bpf_error("unknown 802.11 type");
554                                                 break;
555                                         }
556                                         if ($<i>-1 == ieee80211_type_subtypes[i].type) {
557                                                 types = ieee80211_type_subtypes[i].tok;
558                                                 break;
559                                         }
560                                   }
561
562                                   $$ = str2tok($1, types);
563                                   if ($$ == -1)
564                                         bpf_error("unknown 802.11 subtype name");
565                                 }
566         ;
567
568 type_subtype:   ID              { int i;
569                                   for (i = 0;; i++) {
570                                         if (ieee80211_type_subtypes[i].tok == NULL) {
571                                                 /* Ran out of types */
572                                                 bpf_error("unknown 802.11 type name");
573                                                 break;
574                                         }
575                                         $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
576                                         if ($$ != -1) {
577                                                 $$ |= ieee80211_type_subtypes[i].type;
578                                                 break;
579                                         }
580                                   }
581                                 }
582                 ;
583
584 dir:      NUM
585         | ID                    { if (pcap_strcasecmp($1, "nods") == 0)
586                                         $$ = IEEE80211_FC1_DIR_NODS;
587                                   else if (pcap_strcasecmp($1, "tods") == 0)
588                                         $$ = IEEE80211_FC1_DIR_TODS;
589                                   else if (pcap_strcasecmp($1, "fromds") == 0)
590                                         $$ = IEEE80211_FC1_DIR_FROMDS;
591                                   else if (pcap_strcasecmp($1, "dstods") == 0)
592                                         $$ = IEEE80211_FC1_DIR_DSTODS;
593                                   else
594                                         bpf_error("unknown 802.11 direction");
595                                 }
596         ;
597
598 reason:   NUM                   { $$ = $1; }
599         | ID                    { $$ = pfreason_to_num($1); }
600         ;
601
602 action:   ID                    { $$ = pfaction_to_num($1); }
603         ;
604
605 relop:    '>'                   { $$ = BPF_JGT; }
606         | GEQ                   { $$ = BPF_JGE; }
607         | '='                   { $$ = BPF_JEQ; }
608         ;
609 irelop:   LEQ                   { $$ = BPF_JGT; }
610         | '<'                   { $$ = BPF_JGE; }
611         | NEQ                   { $$ = BPF_JEQ; }
612         ;
613 arth:     pnum                  { $$ = gen_loadi($1); }
614         | narth
615         ;
616 narth:    pname '[' arth ']'            { $$ = gen_load($1, $3, 1); }
617         | pname '[' arth ':' NUM ']'    { $$ = gen_load($1, $3, $5); }
618         | arth '+' arth                 { $$ = gen_arth(BPF_ADD, $1, $3); }
619         | arth '-' arth                 { $$ = gen_arth(BPF_SUB, $1, $3); }
620         | arth '*' arth                 { $$ = gen_arth(BPF_MUL, $1, $3); }
621         | arth '/' arth                 { $$ = gen_arth(BPF_DIV, $1, $3); }
622         | arth '&' arth                 { $$ = gen_arth(BPF_AND, $1, $3); }
623         | arth '|' arth                 { $$ = gen_arth(BPF_OR, $1, $3); }
624         | arth LSH arth                 { $$ = gen_arth(BPF_LSH, $1, $3); }
625         | arth RSH arth                 { $$ = gen_arth(BPF_RSH, $1, $3); }
626         | '-' arth %prec UMINUS         { $$ = gen_neg($2); }
627         | paren narth ')'               { $$ = $2; }
628         | LEN                           { $$ = gen_loadlen(); }
629         ;
630 byteop:   '&'                   { $$ = '&'; }
631         | '|'                   { $$ = '|'; }
632         | '<'                   { $$ = '<'; }
633         | '>'                   { $$ = '>'; }
634         | '='                   { $$ = '='; }
635         ;
636 pnum:     NUM
637         | paren pnum ')'        { $$ = $2; }
638         ;
639 atmtype: LANE                   { $$ = A_LANE; }
640         | LLC                   { $$ = A_LLC; }
641         | METAC                 { $$ = A_METAC; }
642         | BCC                   { $$ = A_BCC; }
643         | OAMF4EC               { $$ = A_OAMF4EC; }
644         | OAMF4SC               { $$ = A_OAMF4SC; }
645         | SC                    { $$ = A_SC; }
646         | ILMIC                 { $$ = A_ILMIC; }
647         ;
648 atmmultitype: OAM               { $$ = A_OAM; }
649         | OAMF4                 { $$ = A_OAMF4; }
650         | CONNECTMSG            { $$ = A_CONNECTMSG; }
651         | METACONNECT           { $$ = A_METACONNECT; }
652         ;
653         /* ATM field types quantifier */
654 atmfield: VPI                   { $$.atmfieldtype = A_VPI; }
655         | VCI                   { $$.atmfieldtype = A_VCI; }
656         ;
657 atmvalue: atmfieldvalue
658         | relop NUM             { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
659         | irelop NUM            { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
660         | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
661         ;
662 atmfieldvalue: NUM {
663         $$.atmfieldtype = $<blk>0.atmfieldtype;
664         if ($$.atmfieldtype == A_VPI ||
665             $$.atmfieldtype == A_VCI)
666                 $$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
667         }
668         ;
669 atmlistvalue: atmfieldvalue
670         | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
671         ;
672         /* MTP2 types quantifier */
673 mtp2type: FISU                  { $$ = M_FISU; }
674         | LSSU                  { $$ = M_LSSU; }
675         | MSU                   { $$ = M_MSU; }
676         ;
677         /* MTP3 field types quantifier */
678 mtp3field: SIO                  { $$.mtp3fieldtype = M_SIO; }
679         | OPC                   { $$.mtp3fieldtype = M_OPC; }
680         | DPC                   { $$.mtp3fieldtype = M_DPC; }
681         | SLS                   { $$.mtp3fieldtype = M_SLS; }
682         ;
683 mtp3value: mtp3fieldvalue
684         | relop NUM             { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
685         | irelop NUM            { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
686         | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
687         ;
688 mtp3fieldvalue: NUM {
689         $$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
690         if ($$.mtp3fieldtype == M_SIO ||
691             $$.mtp3fieldtype == M_OPC ||
692             $$.mtp3fieldtype == M_DPC ||
693             $$.mtp3fieldtype == M_SLS )
694                 $$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
695         }
696         ;
697 mtp3listvalue: mtp3fieldvalue
698         | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
699         ;
700 %%