1/*
2 * We want a reentrant parser.
3 */
4@REENTRANT_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 * According to bison documentation, shift/reduce conflicts are not an issue
23 * in most parsers as long as the number does not evolve over time:
24 * https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html
25 * So, following the advice use %expect to check the amount of shift/reduce
26 * warnings.
27 *
28 * This doesn't appear to work in Berkeley YACC - 1.9 20170709; it still
29 * warns of 38 shift/reduce conflicts.
30 *
31 * The Berkeley YACC documentation:
32 *
33 *    https://invisible-island.net/byacc/manpage/yacc.html
34 *
35 * claims that "Bison's support for "%expect" is broken in more than one
36 * release.", but doesn't give details.  Hopefully, that only means that
37 * you get warnings even if you have the expected number of shift/reduce
38 * conflicts, not that anything else fails.
39 */
40%expect 38
41
42/*
43 * And we need to pass the compiler state to the scanner.
44 */
45%parse-param { compiler_state_t *cstate }
46
47%{
48/*
49 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
50 *        The Regents of the University of California.  All rights reserved.
51 *
52 * Redistribution and use in source and binary forms, with or without
53 * modification, are permitted provided that: (1) source code distributions
54 * retain the above copyright notice and this paragraph in its entirety, (2)
55 * distributions including binary code include the above copyright notice and
56 * this paragraph in its entirety in the documentation or other materials
57 * provided with the distribution, and (3) all advertising materials mentioning
58 * features or use of this software display the following acknowledgement:
59 * ``This product includes software developed by the University of California,
60 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
61 * the University nor the names of its contributors may be used to endorse
62 * or promote products derived from this software without specific prior
63 * written permission.
64 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
65 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
66 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
67 *
68 */
69
70#include <config.h>
71
72/*
73 * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
74 * (see ftmacros.h), so include it early.
75 */
76#include "gencode.h"
77#include "grammar.h"
78
79#include <stdlib.h>
80
81#ifndef _WIN32
82#include <sys/types.h>
83#include <sys/socket.h>
84
85#if __STDC__
86struct mbuf;
87struct rtentry;
88#endif
89
90#include <netinet/in.h>
91#include <arpa/inet.h>
92#endif /* _WIN32 */
93
94#include <stdio.h>
95
96#include "diag-control.h"
97
98#include "pcap-int.h"
99
100#include "scanner.h"
101
102#include "llc.h"
103#include "ieee80211.h"
104#include "pflog.h"
105#include <pcap/namedb.h>
106
107#ifdef HAVE_OS_PROTO_H
108#include "os-proto.h"
109#endif
110
111/*
112 * Work around some bugs in Berkeley YACC prior to the 2017-07-09
113 * release.
114 *
115 * The 2005-05-05 release was the first one to define YYPATCH, so
116 * we treat any release that either 1) doesn't define YYPATCH or
117 * 2) defines it to a value < 20170709 as being buggy.
118 */
119#if defined(YYBYACC) && (!defined(YYPATCH) || YYPATCH < 20170709)
120/*
121 * Both Berkeley YACC and Bison define yydebug (under whatever name
122 * it has) as a global, but Bison does so only if YYDEBUG is defined.
123 * Berkeley YACC, prior to the 2017-07-09 release, defines it even if
124 * YYDEBUG isn't defined; declare it here to suppress a warning.  The
125 * 2017-07-09 release fixes that.
126 */
127#if !defined(YYDEBUG)
128extern int yydebug;
129#endif
130
131/*
132 * In Berkeley YACC, prior to the 2017-07-09 release, yynerrs (under
133 * whatever name it has) is global, even if it's building a reentrant
134 * parser.  In Bison, and in the Berkeley YACC 2017-07-09 release and
135 * later, it's local in reentrant parsers.
136 *
137 * Declare it to squelch a warning.
138 */
139extern int yynerrs;
140#endif
141
142#define QSET(q, p, d, a) (q).proto = (unsigned char)(p),\
143                               (q).dir = (unsigned char)(d),\
144                               (q).addr = (unsigned char)(a)
145
146struct tok {
147          int v;                        /* value */
148          const char *s;                /* string */
149};
150
151static const struct tok ieee80211_types[] = {
152          { IEEE80211_FC0_TYPE_DATA, "data" },
153          { IEEE80211_FC0_TYPE_MGT, "mgt" },
154          { IEEE80211_FC0_TYPE_MGT, "management" },
155          { IEEE80211_FC0_TYPE_CTL, "ctl" },
156          { IEEE80211_FC0_TYPE_CTL, "control" },
157          { 0, NULL }
158};
159static const struct tok ieee80211_mgt_subtypes[] = {
160          { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
161          { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
162          { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
163          { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
164          { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
165          { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
166          { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
167          { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
168          { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
169          { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
170          { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
171          { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
172          { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
173          { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
174          { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
175          { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
176          { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
177          { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
178          { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
179          { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
180          { 0, NULL }
181};
182static const struct tok ieee80211_ctl_subtypes[] = {
183          { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
184          { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
185          { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
186          { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
187          { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
188          { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
189          { 0, NULL }
190};
191static const struct tok ieee80211_data_subtypes[] = {
192          { IEEE80211_FC0_SUBTYPE_DATA, "data" },
193          { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
194          { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
195          { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
196          { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
197          { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
198          { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
199          { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
200          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
201          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
202          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
203          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
204          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
205          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
206          { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
207          { 0, NULL }
208};
209static const struct tok llc_s_subtypes[] = {
210          { LLC_RR, "rr" },
211          { LLC_RNR, "rnr" },
212          { LLC_REJ, "rej" },
213          { 0, NULL }
214};
215static const struct tok llc_u_subtypes[] = {
216          { LLC_UI, "ui" },
217          { LLC_UA, "ua" },
218          { LLC_DISC, "disc" },
219          { LLC_DM, "dm" },
220          { LLC_SABME, "sabme" },
221          { LLC_TEST, "test" },
222          { LLC_XID, "xid" },
223          { LLC_FRMR, "frmr" },
224          { 0, NULL }
225};
226struct type2tok {
227          int type;
228          const struct tok *tok;
229};
230static const struct type2tok ieee80211_type_subtypes[] = {
231          { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
232          { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
233          { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
234          { 0, NULL }
235};
236
237static int
238str2tok(const char *str, const struct tok *toks)
239{
240          int i;
241
242          for (i = 0; toks[i].s != NULL; i++) {
243                    if (pcapint_strcasecmp(toks[i].s, str) == 0) {
244                              /*
245                               * Just in case somebody is using this to
246                               * generate values of -1/0xFFFFFFFF.
247                               * That won't work, as it's indistinguishable
248                               * from an error.
249                               */
250                              if (toks[i].v == -1)
251                                        abort();
252                              return (toks[i].v);
253                    }
254          }
255          return (-1);
256}
257
258static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
259
260static void
261yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
262{
263          bpf_set_error(cstate, "can't parse filter expression: %s", msg);
264}
265
266static const struct tok pflog_reasons[] = {
267          { PFRES_MATCH,                "match" },
268          { PFRES_BADOFF,               "bad-offset" },
269          { PFRES_FRAG,                 "fragment" },
270          { PFRES_SHORT,                "short" },
271          { PFRES_NORM,                 "normalize" },
272          { PFRES_MEMORY,               "memory" },
273          { PFRES_TS,                   "bad-timestamp" },
274          { PFRES_CONGEST,    "congestion" },
275          { PFRES_IPOPTIONS,  "ip-option" },
276          { PFRES_PROTCKSUM,  "proto-cksum" },
277          { PFRES_BADSTATE,   "state-mismatch" },
278          { PFRES_STATEINS,   "state-insert" },
279          { PFRES_MAXSTATES,  "state-limit" },
280          { PFRES_SRCLIMIT,   "src-limit" },
281          { PFRES_SYNPROXY,   "synproxy" },
282#if defined(__FreeBSD__)
283          { PFRES_MAPFAILED,  "map-failed" },
284#elif defined(__NetBSD__)
285          { PFRES_STATELOCKED,          "state-locked" },
286#elif defined(__OpenBSD__)
287          { PFRES_TRANSLATE,  "translate" },
288          { PFRES_NOROUTE,    "no-route" },
289#elif defined(__APPLE__)
290          { PFRES_DUMMYNET,   "dummynet" },
291#endif
292          { 0, NULL }
293};
294
295static int
296pfreason_to_num(compiler_state_t *cstate, const char *reason)
297{
298          int i;
299
300          i = str2tok(reason, pflog_reasons);
301          if (i == -1)
302                    bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
303          return (i);
304}
305
306static const struct tok pflog_actions[] = {
307          { PF_PASS,                    "pass" },
308          { PF_PASS,                    "accept" },         /* alias for "pass" */
309          { PF_DROP,                    "drop" },
310          { PF_DROP,                    "block" },          /* alias for "drop" */
311          { PF_SCRUB,                   "scrub" },
312          { PF_NOSCRUB,                 "noscrub" },
313          { PF_NAT,           "nat" },
314          { PF_NONAT,                   "nonat" },
315          { PF_BINAT,                   "binat" },
316          { PF_NOBINAT,                 "nobinat" },
317          { PF_RDR,           "rdr" },
318          { PF_NORDR,                   "nordr" },
319          { PF_SYNPROXY_DROP, "synproxy-drop" },
320#if defined(__FreeBSD__)
321          { PF_DEFER,                   "defer" },
322#elif defined(__OpenBSD__)
323          { PF_DEFER,                   "defer" },
324          { PF_MATCH,                   "match" },
325          { PF_DIVERT,                  "divert" },
326          { PF_RT,            "rt" },
327          { PF_AFRT,                    "afrt" },
328#elif defined(__APPLE__)
329          { PF_DUMMYNET,                "dummynet" },
330          { PF_NODUMMYNET,    "nodummynet" },
331          { PF_NAT64,                   "nat64" },
332          { PF_NONAT64,                 "nonat64" },
333#endif
334          { 0, NULL },
335};
336
337static int
338pfaction_to_num(compiler_state_t *cstate, const char *action)
339{
340          int i;
341
342          i = str2tok(action, pflog_actions);
343          if (i == -1)
344                    bpf_set_error(cstate, "unknown PF action \"%s\"", action);
345          return (i);
346}
347
348/*
349 * For calls that might return an "an error occurred" value.
350 */
351#define CHECK_INT_VAL(val)    if (val == -1) YYABORT
352#define CHECK_PTR_VAL(val)    if (val == NULL) YYABORT
353
354DIAG_OFF_BISON_BYACC
355%}
356
357%union {
358          int i;
359          bpf_u_int32 h;
360          char *s;
361          struct stmt *stmt;
362          struct arth *a;
363          struct {
364                    struct qual q;
365                    int atmfieldtype;
366                    int mtp3fieldtype;
367                    struct block *b;
368          } blk;
369          struct block *rblk;
370}
371
372%type     <blk>     expr id nid pid term rterm qid
373%type     <blk>     head
374%type     <i>       pqual dqual aqual ndaqual
375%type     <a>       arth narth
376%type     <i>       byteop pname relop irelop
377%type     <h>       pnum
378%type     <blk>     and or paren not null prog
379%type     <rblk>    other pfvar p80211 pllc
380%type     <i>       atmtype atmmultitype
381%type     <blk>     atmfield
382%type     <blk>     atmfieldvalue atmvalue atmlistvalue
383%type     <i>       mtp2type
384%type     <blk>     mtp3field
385%type     <blk>     mtp3fieldvalue mtp3value mtp3listvalue
386
387
388%token  DST SRC HOST GATEWAY
389%token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
390%token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
391%token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
392%token  TK_BROADCAST TK_MULTICAST
393%token  NUM INBOUND OUTBOUND
394%token  IFINDEX
395%token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
396%token    TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
397%token  LINK
398%token    GEQ LEQ NEQ
399%token    ID EID HID HID6 AID
400%token    LSH RSH
401%token  LEN
402%token  IPV6 ICMPV6 AH ESP
403%token    VLAN MPLS
404%token    PPPOED PPPOES GENEVE
405%token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
406%token  STP
407%token  IPX
408%token  NETBEUI
409%token    LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
410%token    OAM OAMF4 CONNECTMSG METACONNECT
411%token    VPI VCI
412%token    RADIO
413%token    FISU LSSU MSU HFISU HLSSU HMSU
414%token    SIO OPC DPC SLS HSIO HOPC HDPC HSLS
415%token    LEX_ERROR
416
417%type     <s> ID EID AID
418%type     <s> HID HID6
419%type     <h> NUM
420%type     <i> action reason type subtype type_subtype dir
421
422%left OR AND
423%nonassoc  '!'
424%left '|'
425%left '&'
426%left LSH RSH
427%left '+' '-'
428%left '*' '/'
429%nonassoc UMINUS
430%%
431prog:       null expr
432{
433          /*
434           * I'm not sure we have a reason to use yynerrs, but it's
435           * declared, and incremented, whether we need it or not,
436           * which means that Clang 15 will give a "used but not
437           * set" warning.  This should suppress the warning for
438           * yynerrs without suppressing it for other variables.
439           */
440          (void) yynerrs;
441          CHECK_INT_VAL(finish_parse(cstate, $2.b));
442}
443          | null
444          ;
445null:       /* null */                  { $$.q = qerr; }
446          ;
447expr:       term
448          | expr and term               { gen_and($1.b, $3.b); $$ = $3; }
449          | expr and id                 { gen_and($1.b, $3.b); $$ = $3; }
450          | expr or term                { gen_or($1.b, $3.b); $$ = $3; }
451          | expr or id                  { gen_or($1.b, $3.b); $$ = $3; }
452          ;
453and:        AND                         { $$ = $<blk>0; }
454          ;
455or:         OR                          { $$ = $<blk>0; }
456          ;
457id:         nid
458          | pnum                        { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
459                                                               $$.q = $<blk>0.q))); }
460          | paren pid ')'               { $$ = $2; }
461          ;
462nid:        ID                          { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
463          | HID '/' NUM                 {
464                                          CHECK_PTR_VAL($1);
465                                          /* Check whether HID/NUM is being used when appropriate */
466                                          $$.q = $<blk>0.q;
467                                          if ($$.q.addr == Q_PORT) {
468                                                  bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length");
469                                                  YYABORT;
470                                          } else if ($$.q.addr == Q_PORTRANGE) {
471                                                  bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length");
472                                                  YYABORT;
473                                          } else if ($$.q.addr == Q_PROTO) {
474                                                  bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length");
475                                                  YYABORT;
476                                          } else if ($$.q.addr == Q_PROTOCHAIN) {
477                                                  bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length");
478                                                  YYABORT;
479                                          }
480                                          CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3, $$.q)));
481                                        }
482          | HID NETMASK HID   {
483                                          CHECK_PTR_VAL($1);
484                                          /* Check whether HID mask HID is being used when appropriate */
485                                          $$.q = $<blk>0.q;
486                                          if ($$.q.addr == Q_PORT) {
487                                                  bpf_set_error(cstate, "'port' modifier applied to IP address and netmask");
488                                                  YYABORT;
489                                          } else if ($$.q.addr == Q_PORTRANGE) {
490                                                  bpf_set_error(cstate, "'portrange' modifier applied to IP address and netmask");
491                                                  YYABORT;
492                                          } else if ($$.q.addr == Q_PROTO) {
493                                                  bpf_set_error(cstate, "'proto' modifier applied to IP address and netmask");
494                                                  YYABORT;
495                                          } else if ($$.q.addr == Q_PROTOCHAIN) {
496                                                  bpf_set_error(cstate, "'protochain' modifier applied to IP address and netmask");
497                                                  YYABORT;
498                                          }
499                                          CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0, $$.q)));
500                                        }
501          | HID                         {
502                                          CHECK_PTR_VAL($1);
503                                          /* Check whether HID is being used when appropriate */
504                                          $$.q = $<blk>0.q;
505                                          if ($$.q.addr == Q_PORT) {
506                                                  bpf_set_error(cstate, "'port' modifier applied to IP address");
507                                                  YYABORT;
508                                          } else if ($$.q.addr == Q_PORTRANGE) {
509                                                  bpf_set_error(cstate, "'portrange' modifier applied to IP address");
510                                                  YYABORT;
511                                          } else if ($$.q.addr == Q_PROTO) {
512                                                  bpf_set_error(cstate, "'proto' modifier applied to IP address");
513                                                  YYABORT;
514                                          } else if ($$.q.addr == Q_PROTOCHAIN) {
515                                                  bpf_set_error(cstate, "'protochain' modifier applied to IP address");
516                                                  YYABORT;
517                                          }
518                                          CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
519                                        }
520          | HID6 '/' NUM                {
521                                          CHECK_PTR_VAL($1);
522#ifdef INET6
523                                          /* Check whether HID6/NUM is being used when appropriate */
524                                          $$.q = $<blk>0.q;
525                                          if ($$.q.addr == Q_PORT) {
526                                                  bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length");
527                                                  YYABORT;
528                                          } else if ($$.q.addr == Q_PORTRANGE) {
529                                                  bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length");
530                                                  YYABORT;
531                                          } else if ($$.q.addr == Q_PROTO) {
532                                                  bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length ");
533                                                  YYABORT;
534                                          } else if ($$.q.addr == Q_PROTOCHAIN) {
535                                                  bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length");
536                                                  YYABORT;
537                                          }
538                                          CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, $3, $$.q)));
539#else
540                                          bpf_set_error(cstate, "IPv6 addresses not supported "
541                                                  "in this configuration");
542                                          YYABORT;
543#endif /*INET6*/
544                                        }
545          | HID6                        {
546                                          CHECK_PTR_VAL($1);
547#ifdef INET6
548                                          /* Check whether HID6 is being used when appropriate */
549                                          $$.q = $<blk>0.q;
550                                          if ($$.q.addr == Q_PORT) {
551                                                  bpf_set_error(cstate, "'port' modifier applied to IP address");
552                                                  YYABORT;
553                                          } else if ($$.q.addr == Q_PORTRANGE) {
554                                                  bpf_set_error(cstate, "'portrange' modifier applied to IP address");
555                                                  YYABORT;
556                                          } else if ($$.q.addr == Q_PROTO) {
557                                                  bpf_set_error(cstate, "'proto' modifier applied to 'ip6addr/prefixlen");
558                                                  YYABORT;
559                                          } else if ($$.q.addr == Q_PROTOCHAIN) {
560                                                  bpf_set_error(cstate, "'protochain' modifier applied to IP address");
561                                                  YYABORT;
562                                          }
563                                          CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 128, $$.q)));
564#else
565                                          bpf_set_error(cstate, "IPv6 addresses not supported "
566                                                  "in this configuration");
567                                          YYABORT;
568#endif /*INET6*/
569                                        }
570          | EID                         { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
571          | AID                         { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
572          | not id            { gen_not($2.b); $$ = $2; }
573          ;
574not:        '!'                         { $$ = $<blk>0; }
575          ;
576paren:      '('                         { $$ = $<blk>0; }
577          ;
578pid:        nid
579          | qid and id                  { gen_and($1.b, $3.b); $$ = $3; }
580          | qid or id                   { gen_or($1.b, $3.b); $$ = $3; }
581          ;
582qid:        pnum                        { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
583                                                               $$.q = $<blk>0.q))); }
584          | pid
585          ;
586term:       rterm
587          | not term                    { gen_not($2.b); $$ = $2; }
588          ;
589head:       pqual dqual aqual { QSET($$.q, $1, $2, $3); }
590          | pqual dqual                 { QSET($$.q, $1, $2, Q_DEFAULT); }
591          | pqual aqual                 { QSET($$.q, $1, Q_DEFAULT, $2); }
592          | pqual PROTO                 { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
593          | pqual PROTOCHAIN  {
594#ifdef NO_PROTOCHAIN
595                                          bpf_set_error(cstate, "protochain not supported");
596                                          YYABORT;
597#else
598                                          QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
599#endif
600                                        }
601          | pqual ndaqual               { QSET($$.q, $1, Q_DEFAULT, $2); }
602          ;
603rterm:      head id           { $$ = $2; }
604          | paren expr ')'    { $$.b = $2.b; $$.q = $1.q; }
605          | pname                       { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
606          | arth relop arth   { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
607                                          $$.q = qerr; }
608          | arth irelop arth  { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
609                                          $$.q = qerr; }
610          | other                       { $$.b = $1; $$.q = qerr; }
611          | atmtype           { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
612          | atmmultitype                { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
613          | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
614          | mtp2type                    { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
615          | mtp3field mtp3value         { $$.b = $2.b; $$.q = qerr; }
616          ;
617/* protocol level qualifiers */
618pqual:      pname
619          |                             { $$ = Q_DEFAULT; }
620          ;
621/* 'direction' qualifiers */
622dqual:      SRC                         { $$ = Q_SRC; }
623          | DST                         { $$ = Q_DST; }
624          | SRC OR DST                  { $$ = Q_OR; }
625          | DST OR SRC                  { $$ = Q_OR; }
626          | SRC AND DST                 { $$ = Q_AND; }
627          | DST AND SRC                 { $$ = Q_AND; }
628          | ADDR1                       { $$ = Q_ADDR1; }
629          | ADDR2                       { $$ = Q_ADDR2; }
630          | ADDR3                       { $$ = Q_ADDR3; }
631          | ADDR4                       { $$ = Q_ADDR4; }
632          | RA                          { $$ = Q_RA; }
633          | TA                          { $$ = Q_TA; }
634          ;
635/* address type qualifiers */
636aqual:      HOST                        { $$ = Q_HOST; }
637          | NET                         { $$ = Q_NET; }
638          | PORT                        { $$ = Q_PORT; }
639          | PORTRANGE                   { $$ = Q_PORTRANGE; }
640          ;
641/* non-directional address type qualifiers */
642ndaqual:  GATEWAY             { $$ = Q_GATEWAY; }
643          ;
644pname:      LINK                        { $$ = Q_LINK; }
645          | IP                          { $$ = Q_IP; }
646          | ARP                         { $$ = Q_ARP; }
647          | RARP                        { $$ = Q_RARP; }
648          | SCTP                        { $$ = Q_SCTP; }
649          | TCP                         { $$ = Q_TCP; }
650          | UDP                         { $$ = Q_UDP; }
651          | ICMP                        { $$ = Q_ICMP; }
652          | IGMP                        { $$ = Q_IGMP; }
653          | IGRP                        { $$ = Q_IGRP; }
654          | PIM                         { $$ = Q_PIM; }
655          | VRRP                        { $$ = Q_VRRP; }
656          | CARP                        { $$ = Q_CARP; }
657          | ATALK                       { $$ = Q_ATALK; }
658          | AARP                        { $$ = Q_AARP; }
659          | DECNET            { $$ = Q_DECNET; }
660          | LAT                         { $$ = Q_LAT; }
661          | SCA                         { $$ = Q_SCA; }
662          | MOPDL                       { $$ = Q_MOPDL; }
663          | MOPRC                       { $$ = Q_MOPRC; }
664          | IPV6                        { $$ = Q_IPV6; }
665          | ICMPV6            { $$ = Q_ICMPV6; }
666          | AH                          { $$ = Q_AH; }
667          | ESP                         { $$ = Q_ESP; }
668          | ISO                         { $$ = Q_ISO; }
669          | ESIS                        { $$ = Q_ESIS; }
670          | ISIS                        { $$ = Q_ISIS; }
671          | L1                          { $$ = Q_ISIS_L1; }
672          | L2                          { $$ = Q_ISIS_L2; }
673          | IIH                         { $$ = Q_ISIS_IIH; }
674          | LSP                         { $$ = Q_ISIS_LSP; }
675          | SNP                         { $$ = Q_ISIS_SNP; }
676          | PSNP                        { $$ = Q_ISIS_PSNP; }
677          | CSNP                        { $$ = Q_ISIS_CSNP; }
678          | CLNP                        { $$ = Q_CLNP; }
679          | STP                         { $$ = Q_STP; }
680          | IPX                         { $$ = Q_IPX; }
681          | NETBEUI           { $$ = Q_NETBEUI; }
682          | RADIO                       { $$ = Q_RADIO; }
683          ;
684other:      pqual TK_BROADCAST          { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
685          | pqual TK_MULTICAST          { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
686          | LESS NUM                    { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
687          | GREATER NUM                 { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
688          | CBYTE NUM byteop NUM        { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
689          | INBOUND           { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
690          | OUTBOUND                    { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
691          | IFINDEX NUM                 { CHECK_PTR_VAL(($$ = gen_ifindex(cstate, $2))); }
692          | VLAN pnum                   { CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); }
693          | VLAN                        { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
694          | MPLS pnum                   { CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); }
695          | MPLS                        { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
696          | PPPOED            { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
697          | PPPOES pnum                 { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); }
698          | PPPOES            { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
699          | GENEVE pnum                 { CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); }
700          | GENEVE            { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
701          | pfvar                       { $$ = $1; }
702          | pqual p80211                { $$ = $2; }
703          | pllc                        { $$ = $1; }
704          ;
705
706pfvar:      PF_IFNAME ID                { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
707          | PF_RSET ID                  { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
708          | PF_RNR NUM                  { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
709          | PF_SRNR NUM                 { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
710          | PF_REASON reason  { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
711          | PF_ACTION action  { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
712          ;
713
714p80211:   TYPE type SUBTYPE subtype
715                                        { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
716                                                  IEEE80211_FC0_TYPE_MASK |
717                                                  IEEE80211_FC0_SUBTYPE_MASK)));
718                                        }
719          | TYPE type                   { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
720                                                  IEEE80211_FC0_TYPE_MASK)));
721                                        }
722          | SUBTYPE type_subtype        { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
723                                                  IEEE80211_FC0_TYPE_MASK |
724                                                  IEEE80211_FC0_SUBTYPE_MASK)));
725                                        }
726          | DIR dir           { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
727          ;
728
729type:       NUM                         { if (($1 & (~IEEE80211_FC0_TYPE_MASK)) != 0) {
730                                                  bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", $1);
731                                                  YYABORT;
732                                          }
733                                          $$ = (int)$1;
734                                        }
735          | ID                          { CHECK_PTR_VAL($1);
736                                          $$ = str2tok($1, ieee80211_types);
737                                          if ($$ == -1) {
738                                                  bpf_set_error(cstate, "unknown 802.11 type name \"%s\"", $1);
739                                                  YYABORT;
740                                          }
741                                        }
742          ;
743
744subtype:  NUM                           { if (($1 & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) {
745                                                  bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", $1);
746                                                  YYABORT;
747                                          }
748                                          $$ = (int)$1;
749                                        }
750          | ID                          { const struct tok *types = NULL;
751                                          int i;
752                                          CHECK_PTR_VAL($1);
753                                          for (i = 0;; i++) {
754                                                  if (ieee80211_type_subtypes[i].tok == NULL) {
755                                                            /* Ran out of types */
756                                                            bpf_set_error(cstate, "unknown 802.11 type");
757                                                            YYABORT;
758                                                  }
759                                                  if ($<i>-1 == ieee80211_type_subtypes[i].type) {
760                                                            types = ieee80211_type_subtypes[i].tok;
761                                                            break;
762                                                  }
763                                          }
764
765                                          $$ = str2tok($1, types);
766                                          if ($$ == -1) {
767                                                  bpf_set_error(cstate, "unknown 802.11 subtype name \"%s\"", $1);
768                                                  YYABORT;
769                                          }
770                                        }
771          ;
772
773type_subtype:       ID                  { int i;
774                                          CHECK_PTR_VAL($1);
775                                          for (i = 0;; i++) {
776                                                  if (ieee80211_type_subtypes[i].tok == NULL) {
777                                                            /* Ran out of types */
778                                                            bpf_set_error(cstate, "unknown 802.11 type name");
779                                                            YYABORT;
780                                                  }
781                                                  $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
782                                                  if ($$ != -1) {
783                                                            $$ |= ieee80211_type_subtypes[i].type;
784                                                            break;
785                                                  }
786                                          }
787                                        }
788                    ;
789
790pllc:     LLC                           { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
791          | LLC ID            { CHECK_PTR_VAL($2);
792                                          if (pcapint_strcasecmp($2, "i") == 0) {
793                                                  CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
794                                          } else if (pcapint_strcasecmp($2, "s") == 0) {
795                                                  CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
796                                          } else if (pcapint_strcasecmp($2, "u") == 0) {
797                                                  CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
798                                          } else {
799                                                  int subtype;
800
801                                                  subtype = str2tok($2, llc_s_subtypes);
802                                                  if (subtype != -1) {
803                                                            CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
804                                                  } else {
805                                                            subtype = str2tok($2, llc_u_subtypes);
806                                                            if (subtype == -1) {
807                                                                      bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
808                                                                      YYABORT;
809                                                            }
810                                                            CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
811                                                  }
812                                          }
813                                        }
814                                        /* sigh, "rnr" is already a keyword for PF */
815          | LLC PF_RNR                  { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
816          ;
817
818dir:        NUM                         { $$ = (int)$1; }
819          | ID                          { CHECK_PTR_VAL($1);
820                                          if (pcapint_strcasecmp($1, "nods") == 0)
821                                                  $$ = IEEE80211_FC1_DIR_NODS;
822                                          else if (pcapint_strcasecmp($1, "tods") == 0)
823                                                  $$ = IEEE80211_FC1_DIR_TODS;
824                                          else if (pcapint_strcasecmp($1, "fromds") == 0)
825                                                  $$ = IEEE80211_FC1_DIR_FROMDS;
826                                          else if (pcapint_strcasecmp($1, "dstods") == 0)
827                                                  $$ = IEEE80211_FC1_DIR_DSTODS;
828                                          else {
829                                                  bpf_set_error(cstate, "unknown 802.11 direction");
830                                                  YYABORT;
831                                          }
832                                        }
833          ;
834
835reason:     NUM                         { $$ = $1; }
836          | ID                          { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
837          ;
838
839action:     ID                          { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
840          ;
841
842relop:      '>'                         { $$ = BPF_JGT; }
843          | GEQ                         { $$ = BPF_JGE; }
844          | '='                         { $$ = BPF_JEQ; }
845          ;
846irelop:     LEQ                         { $$ = BPF_JGT; }
847          | '<'                         { $$ = BPF_JGE; }
848          | NEQ                         { $$ = BPF_JEQ; }
849          ;
850arth:       pnum                        { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
851          | narth
852          ;
853narth:      pname '[' arth ']'                    { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
854          | pname '[' arth ':' NUM ']'  { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
855          | arth '+' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
856          | arth '-' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
857          | arth '*' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
858          | arth '/' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
859          | arth '%' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
860          | arth '&' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
861          | arth '|' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
862          | arth '^' arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
863          | arth LSH arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
864          | arth RSH arth                         { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
865          | '-' arth %prec UMINUS                 { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
866          | paren narth ')'             { $$ = $2; }
867          | LEN                                   { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
868          ;
869byteop:     '&'                         { $$ = '&'; }
870          | '|'                         { $$ = '|'; }
871          | '<'                         { $$ = '<'; }
872          | '>'                         { $$ = '>'; }
873          | '='                         { $$ = '='; }
874          ;
875pnum:       NUM
876          | paren pnum ')'    { $$ = $2; }
877          ;
878atmtype: LANE                           { $$ = A_LANE; }
879          | METAC                       { $$ = A_METAC;     }
880          | BCC                         { $$ = A_BCC; }
881          | OAMF4EC           { $$ = A_OAMF4EC; }
882          | OAMF4SC           { $$ = A_OAMF4SC; }
883          | SC                          { $$ = A_SC; }
884          | ILMIC                       { $$ = A_ILMIC; }
885          ;
886atmmultitype: OAM             { $$ = A_OAM; }
887          | OAMF4                       { $$ = A_OAMF4; }
888          | CONNECTMSG                  { $$ = A_CONNECTMSG; }
889          | METACONNECT                 { $$ = A_METACONNECT; }
890          ;
891          /* ATM field types quantifier */
892atmfield: VPI                           { $$.atmfieldtype = A_VPI; }
893          | VCI                         { $$.atmfieldtype = A_VCI; }
894          ;
895atmvalue: atmfieldvalue
896          | relop NUM                   { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 0))); }
897          | irelop NUM                  { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 1))); }
898          | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
899          ;
900atmfieldvalue: NUM {
901          $$.atmfieldtype = $<blk>0.atmfieldtype;
902          if ($$.atmfieldtype == A_VPI ||
903              $$.atmfieldtype == A_VCI)
904                    CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, $1, BPF_JEQ, 0)));
905          }
906          ;
907atmlistvalue: atmfieldvalue
908          | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
909          ;
910          /* MTP2 types quantifier */
911mtp2type: FISU                          { $$ = M_FISU; }
912          | LSSU                        { $$ = M_LSSU; }
913          | MSU                         { $$ = M_MSU; }
914          | HFISU                       { $$ = MH_FISU; }
915          | HLSSU                       { $$ = MH_LSSU; }
916          | HMSU                        { $$ = MH_MSU; }
917          ;
918          /* MTP3 field types quantifier */
919mtp3field: SIO                          { $$.mtp3fieldtype = M_SIO; }
920          | OPC                         { $$.mtp3fieldtype = M_OPC; }
921          | DPC                         { $$.mtp3fieldtype = M_DPC; }
922          | SLS                   { $$.mtp3fieldtype = M_SLS; }
923          | HSIO                        { $$.mtp3fieldtype = MH_SIO; }
924          | HOPC                        { $$.mtp3fieldtype = MH_OPC; }
925          | HDPC                        { $$.mtp3fieldtype = MH_DPC; }
926          | HSLS                  { $$.mtp3fieldtype = MH_SLS; }
927          ;
928mtp3value: mtp3fieldvalue
929          | relop NUM                   { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 0))); }
930          | irelop NUM                  { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 1))); }
931          | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
932          ;
933mtp3fieldvalue: NUM {
934          $$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
935          if ($$.mtp3fieldtype == M_SIO ||
936              $$.mtp3fieldtype == M_OPC ||
937              $$.mtp3fieldtype == M_DPC ||
938              $$.mtp3fieldtype == M_SLS ||
939              $$.mtp3fieldtype == MH_SIO ||
940              $$.mtp3fieldtype == MH_OPC ||
941              $$.mtp3fieldtype == MH_DPC ||
942              $$.mtp3fieldtype == MH_SLS)
943                    CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, $1, BPF_JEQ, 0)));
944          }
945          ;
946mtp3listvalue: mtp3fieldvalue
947          | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
948          ;
949%%
950