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