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