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