Home | History | Annotate | Download | only in libpcap
      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