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
24static 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__
43struct mbuf;
44struct 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
70int n_errors = 0;
71
72static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
73
74static void
75yyerror(const char *msg)
76{
77	++n_errors;
78	bpf_error("%s", msg);
79	/* NOTREACHED */
80}
81
82#ifndef YYBISON
83int yyparse(void);
84
85int
86pcap_parse()
87{
88	return (yyparse());
89}
90#endif
91
92#ifdef HAVE_NET_PFVAR_H
93static int
94pfreason_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
107static int
108pfaction_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 */
122static int
123pfreason_to_num(const char *reason)
124{
125	bpf_error("libpcap was compiled on a machine without pf support");
126	/*NOTREACHED*/
127}
128
129static int
130pfaction_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%%
210prog:	  null expr
211{
212	finish_parse($2.b);
213}
214	| null
215	;
216null:	  /* null */		{ $$.q = qerr; }
217	;
218expr:	  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	;
224and:	  AND			{ $$ = $<blk>0; }
225	;
226or:	  OR			{ $$ = $<blk>0; }
227	;
228id:	  nid
229	| pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
230						   $$.q = $<blk>0.q); }
231	| paren pid ')'		{ $$ = $2; }
232	;
233nid:	  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	;
281not:	  '!'			{ $$ = $<blk>0; }
282	;
283paren:	  '('			{ $$ = $<blk>0; }
284	;
285pid:	  nid
286	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
287	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
288	;
289qid:	  pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
290						   $$.q = $<blk>0.q); }
291	| pid
292	;
293term:	  rterm
294	| not term		{ gen_not($2.b); $$ = $2; }
295	;
296head:	  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	;
303rterm:	  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 */
318pqual:	  pname
319	|			{ $$ = Q_DEFAULT; }
320	;
321/* 'direction' qualifiers */
322dqual:	  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 */
330aqual:	  HOST			{ $$ = Q_HOST; }
331	| NET			{ $$ = Q_NET; }
332	| PORT			{ $$ = Q_PORT; }
333	| PORTRANGE		{ $$ = Q_PORTRANGE; }
334	;
335/* non-directional address type qualifiers */
336ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
337	;
338pname:	  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	;
377other:	  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
393pfvar:	  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
401reason:	  NUM			{ $$ = $1; }
402	| ID			{ $$ = pfreason_to_num($1); }
403	;
404
405action:	  ID			{ $$ = pfaction_to_num($1); }
406	;
407
408relop:	  '>'			{ $$ = BPF_JGT; }
409	| GEQ			{ $$ = BPF_JGE; }
410	| '='			{ $$ = BPF_JEQ; }
411	;
412irelop:	  LEQ			{ $$ = BPF_JGT; }
413	| '<'			{ $$ = BPF_JGE; }
414	| NEQ			{ $$ = BPF_JEQ; }
415	;
416arth:	  pnum			{ $$ = gen_loadi($1); }
417	| narth
418	;
419narth:	  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	;
433byteop:	  '&'			{ $$ = '&'; }
434	| '|'			{ $$ = '|'; }
435	| '<'			{ $$ = '<'; }
436	| '>'			{ $$ = '>'; }
437	| '='			{ $$ = '='; }
438	;
439pnum:	  NUM
440	| paren pnum ')'	{ $$ = $2; }
441	;
442atmtype: 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	;
451atmmultitype: OAM		{ $$ = A_OAM; }
452	| OAMF4			{ $$ = A_OAMF4; }
453	| CONNECTMSG		{ $$ = A_CONNECTMSG; }
454	| METACONNECT		{ $$ = A_METACONNECT; }
455	;
456	/* ATM field types quantifier */
457atmfield: VPI			{ $$.atmfieldtype = A_VPI; }
458	| VCI			{ $$.atmfieldtype = A_VCI; }
459	;
460atmvalue: 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	;
465atmfieldvalue: 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	;
472atmlistvalue: atmfieldvalue
473	| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
474	;
475	/* MTP2 types quantifier */
476mtp2type: FISU			{ $$ = M_FISU; }
477	| LSSU			{ $$ = M_LSSU; }
478	| MSU			{ $$ = M_MSU; }
479	;
480	/* MTP3 field types quantifier */
481mtp3field: SIO			{ $$.mtp3fieldtype = M_SIO; }
482	| OPC			{ $$.mtp3fieldtype = M_OPC; }
483	| DPC			{ $$.mtp3fieldtype = M_DPC; }
484	| SLS                   { $$.mtp3fieldtype = M_SLS; }
485	;
486mtp3value: 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	;
491mtp3fieldvalue: 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	;
500mtp3listvalue: mtp3fieldvalue
501	| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
502	;
503%%
504