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