xref: /openbsd/lib/libpcap/grammar.y (revision 07ea8d15)
1 %{
2 /*	$OpenBSD: grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $	*/
3 
4 /*
5  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that: (1) source code distributions
10  * retain the above copyright notice and this paragraph in its entirety, (2)
11  * distributions including binary code include the above copyright notice and
12  * this paragraph in its entirety in the documentation or other materials
13  * provided with the distribution, and (3) all advertising materials mentioning
14  * features or use of this software display the following acknowledgement:
15  * ``This product includes software developed by the University of California,
16  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
17  * the University nor the names of its contributors may be used to endorse
18  * or promote products derived from this software without specific prior
19  * written permission.
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
21  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23  *
24  */
25 #ifndef lint
26 static char rcsid[] =
27     "@(#) $Header: /home/cvs/src/lib/libpcap/grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $ (LBL)";
28 #endif
29 
30 #include <sys/types.h>
31 #include <sys/time.h>
32 #include <sys/socket.h>
33 
34 #if __STDC__
35 struct mbuf;
36 struct rtentry;
37 #endif
38 
39 #include <net/if.h>
40 #include <net/bpf.h>
41 
42 #include <netinet/in.h>
43 #include <netinet/if_ether.h>
44 
45 #include <stdio.h>
46 #include <pcap.h>
47 #include <pcap-namedb.h>
48 
49 #ifdef HAVE_OS_PROTO_H
50 #include "os-proto.h"
51 #endif
52 
53 #include "pcap-int.h"
54 #include "gencode.h"
55 
56 #define QSET(q, p, d, a) (q).proto = (p),\
57 			 (q).dir = (d),\
58 			 (q).addr = (a)
59 
60 int n_errors = 0;
61 
62 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
63 
64 static void
65 yyerror(char *msg)
66 {
67 	++n_errors;
68 	bpf_error(msg);
69 	/* NOTREACHED */
70 }
71 
72 #ifndef YYBISON
73 int yyparse(void);
74 
75 int
76 pcap_parse()
77 {
78 	return (yyparse());
79 }
80 #endif
81 
82 %}
83 
84 %union {
85 	int i;
86 	u_long h;
87 	u_char *e;
88 	char *s;
89 	struct stmt *stmt;
90 	struct arth *a;
91 	struct {
92 		struct qual q;
93 		struct block *b;
94 	} blk;
95 	struct block *rblk;
96 }
97 
98 %type	<blk>	expr id nid pid term rterm qid
99 %type	<blk>	head
100 %type	<i>	pqual dqual aqual ndaqual
101 %type	<a>	arth narth
102 %type	<i>	byteop pname pnum relop irelop
103 %type	<blk>	and or paren not null prog
104 %type	<rblk>	other
105 
106 %token  DST SRC HOST GATEWAY
107 %token  NET PORT LESS GREATER PROTO BYTE
108 %token  ARP RARP IP TCP UDP ICMP IGMP
109 %token  DECNET LAT MOPRC MOPDL
110 %token  TK_BROADCAST TK_MULTICAST
111 %token  NUM INBOUND OUTBOUND
112 %token  LINK
113 %token	GEQ LEQ NEQ
114 %token	ID EID HID
115 %token	LSH RSH
116 %token  LEN
117 
118 %type	<s> ID
119 %type	<e> EID
120 %type	<h> HID
121 %type	<i> NUM
122 
123 %left OR AND
124 %nonassoc  '!'
125 %left '|'
126 %left '&'
127 %left LSH RSH
128 %left '+' '-'
129 %left '*' '/'
130 %nonassoc UMINUS
131 %%
132 prog:	  null expr
133 {
134 	finish_parse($2.b);
135 }
136 	| null
137 	;
138 null:	  /* null */		{ $$.q = qerr; }
139 	;
140 expr:	  term
141 	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
142 	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
143 	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
144 	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
145 	;
146 and:	  AND			{ $$ = $<blk>0; }
147 	;
148 or:	  OR			{ $$ = $<blk>0; }
149 	;
150 id:	  nid
151 	| pnum			{ $$.b = gen_ncode((u_long)$1,
152 						   $$.q = $<blk>0.q); }
153 	| paren pid ')'		{ $$ = $2; }
154 	;
155 nid:	  ID			{ $$.b = gen_scode($1, $$.q = $<blk>0.q); }
156 	| HID			{
157 				  /* Decide how to parse HID based on proto */
158 				  $$.q = $<blk>0.q;
159 				  switch ($$.q.proto) {
160 				  case Q_DECNET:
161 					$$.b =
162 					    gen_ncode(__pcap_atodn((char *)$1),
163 					    $$.q);
164 					break;
165 				  default:
166 					$$.b =
167 					    gen_ncode(__pcap_atoin((char *)$1),
168 					    $$.q);
169 					break;
170 				  }
171 				}
172 	| EID			{ $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
173 	| not id		{ gen_not($2.b); $$ = $2; }
174 	;
175 not:	  '!'			{ $$ = $<blk>0; }
176 	;
177 paren:	  '('			{ $$ = $<blk>0; }
178 	;
179 pid:	  nid
180 	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
181 	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
182 	;
183 qid:	  pnum			{ $$.b = gen_ncode((u_long)$1,
184 						   $$.q = $<blk>0.q); }
185 	| pid
186 	;
187 term:	  rterm
188 	| not term		{ gen_not($2.b); $$ = $2; }
189 	;
190 head:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
191 	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
192 	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
193 	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
194 	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
195 	;
196 rterm:	  head id		{ $$ = $2; }
197 	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
198 	| pname			{ $$.b = gen_proto_abbrev($1); $$.q = qerr; }
199 	| arth relop arth	{ $$.b = gen_relation($2, $1, $3, 0);
200 				  $$.q = qerr; }
201 	| arth irelop arth	{ $$.b = gen_relation($2, $1, $3, 1);
202 				  $$.q = qerr; }
203 	| other			{ $$.b = $1; $$.q = qerr; }
204 	;
205 /* protocol level qualifiers */
206 pqual:	  pname
207 	|			{ $$ = Q_DEFAULT; }
208 	;
209 /* 'direction' qualifiers */
210 dqual:	  SRC			{ $$ = Q_SRC; }
211 	| DST			{ $$ = Q_DST; }
212 	| SRC OR DST		{ $$ = Q_OR; }
213 	| DST OR SRC		{ $$ = Q_OR; }
214 	| SRC AND DST		{ $$ = Q_AND; }
215 	| DST AND SRC		{ $$ = Q_AND; }
216 	;
217 /* address type qualifiers */
218 aqual:	  HOST			{ $$ = Q_HOST; }
219 	| NET			{ $$ = Q_NET; }
220 	| PORT			{ $$ = Q_PORT; }
221 	;
222 /* non-directional address type qualifiers */
223 ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
224 	;
225 pname:	  LINK			{ $$ = Q_LINK; }
226 	| IP			{ $$ = Q_IP; }
227 	| ARP			{ $$ = Q_ARP; }
228 	| RARP			{ $$ = Q_RARP; }
229 	| TCP			{ $$ = Q_TCP; }
230 	| UDP			{ $$ = Q_UDP; }
231 	| ICMP			{ $$ = Q_ICMP; }
232 	| IGMP			{ $$ = Q_IGMP; }
233 	| DECNET		{ $$ = Q_DECNET; }
234 	| LAT			{ $$ = Q_LAT; }
235 	| MOPDL			{ $$ = Q_MOPDL; }
236 	| MOPRC			{ $$ = Q_MOPRC; }
237 	;
238 other:	  pqual TK_BROADCAST	{ $$ = gen_broadcast($1); }
239 	| pqual TK_MULTICAST	{ $$ = gen_multicast($1); }
240 	| LESS NUM		{ $$ = gen_less($2); }
241 	| GREATER NUM		{ $$ = gen_greater($2); }
242 	| BYTE NUM byteop NUM	{ $$ = gen_byteop($3, $2, $4); }
243 	| INBOUND		{ $$ = gen_inbound(0); }
244 	| OUTBOUND		{ $$ = gen_inbound(1); }
245 	;
246 relop:	  '>'			{ $$ = BPF_JGT; }
247 	| GEQ			{ $$ = BPF_JGE; }
248 	| '='			{ $$ = BPF_JEQ; }
249 	;
250 irelop:	  LEQ			{ $$ = BPF_JGT; }
251 	| '<'			{ $$ = BPF_JGE; }
252 	| NEQ			{ $$ = BPF_JEQ; }
253 	;
254 arth:	  pnum			{ $$ = gen_loadi($1); }
255 	| narth
256 	;
257 narth:	  pname '[' arth ']'		{ $$ = gen_load($1, $3, 1); }
258 	| pname '[' arth ':' NUM ']'	{ $$ = gen_load($1, $3, $5); }
259 	| arth '+' arth			{ $$ = gen_arth(BPF_ADD, $1, $3); }
260 	| arth '-' arth			{ $$ = gen_arth(BPF_SUB, $1, $3); }
261 	| arth '*' arth			{ $$ = gen_arth(BPF_MUL, $1, $3); }
262 	| arth '/' arth			{ $$ = gen_arth(BPF_DIV, $1, $3); }
263 	| arth '&' arth			{ $$ = gen_arth(BPF_AND, $1, $3); }
264 	| arth '|' arth			{ $$ = gen_arth(BPF_OR, $1, $3); }
265 	| arth LSH arth			{ $$ = gen_arth(BPF_LSH, $1, $3); }
266 	| arth RSH arth			{ $$ = gen_arth(BPF_RSH, $1, $3); }
267 	| '-' arth %prec UMINUS		{ $$ = gen_neg($2); }
268 	| paren narth ')'		{ $$ = $2; }
269 	| LEN				{ $$ = gen_loadlen(); }
270 	;
271 byteop:	  '&'			{ $$ = '&'; }
272 	| '|'			{ $$ = '|'; }
273 	| '<'			{ $$ = '<'; }
274 	| '>'			{ $$ = '>'; }
275 	| '='			{ $$ = '='; }
276 	;
277 pnum:	  NUM
278 	| paren pnum ')'	{ $$ = $2; }
279 	;
280 %%
281