1 |
|
|
%{ |
2 |
|
|
/* $OpenBSD: grammar.y,v 1.19 2009/10/27 23:59:30 deraadt 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 |
|
|
|
26 |
|
|
#include <sys/types.h> |
27 |
|
|
#include <sys/time.h> |
28 |
|
|
#include <sys/socket.h> |
29 |
|
|
|
30 |
|
|
struct mbuf; |
31 |
|
|
struct rtentry; |
32 |
|
|
|
33 |
|
|
#include <net/if.h> |
34 |
|
|
|
35 |
|
|
#include <netinet/in.h> |
36 |
|
|
#include <netinet/if_ether.h> |
37 |
|
|
|
38 |
|
|
#include <net/pfvar.h> |
39 |
|
|
|
40 |
|
|
#include <net80211/ieee80211.h> |
41 |
|
|
|
42 |
|
|
#include <stdio.h> |
43 |
|
|
#include <string.h> |
44 |
|
|
|
45 |
|
|
#include "pcap-int.h" |
46 |
|
|
|
47 |
|
|
#include "gencode.h" |
48 |
|
|
#include <pcap-namedb.h> |
49 |
|
|
|
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 |
|
|
|
58 |
|
|
int n_errors = 0; |
59 |
|
|
|
60 |
|
|
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; |
61 |
|
|
|
62 |
|
|
static void |
63 |
|
|
yyerror(char *msg) |
64 |
|
|
{ |
65 |
|
|
++n_errors; |
66 |
|
|
bpf_error("%s", msg); |
67 |
|
|
/* NOTREACHED */ |
68 |
|
|
} |
69 |
|
|
|
70 |
|
|
#ifndef YYBISON |
71 |
|
|
int yyparse(void); |
72 |
|
|
|
73 |
|
|
int |
74 |
|
|
pcap_parse() |
75 |
|
|
{ |
76 |
|
6 |
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 pfvar p80211 |
103 |
|
|
|
104 |
|
|
%token DST SRC HOST GATEWAY |
105 |
|
|
%token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE |
106 |
|
|
%token ARP RARP IP TCP UDP ICMP IGMP IGRP PIM |
107 |
|
|
%token ATALK DECNET LAT SCA MOPRC MOPDL STP |
108 |
|
|
%token TK_BROADCAST TK_MULTICAST |
109 |
|
|
%token NUM INBOUND OUTBOUND |
110 |
|
|
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION |
111 |
|
|
%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 |
112 |
|
|
%token LINK |
113 |
|
|
%token GEQ LEQ NEQ |
114 |
|
|
%token ID EID HID HID6 |
115 |
|
|
%token LSH RSH |
116 |
|
|
%token LEN |
117 |
|
|
%token IPV6 ICMPV6 AH ESP |
118 |
|
|
%token VLAN |
119 |
|
|
|
120 |
|
|
%type <s> ID |
121 |
|
|
%type <e> EID |
122 |
|
|
%type <s> HID HID6 |
123 |
|
|
%type <i> NUM action reason type subtype dir |
124 |
|
|
|
125 |
|
|
%left OR AND |
126 |
|
|
%nonassoc '!' |
127 |
|
|
%left '|' |
128 |
|
|
%left '&' |
129 |
|
|
%left LSH RSH |
130 |
|
|
%left '+' '-' |
131 |
|
|
%left '*' '/' |
132 |
|
|
%nonassoc UMINUS |
133 |
|
|
%% |
134 |
|
|
prog: null expr |
135 |
|
|
{ |
136 |
|
|
finish_parse($2.b); |
137 |
|
|
} |
138 |
|
|
| null |
139 |
|
|
; |
140 |
|
|
null: /* null */ { $$.q = qerr; } |
141 |
|
|
; |
142 |
|
|
expr: term |
143 |
|
|
| expr and term { gen_and($1.b, $3.b); $$ = $3; } |
144 |
|
|
| expr and id { gen_and($1.b, $3.b); $$ = $3; } |
145 |
|
|
| expr or term { gen_or($1.b, $3.b); $$ = $3; } |
146 |
|
|
| expr or id { gen_or($1.b, $3.b); $$ = $3; } |
147 |
|
|
; |
148 |
|
|
and: AND { $$ = $<blk>0; } |
149 |
|
|
; |
150 |
|
|
or: OR { $$ = $<blk>0; } |
151 |
|
|
; |
152 |
|
|
id: nid |
153 |
|
|
| pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, |
154 |
|
|
$$.q = $<blk>0.q); } |
155 |
|
|
| paren pid ')' { $$ = $2; } |
156 |
|
|
; |
157 |
|
|
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); } |
158 |
|
|
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3, |
159 |
|
|
$$.q = $<blk>0.q); } |
160 |
|
|
| HID MASK HID { $$.b = gen_mcode($1, $3, 0, |
161 |
|
|
$$.q = $<blk>0.q); } |
162 |
|
|
| HID { |
163 |
|
|
/* Decide how to parse HID based on proto */ |
164 |
|
|
$$.q = $<blk>0.q; |
165 |
|
|
switch ($$.q.proto) { |
166 |
|
|
case Q_DECNET: |
167 |
|
|
$$.b = gen_ncode($1, 0, $$.q); |
168 |
|
|
break; |
169 |
|
|
default: |
170 |
|
|
$$.b = gen_ncode($1, 0, $$.q); |
171 |
|
|
break; |
172 |
|
|
} |
173 |
|
|
} |
174 |
|
|
| HID6 '/' NUM { |
175 |
|
|
#ifdef INET6 |
176 |
|
|
$$.b = gen_mcode6($1, NULL, $3, |
177 |
|
|
$$.q = $<blk>0.q); |
178 |
|
|
#else |
179 |
|
|
bpf_error("'ip6addr/prefixlen' not supported " |
180 |
|
|
"in this configuration"); |
181 |
|
|
#endif /*INET6*/ |
182 |
|
|
} |
183 |
|
|
| HID6 { |
184 |
|
|
#ifdef INET6 |
185 |
|
|
$$.b = gen_mcode6($1, 0, 128, |
186 |
|
|
$$.q = $<blk>0.q); |
187 |
|
|
#else |
188 |
|
|
bpf_error("'ip6addr' not supported " |
189 |
|
|
"in this configuration"); |
190 |
|
|
#endif /*INET6*/ |
191 |
|
|
} |
192 |
|
|
| EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); } |
193 |
|
|
| not id { gen_not($2.b); $$ = $2; } |
194 |
|
|
; |
195 |
|
|
not: '!' { $$ = $<blk>0; } |
196 |
|
|
; |
197 |
|
|
paren: '(' { $$ = $<blk>0; } |
198 |
|
|
; |
199 |
|
|
pid: nid |
200 |
|
|
| qid and id { gen_and($1.b, $3.b); $$ = $3; } |
201 |
|
|
| qid or id { gen_or($1.b, $3.b); $$ = $3; } |
202 |
|
|
; |
203 |
|
|
qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, |
204 |
|
|
$$.q = $<blk>0.q); } |
205 |
|
|
| pid |
206 |
|
|
; |
207 |
|
|
term: rterm |
208 |
|
|
| not term { gen_not($2.b); $$ = $2; } |
209 |
|
|
; |
210 |
|
|
head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } |
211 |
|
|
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } |
212 |
|
|
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } |
213 |
|
|
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } |
214 |
|
|
| pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); } |
215 |
|
|
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } |
216 |
|
|
; |
217 |
|
|
rterm: head id { $$ = $2; } |
218 |
|
|
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; } |
219 |
|
|
| pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } |
220 |
|
|
| arth relop arth { $$.b = gen_relation($2, $1, $3, 0); |
221 |
|
|
$$.q = qerr; } |
222 |
|
|
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); |
223 |
|
|
$$.q = qerr; } |
224 |
|
|
| other { $$.b = $1; $$.q = qerr; } |
225 |
|
|
; |
226 |
|
|
/* protocol level qualifiers */ |
227 |
|
|
pqual: pname |
228 |
|
|
| { $$ = Q_DEFAULT; } |
229 |
|
|
; |
230 |
|
|
/* 'direction' qualifiers */ |
231 |
|
|
dqual: SRC { $$ = Q_SRC; } |
232 |
|
|
| DST { $$ = Q_DST; } |
233 |
|
|
| SRC OR DST { $$ = Q_OR; } |
234 |
|
|
| DST OR SRC { $$ = Q_OR; } |
235 |
|
|
| SRC AND DST { $$ = Q_AND; } |
236 |
|
|
| DST AND SRC { $$ = Q_AND; } |
237 |
|
|
| ADDR1 { $$ = Q_ADDR1; } |
238 |
|
|
| ADDR2 { $$ = Q_ADDR2; } |
239 |
|
|
| ADDR3 { $$ = Q_ADDR3; } |
240 |
|
|
| ADDR4 { $$ = Q_ADDR4; } |
241 |
|
|
; |
242 |
|
|
|
243 |
|
|
/* address type qualifiers */ |
244 |
|
|
aqual: HOST { $$ = Q_HOST; } |
245 |
|
|
| NET { $$ = Q_NET; } |
246 |
|
|
| PORT { $$ = Q_PORT; } |
247 |
|
|
; |
248 |
|
|
/* non-directional address type qualifiers */ |
249 |
|
|
ndaqual: GATEWAY { $$ = Q_GATEWAY; } |
250 |
|
|
; |
251 |
|
|
pname: LINK { $$ = Q_LINK; } |
252 |
|
|
| IP { $$ = Q_IP; } |
253 |
|
|
| ARP { $$ = Q_ARP; } |
254 |
|
|
| RARP { $$ = Q_RARP; } |
255 |
|
|
| TCP { $$ = Q_TCP; } |
256 |
|
|
| UDP { $$ = Q_UDP; } |
257 |
|
|
| ICMP { $$ = Q_ICMP; } |
258 |
|
|
| IGMP { $$ = Q_IGMP; } |
259 |
|
|
| IGRP { $$ = Q_IGRP; } |
260 |
|
|
| PIM { $$ = Q_PIM; } |
261 |
|
|
| ATALK { $$ = Q_ATALK; } |
262 |
|
|
| DECNET { $$ = Q_DECNET; } |
263 |
|
|
| LAT { $$ = Q_LAT; } |
264 |
|
|
| SCA { $$ = Q_SCA; } |
265 |
|
|
| MOPDL { $$ = Q_MOPDL; } |
266 |
|
|
| MOPRC { $$ = Q_MOPRC; } |
267 |
|
|
| IPV6 { $$ = Q_IPV6; } |
268 |
|
|
| ICMPV6 { $$ = Q_ICMPV6; } |
269 |
|
|
| AH { $$ = Q_AH; } |
270 |
|
|
| ESP { $$ = Q_ESP; } |
271 |
|
|
| STP { $$ = Q_STP; } |
272 |
|
|
; |
273 |
|
|
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } |
274 |
|
|
| pqual TK_MULTICAST { $$ = gen_multicast($1); } |
275 |
|
|
| LESS NUM { $$ = gen_less($2); } |
276 |
|
|
| GREATER NUM { $$ = gen_greater($2); } |
277 |
|
|
| BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } |
278 |
|
|
| INBOUND { $$ = gen_inbound(0); } |
279 |
|
|
| OUTBOUND { $$ = gen_inbound(1); } |
280 |
|
|
| VLAN pnum { $$ = gen_vlan($2); } |
281 |
|
|
| VLAN { $$ = gen_vlan(-1); } |
282 |
|
|
| pfvar { $$ = $1; } |
283 |
|
|
| pqual p80211 { $$ = $2; } |
284 |
|
|
; |
285 |
|
|
|
286 |
|
|
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); } |
287 |
|
|
| PF_RSET ID { $$ = gen_pf_ruleset($2); } |
288 |
|
|
| PF_RNR NUM { $$ = gen_pf_rnr($2); } |
289 |
|
|
| PF_SRNR NUM { $$ = gen_pf_srnr($2); } |
290 |
|
|
| PF_REASON reason { $$ = gen_pf_reason($2); } |
291 |
|
|
| PF_ACTION action { $$ = gen_pf_action($2); } |
292 |
|
|
; |
293 |
|
|
|
294 |
|
|
reason: NUM { $$ = $1; } |
295 |
|
|
| ID { const char *reasons[] = PFRES_NAMES; |
296 |
|
|
int i; |
297 |
|
|
for (i = 0; reasons[i]; i++) { |
298 |
|
|
if (strcasecmp($1, reasons[i]) == 0) { |
299 |
|
|
$$ = i; |
300 |
|
|
break; |
301 |
|
|
} |
302 |
|
|
} |
303 |
|
|
if (reasons[i] == NULL) |
304 |
|
|
bpf_error("unknown PF reason"); |
305 |
|
|
} |
306 |
|
|
; |
307 |
|
|
|
308 |
|
|
action: ID { if (strcasecmp($1, "pass") == 0 || |
309 |
|
|
strcasecmp($1, "accept") == 0) |
310 |
|
|
$$ = PF_PASS; |
311 |
|
|
else if (strcasecmp($1, "drop") == 0 || |
312 |
|
|
strcasecmp($1, "block") == 0) |
313 |
|
|
$$ = PF_DROP; |
314 |
|
|
else if (strcasecmp($1, "match") == 0) |
315 |
|
|
$$ = PF_MATCH; |
316 |
|
|
else if (strcasecmp($1, "rdr") == 0) |
317 |
|
|
$$ = PF_RDR; |
318 |
|
|
else if (strcasecmp($1, "nat") == 0) |
319 |
|
|
$$ = PF_NAT; |
320 |
|
|
else if (strcasecmp($1, "binat") == 0) |
321 |
|
|
$$ = PF_BINAT; |
322 |
|
|
else if (strcasecmp($1, "scrub") == 0) |
323 |
|
|
$$ = PF_SCRUB; |
324 |
|
|
else |
325 |
|
|
bpf_error("unknown PF action"); |
326 |
|
|
} |
327 |
|
|
; |
328 |
|
|
|
329 |
|
|
p80211: TYPE type SUBTYPE subtype |
330 |
|
|
{ $$ = gen_p80211_type($2 | $4, |
331 |
|
|
IEEE80211_FC0_TYPE_MASK | |
332 |
|
|
IEEE80211_FC0_SUBTYPE_MASK); |
333 |
|
|
} |
334 |
|
|
| TYPE type { $$ = gen_p80211_type($2, |
335 |
|
|
IEEE80211_FC0_TYPE_MASK); } |
336 |
|
|
| SUBTYPE subtype { $$ = gen_p80211_type($2, |
337 |
|
|
IEEE80211_FC0_SUBTYPE_MASK); } |
338 |
|
|
| DIR dir { $$ = gen_p80211_fcdir($2); } |
339 |
|
|
; |
340 |
|
|
|
341 |
|
|
type: NUM |
342 |
|
|
| ID { if (strcasecmp($1, "data") == 0) |
343 |
|
|
$$ = IEEE80211_FC0_TYPE_DATA; |
344 |
|
|
else if (strcasecmp($1, "mgt") == 0 || |
345 |
|
|
strcasecmp($1, "management") == 0) |
346 |
|
|
$$ = IEEE80211_FC0_TYPE_MGT; |
347 |
|
|
else if (strcasecmp($1, "ctl") == 0 || |
348 |
|
|
strcasecmp($1, "control") == 0) |
349 |
|
|
$$ = IEEE80211_FC0_TYPE_CTL; |
350 |
|
|
else |
351 |
|
|
bpf_error("unknown 802.11 type"); |
352 |
|
|
} |
353 |
|
|
; |
354 |
|
|
|
355 |
|
|
subtype: NUM |
356 |
|
|
| ID { if (strcasecmp($1, "assocreq") == 0) |
357 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_ASSOC_REQ; |
358 |
|
|
else if (strcasecmp($1, "assocresp") == 0) |
359 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; |
360 |
|
|
else if (strcasecmp($1, "reassocreq") == 0) |
361 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_REASSOC_REQ; |
362 |
|
|
else if (strcasecmp($1, "reassocresp") == 0) |
363 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; |
364 |
|
|
else if (strcasecmp($1, "probereq") == 0) |
365 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_PROBE_REQ; |
366 |
|
|
else if (strcasecmp($1, "proberesp") == 0) |
367 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_PROBE_RESP; |
368 |
|
|
else if (strcasecmp($1, "beacon") == 0) |
369 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_BEACON; |
370 |
|
|
else if (strcasecmp($1, "atim") == 0) |
371 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_ATIM; |
372 |
|
|
else if (strcasecmp($1, "disassoc") == 0 || |
373 |
|
|
strcasecmp($1, "disassociation") == 0) |
374 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_DISASSOC; |
375 |
|
|
else if (strcasecmp($1, "auth") == 0 || |
376 |
|
|
strcasecmp($1, "authentication") == 0) |
377 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_AUTH; |
378 |
|
|
else if (strcasecmp($1, "deauth") == 0 || |
379 |
|
|
strcasecmp($1, "deauthentication") == 0) |
380 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_DEAUTH; |
381 |
|
|
else if (strcasecmp($1, "data") == 0) |
382 |
|
|
$$ = IEEE80211_FC0_SUBTYPE_DATA; |
383 |
|
|
else |
384 |
|
|
bpf_error("unknown 802.11 subtype"); |
385 |
|
|
} |
386 |
|
|
; |
387 |
|
|
|
388 |
|
|
dir: NUM |
389 |
|
|
| ID { if (strcasecmp($1, "nods") == 0) |
390 |
|
|
$$ = IEEE80211_FC1_DIR_NODS; |
391 |
|
|
else if (strcasecmp($1, "tods") == 0) |
392 |
|
|
$$ = IEEE80211_FC1_DIR_TODS; |
393 |
|
|
else if (strcasecmp($1, "fromds") == 0) |
394 |
|
|
$$ = IEEE80211_FC1_DIR_FROMDS; |
395 |
|
|
else if (strcasecmp($1, "dstods") == 0) |
396 |
|
|
$$ = IEEE80211_FC1_DIR_DSTODS; |
397 |
|
|
else |
398 |
|
|
bpf_error("unknown 802.11 direction"); |
399 |
|
|
} |
400 |
|
|
; |
401 |
|
|
|
402 |
|
|
relop: '>' { $$ = BPF_JGT; } |
403 |
|
|
| GEQ { $$ = BPF_JGE; } |
404 |
|
|
| '=' { $$ = BPF_JEQ; } |
405 |
|
|
; |
406 |
|
|
irelop: LEQ { $$ = BPF_JGT; } |
407 |
|
|
| '<' { $$ = BPF_JGE; } |
408 |
|
|
| NEQ { $$ = BPF_JEQ; } |
409 |
|
|
; |
410 |
|
|
arth: pnum { $$ = gen_loadi($1); } |
411 |
|
|
| narth |
412 |
|
|
; |
413 |
|
|
narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } |
414 |
|
|
| pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } |
415 |
|
|
| arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } |
416 |
|
|
| arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } |
417 |
|
|
| arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } |
418 |
|
|
| arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } |
419 |
|
|
| arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } |
420 |
|
|
| arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } |
421 |
|
|
| arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } |
422 |
|
|
| arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } |
423 |
|
|
| '-' arth %prec UMINUS { $$ = gen_neg($2); } |
424 |
|
|
| paren narth ')' { $$ = $2; } |
425 |
|
|
| LEN { $$ = gen_loadlen(); } |
426 |
|
|
; |
427 |
|
|
byteop: '&' { $$ = '&'; } |
428 |
|
|
| '|' { $$ = '|'; } |
429 |
|
|
| '<' { $$ = '<'; } |
430 |
|
|
| '>' { $$ = '>'; } |
431 |
|
|
| '=' { $$ = '='; } |
432 |
|
|
; |
433 |
|
|
pnum: NUM |
434 |
|
|
| paren pnum ')' { $$ = $2; } |
435 |
|
|
; |
436 |
|
|
%% |