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