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