1 %{ 2 /* 3 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that: (1) source code distributions 8 * retain the above copyright notice and this paragraph in its entirety, (2) 9 * distributions including binary code include the above copyright notice and 10 * this paragraph in its entirety in the documentation or other materials 11 * provided with the distribution, and (3) all advertising materials mentioning 12 * features or use of this software display the following acknowledgement: 13 * ``This product includes software developed by the University of California, 14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 15 * the University nor the names of its contributors may be used to endorse 16 * or promote products derived from this software without specific prior 17 * written permission. 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 21 * 22 */ 23 #ifndef lint 24 static const char rcsid[] _U_ = 25 "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.9 2007/09/12 19:17:25 guy Exp $ (LBL)"; 26 #endif 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #ifdef WIN32 33 #include <pcap-stdinc.h> 34 #else /* WIN32 */ 35 #include <sys/types.h> 36 #include <sys/socket.h> 37 #endif /* WIN32 */ 38 39 #include <stdlib.h> 40 41 #ifndef WIN32 42 #if __STDC__ 43 struct mbuf; 44 struct rtentry; 45 #endif 46 47 #include <netinet/in.h> 48 #endif /* WIN32 */ 49 50 #include <stdio.h> 51 52 #include "pcap-int.h" 53 54 #include "gencode.h" 55 #ifdef HAVE_NET_PFVAR_H 56 #include <net/if.h> 57 #include <net/pfvar.h> 58 #include <net/if_pflog.h> 59 #endif 60 #include <pcap-namedb.h> 61 62 #ifdef HAVE_OS_PROTO_H 63 #include "os-proto.h" 64 #endif 65 66 #define QSET(q, p, d, a) (q).proto = (p),\ 67 (q).dir = (d),\ 68 (q).addr = (a) 69 70 int n_errors = 0; 71 72 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; 73 74 static void 75 yyerror(const char *msg) 76 { 77 ++n_errors; 78 bpf_error("%s", msg); 79 /* NOTREACHED */ 80 } 81 82 #ifndef YYBISON 83 int yyparse(void); 84 85 int 86 pcap_parse() 87 { 88 return (yyparse()); 89 } 90 #endif 91 92 #ifdef HAVE_NET_PFVAR_H 93 static int 94 pfreason_to_num(const char *reason) 95 { 96 const char *reasons[] = PFRES_NAMES; 97 int i; 98 99 for (i = 0; reasons[i]; i++) { 100 if (pcap_strcasecmp(reason, reasons[i]) == 0) 101 return (i); 102 } 103 bpf_error("unknown PF reason"); 104 /*NOTREACHED*/ 105 } 106 107 static int 108 pfaction_to_num(const char *action) 109 { 110 if (pcap_strcasecmp(action, "pass") == 0 || 111 pcap_strcasecmp(action, "accept") == 0) 112 return (PF_PASS); 113 else if (pcap_strcasecmp(action, "drop") == 0 || 114 pcap_strcasecmp(action, "block") == 0) 115 return (PF_DROP); 116 else { 117 bpf_error("unknown PF action"); 118 /*NOTREACHED*/ 119 } 120 } 121 #else /* !HAVE_NET_PFVAR_H */ 122 static int 123 pfreason_to_num(const char *reason) 124 { 125 bpf_error("libpcap was compiled on a machine without pf support"); 126 /*NOTREACHED*/ 127 } 128 129 static int 130 pfaction_to_num(const char *action) 131 { 132 bpf_error("libpcap was compiled on a machine without pf support"); 133 /*NOTREACHED*/ 134 } 135 #endif /* HAVE_NET_PFVAR_H */ 136 %} 137 138 %union { 139 int i; 140 bpf_u_int32 h; 141 u_char *e; 142 char *s; 143 struct stmt *stmt; 144 struct arth *a; 145 struct { 146 struct qual q; 147 int atmfieldtype; 148 int mtp3fieldtype; 149 struct block *b; 150 } blk; 151 struct block *rblk; 152 } 153 154 %type <blk> expr id nid pid term rterm qid 155 %type <blk> head 156 %type <i> pqual dqual aqual ndaqual 157 %type <a> arth narth 158 %type <i> byteop pname pnum relop irelop 159 %type <blk> and or paren not null prog 160 %type <rblk> other pfvar 161 %type <i> atmtype atmmultitype 162 %type <blk> atmfield 163 %type <blk> atmfieldvalue atmvalue atmlistvalue 164 %type <i> mtp2type 165 %type <blk> mtp3field 166 %type <blk> mtp3fieldvalue mtp3value mtp3listvalue 167 168 169 %token DST SRC HOST GATEWAY 170 %token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE 171 %token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP 172 %token ATALK AARP DECNET LAT SCA MOPRC MOPDL 173 %token TK_BROADCAST TK_MULTICAST 174 %token NUM INBOUND OUTBOUND 175 %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION 176 %token LINK 177 %token GEQ LEQ NEQ 178 %token ID EID HID HID6 AID 179 %token LSH RSH 180 %token LEN 181 %token IPV6 ICMPV6 AH ESP 182 %token VLAN MPLS 183 %token PPPOED PPPOES 184 %token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP 185 %token STP 186 %token IPX 187 %token NETBEUI 188 %token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC 189 %token OAM OAMF4 CONNECTMSG METACONNECT 190 %token VPI VCI 191 %token RADIO 192 %token FISU LSSU MSU 193 %token SIO OPC DPC SLS 194 195 %type <s> ID 196 %type <e> EID 197 %type <e> AID 198 %type <s> HID HID6 199 %type <i> NUM action reason 200 201 %left OR AND 202 %nonassoc '!' 203 %left '|' 204 %left '&' 205 %left LSH RSH 206 %left '+' '-' 207 %left '*' '/' 208 %nonassoc UMINUS 209 %% 210 prog: null expr 211 { 212 finish_parse($2.b); 213 } 214 | null 215 ; 216 null: /* null */ { $$.q = qerr; } 217 ; 218 expr: term 219 | expr and term { gen_and($1.b, $3.b); $$ = $3; } 220 | expr and id { gen_and($1.b, $3.b); $$ = $3; } 221 | expr or term { gen_or($1.b, $3.b); $$ = $3; } 222 | expr or id { gen_or($1.b, $3.b); $$ = $3; } 223 ; 224 and: AND { $$ = $<blk>0; } 225 ; 226 or: OR { $$ = $<blk>0; } 227 ; 228 id: nid 229 | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, 230 $$.q = $<blk>0.q); } 231 | paren pid ')' { $$ = $2; } 232 ; 233 nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); } 234 | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3, 235 $$.q = $<blk>0.q); } 236 | HID NETMASK HID { $$.b = gen_mcode($1, $3, 0, 237 $$.q = $<blk>0.q); } 238 | HID { 239 /* Decide how to parse HID based on proto */ 240 $$.q = $<blk>0.q; 241 $$.b = gen_ncode($1, 0, $$.q); 242 } 243 | HID6 '/' NUM { 244 #ifdef INET6 245 $$.b = gen_mcode6($1, NULL, $3, 246 $$.q = $<blk>0.q); 247 #else 248 bpf_error("'ip6addr/prefixlen' not supported " 249 "in this configuration"); 250 #endif /*INET6*/ 251 } 252 | HID6 { 253 #ifdef INET6 254 $$.b = gen_mcode6($1, 0, 128, 255 $$.q = $<blk>0.q); 256 #else 257 bpf_error("'ip6addr' not supported " 258 "in this configuration"); 259 #endif /*INET6*/ 260 } 261 | EID { 262 $$.b = gen_ecode($1, $$.q = $<blk>0.q); 263 /* 264 * $1 was allocated by "pcap_ether_aton()", 265 * so we must free it now that we're done 266 * with it. 267 */ 268 free($1); 269 } 270 | AID { 271 $$.b = gen_acode($1, $$.q = $<blk>0.q); 272 /* 273 * $1 was allocated by "pcap_ether_aton()", 274 * so we must free it now that we're done 275 * with it. 276 */ 277 free($1); 278 } 279 | not id { gen_not($2.b); $$ = $2; } 280 ; 281 not: '!' { $$ = $<blk>0; } 282 ; 283 paren: '(' { $$ = $<blk>0; } 284 ; 285 pid: nid 286 | qid and id { gen_and($1.b, $3.b); $$ = $3; } 287 | qid or id { gen_or($1.b, $3.b); $$ = $3; } 288 ; 289 qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, 290 $$.q = $<blk>0.q); } 291 | pid 292 ; 293 term: rterm 294 | not term { gen_not($2.b); $$ = $2; } 295 ; 296 head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } 297 | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } 298 | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } 299 | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } 300 | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); } 301 | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } 302 ; 303 rterm: head id { $$ = $2; } 304 | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } 305 | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } 306 | arth relop arth { $$.b = gen_relation($2, $1, $3, 0); 307 $$.q = qerr; } 308 | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); 309 $$.q = qerr; } 310 | other { $$.b = $1; $$.q = qerr; } 311 | atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; } 312 | atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; } 313 | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; } 314 | mtp2type { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; } 315 | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; } 316 ; 317 /* protocol level qualifiers */ 318 pqual: pname 319 | { $$ = Q_DEFAULT; } 320 ; 321 /* 'direction' qualifiers */ 322 dqual: SRC { $$ = Q_SRC; } 323 | DST { $$ = Q_DST; } 324 | SRC OR DST { $$ = Q_OR; } 325 | DST OR SRC { $$ = Q_OR; } 326 | SRC AND DST { $$ = Q_AND; } 327 | DST AND SRC { $$ = Q_AND; } 328 ; 329 /* address type qualifiers */ 330 aqual: HOST { $$ = Q_HOST; } 331 | NET { $$ = Q_NET; } 332 | PORT { $$ = Q_PORT; } 333 | PORTRANGE { $$ = Q_PORTRANGE; } 334 ; 335 /* non-directional address type qualifiers */ 336 ndaqual: GATEWAY { $$ = Q_GATEWAY; } 337 ; 338 pname: LINK { $$ = Q_LINK; } 339 | IP { $$ = Q_IP; } 340 | ARP { $$ = Q_ARP; } 341 | RARP { $$ = Q_RARP; } 342 | SCTP { $$ = Q_SCTP; } 343 | TCP { $$ = Q_TCP; } 344 | UDP { $$ = Q_UDP; } 345 | ICMP { $$ = Q_ICMP; } 346 | IGMP { $$ = Q_IGMP; } 347 | IGRP { $$ = Q_IGRP; } 348 | PIM { $$ = Q_PIM; } 349 | VRRP { $$ = Q_VRRP; } 350 | ATALK { $$ = Q_ATALK; } 351 | AARP { $$ = Q_AARP; } 352 | DECNET { $$ = Q_DECNET; } 353 | LAT { $$ = Q_LAT; } 354 | SCA { $$ = Q_SCA; } 355 | MOPDL { $$ = Q_MOPDL; } 356 | MOPRC { $$ = Q_MOPRC; } 357 | IPV6 { $$ = Q_IPV6; } 358 | ICMPV6 { $$ = Q_ICMPV6; } 359 | AH { $$ = Q_AH; } 360 | ESP { $$ = Q_ESP; } 361 | ISO { $$ = Q_ISO; } 362 | ESIS { $$ = Q_ESIS; } 363 | ISIS { $$ = Q_ISIS; } 364 | L1 { $$ = Q_ISIS_L1; } 365 | L2 { $$ = Q_ISIS_L2; } 366 | IIH { $$ = Q_ISIS_IIH; } 367 | LSP { $$ = Q_ISIS_LSP; } 368 | SNP { $$ = Q_ISIS_SNP; } 369 | PSNP { $$ = Q_ISIS_PSNP; } 370 | CSNP { $$ = Q_ISIS_CSNP; } 371 | CLNP { $$ = Q_CLNP; } 372 | STP { $$ = Q_STP; } 373 | IPX { $$ = Q_IPX; } 374 | NETBEUI { $$ = Q_NETBEUI; } 375 | RADIO { $$ = Q_RADIO; } 376 ; 377 other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } 378 | pqual TK_MULTICAST { $$ = gen_multicast($1); } 379 | LESS NUM { $$ = gen_less($2); } 380 | GREATER NUM { $$ = gen_greater($2); } 381 | CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } 382 | INBOUND { $$ = gen_inbound(0); } 383 | OUTBOUND { $$ = gen_inbound(1); } 384 | VLAN pnum { $$ = gen_vlan($2); } 385 | VLAN { $$ = gen_vlan(-1); } 386 | MPLS pnum { $$ = gen_mpls($2); } 387 | MPLS { $$ = gen_mpls(-1); } 388 | PPPOED { $$ = gen_pppoed(); } 389 | PPPOES { $$ = gen_pppoes(); } 390 | pfvar { $$ = $1; } 391 ; 392 393 pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); } 394 | PF_RSET ID { $$ = gen_pf_ruleset($2); } 395 | PF_RNR NUM { $$ = gen_pf_rnr($2); } 396 | PF_SRNR NUM { $$ = gen_pf_srnr($2); } 397 | PF_REASON reason { $$ = gen_pf_reason($2); } 398 | PF_ACTION action { $$ = gen_pf_action($2); } 399 ; 400 401 reason: NUM { $$ = $1; } 402 | ID { $$ = pfreason_to_num($1); } 403 ; 404 405 action: ID { $$ = pfaction_to_num($1); } 406 ; 407 408 relop: '>' { $$ = BPF_JGT; } 409 | GEQ { $$ = BPF_JGE; } 410 | '=' { $$ = BPF_JEQ; } 411 ; 412 irelop: LEQ { $$ = BPF_JGT; } 413 | '<' { $$ = BPF_JGE; } 414 | NEQ { $$ = BPF_JEQ; } 415 ; 416 arth: pnum { $$ = gen_loadi($1); } 417 | narth 418 ; 419 narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } 420 | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } 421 | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } 422 | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } 423 | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } 424 | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } 425 | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } 426 | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } 427 | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } 428 | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } 429 | '-' arth %prec UMINUS { $$ = gen_neg($2); } 430 | paren narth ')' { $$ = $2; } 431 | LEN { $$ = gen_loadlen(); } 432 ; 433 byteop: '&' { $$ = '&'; } 434 | '|' { $$ = '|'; } 435 | '<' { $$ = '<'; } 436 | '>' { $$ = '>'; } 437 | '=' { $$ = '='; } 438 ; 439 pnum: NUM 440 | paren pnum ')' { $$ = $2; } 441 ; 442 atmtype: LANE { $$ = A_LANE; } 443 | LLC { $$ = A_LLC; } 444 | METAC { $$ = A_METAC; } 445 | BCC { $$ = A_BCC; } 446 | OAMF4EC { $$ = A_OAMF4EC; } 447 | OAMF4SC { $$ = A_OAMF4SC; } 448 | SC { $$ = A_SC; } 449 | ILMIC { $$ = A_ILMIC; } 450 ; 451 atmmultitype: OAM { $$ = A_OAM; } 452 | OAMF4 { $$ = A_OAMF4; } 453 | CONNECTMSG { $$ = A_CONNECTMSG; } 454 | METACONNECT { $$ = A_METACONNECT; } 455 ; 456 /* ATM field types quantifier */ 457 atmfield: VPI { $$.atmfieldtype = A_VPI; } 458 | VCI { $$.atmfieldtype = A_VCI; } 459 ; 460 atmvalue: atmfieldvalue 461 | relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); } 462 | irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); } 463 | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; } 464 ; 465 atmfieldvalue: NUM { 466 $$.atmfieldtype = $<blk>0.atmfieldtype; 467 if ($$.atmfieldtype == A_VPI || 468 $$.atmfieldtype == A_VCI) 469 $$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0); 470 } 471 ; 472 atmlistvalue: atmfieldvalue 473 | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; } 474 ; 475 /* MTP2 types quantifier */ 476 mtp2type: FISU { $$ = M_FISU; } 477 | LSSU { $$ = M_LSSU; } 478 | MSU { $$ = M_MSU; } 479 ; 480 /* MTP3 field types quantifier */ 481 mtp3field: SIO { $$.mtp3fieldtype = M_SIO; } 482 | OPC { $$.mtp3fieldtype = M_OPC; } 483 | DPC { $$.mtp3fieldtype = M_DPC; } 484 | SLS { $$.mtp3fieldtype = M_SLS; } 485 ; 486 mtp3value: mtp3fieldvalue 487 | relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); } 488 | irelop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); } 489 | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; } 490 ; 491 mtp3fieldvalue: NUM { 492 $$.mtp3fieldtype = $<blk>0.mtp3fieldtype; 493 if ($$.mtp3fieldtype == M_SIO || 494 $$.mtp3fieldtype == M_OPC || 495 $$.mtp3fieldtype == M_DPC || 496 $$.mtp3fieldtype == M_SLS ) 497 $$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0); 498 } 499 ; 500 mtp3listvalue: mtp3fieldvalue 501 | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; } 502 ; 503 %% 504