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