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