grammar.y revision 21344
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 char rcsid[] =
25    "@(#) $Header: grammar.y,v 1.54 96/07/17 00:11:34 leres Exp $ (LBL)";
26#endif
27
28#include <sys/types.h>
29#include <sys/time.h>
30#include <sys/socket.h>
31
32#if __STDC__
33struct mbuf;
34struct rtentry;
35#endif
36
37#include <net/if.h>
38
39#include <netinet/in.h>
40#include <net/ethernet.h>
41
42#include <stdio.h>
43
44#include "pcap-int.h"
45
46#include "gencode.h"
47#include <pcap-namedb.h>
48
49#include "gnuc.h"
50#ifdef HAVE_OS_PROTO_H
51#include "os-proto.h"
52#endif
53
54#define QSET(q, p, d, a) (q).proto = (p),\
55			 (q).dir = (d),\
56			 (q).addr = (a)
57
58int n_errors = 0;
59
60static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
61
62static void
63yyerror(char *msg)
64{
65	++n_errors;
66	bpf_error(msg);
67	/* NOTREACHED */
68}
69
70#ifndef YYBISON
71int yyparse(void);
72
73int
74pcap_parse()
75{
76	return (yyparse());
77}
78#endif
79
80%}
81
82%union {
83	int i;
84	bpf_u_int32 h;
85	u_char *e;
86	char *s;
87	struct stmt *stmt;
88	struct arth *a;
89	struct {
90		struct qual q;
91		struct block *b;
92	} blk;
93	struct block *rblk;
94}
95
96%type	<blk>	expr id nid pid term rterm qid
97%type	<blk>	head
98%type	<i>	pqual dqual aqual ndaqual
99%type	<a>	arth narth
100%type	<i>	byteop pname pnum relop irelop
101%type	<blk>	and or paren not null prog
102%type	<rblk>	other
103
104%token  DST SRC HOST GATEWAY
105%token  NET MASK PORT LESS GREATER PROTO BYTE
106%token  ARP RARP IP TCP UDP ICMP IGMP IGRP
107%token  ATALK DECNET LAT SCA MOPRC MOPDL
108%token  TK_BROADCAST TK_MULTICAST
109%token  NUM INBOUND OUTBOUND
110%token  LINK
111%token	GEQ LEQ NEQ
112%token	ID EID HID
113%token	LSH RSH
114%token  LEN
115%token  ISO ESIS ISIS
116
117%type	<s> ID
118%type	<e> EID
119%type	<s> HID
120%type	<i> NUM
121
122%left OR AND
123%nonassoc  '!'
124%left '|'
125%left '&'
126%left LSH RSH
127%left '+' '-'
128%left '*' '/'
129%nonassoc UMINUS
130%%
131prog:	  null expr
132{
133	finish_parse($2.b);
134}
135	| null
136	;
137null:	  /* null */		{ $$.q = qerr; }
138	;
139expr:	  term
140	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
141	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
142	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
143	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
144	;
145and:	  AND			{ $$ = $<blk>0; }
146	;
147or:	  OR			{ $$ = $<blk>0; }
148	;
149id:	  nid
150	| pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
151						   $$.q = $<blk>0.q); }
152	| paren pid ')'		{ $$ = $2; }
153	;
154nid:	  ID			{ $$.b = gen_scode($1, $$.q = $<blk>0.q); }
155	| HID '/' NUM		{ $$.b = gen_mcode($1, NULL, $3,
156				    $$.q = $<blk>0.q); }
157	| HID MASK HID		{ $$.b = gen_mcode($1, $3, 0,
158				    $$.q = $<blk>0.q); }
159	| HID			{
160				  /* Decide how to parse HID based on proto */
161				  $$.q = $<blk>0.q;
162				  switch ($$.q.proto) {
163				  case Q_DECNET:
164					$$.b = gen_ncode($1, 0, $$.q);
165					break;
166				  default:
167					$$.b = gen_ncode($1, 0, $$.q);
168					break;
169				  }
170				}
171	| EID			{ $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
172	| not id		{ gen_not($2.b); $$ = $2; }
173	;
174not:	  '!'			{ $$ = $<blk>0; }
175	;
176paren:	  '('			{ $$ = $<blk>0; }
177	;
178pid:	  nid
179	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
180	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
181	;
182qid:	  pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
183						   $$.q = $<blk>0.q); }
184	| pid
185	;
186term:	  rterm
187	| not term		{ gen_not($2.b); $$ = $2; }
188	;
189head:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
190	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
191	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
192	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
193	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
194	;
195rterm:	  head id		{ $$ = $2; }
196	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
197	| pname			{ $$.b = gen_proto_abbrev($1); $$.q = qerr; }
198	| arth relop arth	{ $$.b = gen_relation($2, $1, $3, 0);
199				  $$.q = qerr; }
200	| arth irelop arth	{ $$.b = gen_relation($2, $1, $3, 1);
201				  $$.q = qerr; }
202	| other			{ $$.b = $1; $$.q = qerr; }
203	;
204/* protocol level qualifiers */
205pqual:	  pname
206	|			{ $$ = Q_DEFAULT; }
207	;
208/* 'direction' qualifiers */
209dqual:	  SRC			{ $$ = Q_SRC; }
210	| DST			{ $$ = Q_DST; }
211	| SRC OR DST		{ $$ = Q_OR; }
212	| DST OR SRC		{ $$ = Q_OR; }
213	| SRC AND DST		{ $$ = Q_AND; }
214	| DST AND SRC		{ $$ = Q_AND; }
215	;
216/* address type qualifiers */
217aqual:	  HOST			{ $$ = Q_HOST; }
218	| NET			{ $$ = Q_NET; }
219	| PORT			{ $$ = Q_PORT; }
220	;
221/* non-directional address type qualifiers */
222ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
223	;
224pname:	  LINK			{ $$ = Q_LINK; }
225	| IP			{ $$ = Q_IP; }
226	| ARP			{ $$ = Q_ARP; }
227	| RARP			{ $$ = Q_RARP; }
228	| TCP			{ $$ = Q_TCP; }
229	| UDP			{ $$ = Q_UDP; }
230	| ICMP			{ $$ = Q_ICMP; }
231	| IGMP			{ $$ = Q_IGMP; }
232	| IGRP			{ $$ = Q_IGRP; }
233	| ATALK			{ $$ = Q_ATALK; }
234	| DECNET		{ $$ = Q_DECNET; }
235	| LAT			{ $$ = Q_LAT; }
236	| SCA			{ $$ = Q_SCA; }
237	| MOPDL			{ $$ = Q_MOPDL; }
238	| MOPRC			{ $$ = Q_MOPRC; }
239	| ISO			{ $$ = Q_ISO; }
240	| ESIS			{ $$ = Q_ESIS; }
241	| ISIS			{ $$ = Q_ISIS; }
242	;
243other:	  pqual TK_BROADCAST	{ $$ = gen_broadcast($1); }
244	| pqual TK_MULTICAST	{ $$ = gen_multicast($1); }
245	| LESS NUM		{ $$ = gen_less($2); }
246	| GREATER NUM		{ $$ = gen_greater($2); }
247	| BYTE NUM byteop NUM	{ $$ = gen_byteop($3, $2, $4); }
248	| INBOUND		{ $$ = gen_inbound(0); }
249	| OUTBOUND		{ $$ = gen_inbound(1); }
250	;
251relop:	  '>'			{ $$ = BPF_JGT; }
252	| GEQ			{ $$ = BPF_JGE; }
253	| '='			{ $$ = BPF_JEQ; }
254	;
255irelop:	  LEQ			{ $$ = BPF_JGT; }
256	| '<'			{ $$ = BPF_JGE; }
257	| NEQ			{ $$ = BPF_JEQ; }
258	;
259arth:	  pnum			{ $$ = gen_loadi($1); }
260	| narth
261	;
262narth:	  pname '[' arth ']'		{ $$ = gen_load($1, $3, 1); }
263	| pname '[' arth ':' NUM ']'	{ $$ = gen_load($1, $3, $5); }
264	| arth '+' arth			{ $$ = gen_arth(BPF_ADD, $1, $3); }
265	| arth '-' arth			{ $$ = gen_arth(BPF_SUB, $1, $3); }
266	| arth '*' arth			{ $$ = gen_arth(BPF_MUL, $1, $3); }
267	| arth '/' arth			{ $$ = gen_arth(BPF_DIV, $1, $3); }
268	| arth '&' arth			{ $$ = gen_arth(BPF_AND, $1, $3); }
269	| arth '|' arth			{ $$ = gen_arth(BPF_OR, $1, $3); }
270	| arth LSH arth			{ $$ = gen_arth(BPF_LSH, $1, $3); }
271	| arth RSH arth			{ $$ = gen_arth(BPF_RSH, $1, $3); }
272	| '-' arth %prec UMINUS		{ $$ = gen_neg($2); }
273	| paren narth ')'		{ $$ = $2; }
274	| LEN				{ $$ = gen_loadlen(); }
275	;
276byteop:	  '&'			{ $$ = '&'; }
277	| '|'			{ $$ = '|'; }
278	| '<'			{ $$ = '<'; }
279	| '>'			{ $$ = '>'; }
280	| '='			{ $$ = '='; }
281	;
282pnum:	  NUM
283	| paren pnum ')'	{ $$ = $2; }
284	;
285%%
286