• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
yyerror(const char * msg)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
pcap_parse()86 pcap_parse()
87 {
88 	return (yyparse());
89 }
90 #endif
91 
92 #ifdef HAVE_NET_PFVAR_H
93 static int
pfreason_to_num(const char * reason)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
pfaction_to_num(const char * action)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
pfreason_to_num(const char * reason)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
pfaction_to_num(const char * action)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