ring: remove macro with ptr dereference
[netsniff-ng.git] / src / bpf_parser.y
bloba29324bdb4b144c092a494e1f24d8196fde5fdb5
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
5 * Swiss federal institute of technology (ETH Zurich)
6 * Subject to the GPL, version 2.
7 */
9 /* yaac-func-prefix: yy */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdbool.h>
16 #include <signal.h>
17 #include <stdint.h>
18 #include <errno.h>
20 #include "bpf.h"
21 #include "xmalloc.h"
22 #include "bpf_parser.tab.h"
23 #include "built_in.h"
24 #include "die.h"
26 #define MAX_INSTRUCTIONS 4096
28 int compile_filter(char *file, int verbose, int bypass);
30 static int curr_instr = 0;
32 static struct sock_filter out[MAX_INSTRUCTIONS];
34 static char *labels[MAX_INSTRUCTIONS];
36 static char *labels_jt[MAX_INSTRUCTIONS];
37 static char *labels_jf[MAX_INSTRUCTIONS];
38 static char *labels_k[MAX_INSTRUCTIONS];
40 #define YYERROR_VERBOSE 0
41 #define YYDEBUG 0
42 #define YYENABLE_NLS 1
43 #define YYLTYPE_IS_TRIVIAL 1
44 #define ENABLE_NLS 1
46 extern FILE *yyin;
47 extern int yylex(void);
48 extern void yyerror(const char *);
49 extern int yylineno;
50 extern char *yytext;
52 static inline void check_max_instr(void)
54 if (curr_instr >= MAX_INSTRUCTIONS)
55 panic("Exceeded maximal number of instructions!\n");
58 static inline void set_curr_instr(uint16_t code, uint8_t jt, uint8_t jf, uint32_t k)
60 check_max_instr();
62 out[curr_instr].code = code;
63 out[curr_instr].jt = jt;
64 out[curr_instr].jf = jf;
65 out[curr_instr].k = k;
67 curr_instr++;
70 static inline void set_curr_label(char *label)
72 check_max_instr();
74 labels[curr_instr] = label;
77 #define JTL 1
78 #define JFL 2
79 #define JKL 3
81 static inline void set_jmp_label(char *label, int which)
83 check_max_instr();
85 switch (which) {
86 case JTL:
87 labels_jt[curr_instr] = label;
88 break;
89 case JFL:
90 labels_jf[curr_instr] = label;
91 break;
92 case JKL:
93 labels_k[curr_instr] = label;
94 break;
95 default:
96 bug();
100 static int find_intr_offset_or_panic(char *label_to_search)
102 int i, max = curr_instr, ret = -ENOENT;
104 bug_on(!label_to_search);
106 for (i = 0; i < max; ++i) {
107 if (labels[i] != NULL) {
108 /* Both are \0-terminated! */
109 if (!strcmp(label_to_search, labels[i])) {
110 ret = i;
111 break;
116 if (ret == -ENOENT)
117 panic("No such label!\n");
119 return ret;
124 %union {
125 char *label;
126 long int number;
129 %token OP_LDB OP_LDH OP_LD OP_LDX OP_ST OP_STX OP_JMP OP_JEQ OP_JGT OP_JGE
130 %token OP_JSET OP_ADD OP_SUB OP_MUL OP_DIV OP_AND OP_OR OP_XOR OP_LSH OP_RSH
131 %token OP_RET OP_TAX OP_TXA OP_LDXB OP_MOD OP_NEG OP_JNEQ OP_JLT OP_JLE OP_LDI
132 %token OP_LDXI
134 %token K_PKT_LEN K_PROTO K_TYPE K_NLATTR K_NLATTR_NEST K_MARK K_QUEUE K_HATYPE
135 %token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP
137 %token HOPT
139 %token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#'
141 %token number label
143 %type <number> number
144 %type <label> label
148 prog
149 : line
150 | prog line
153 line
154 : instr
155 | labelled_instr
158 labelled_instr
159 : labelled instr
162 instr
163 : ldb
164 | ldh
165 | ld
166 | ldi
167 | ldx
168 | ldxi
169 | st
170 | stx
171 | jmp
172 | jeq
173 | jneq
174 | jlt
175 | jle
176 | jgt
177 | jge
178 | jset
179 | add
180 | sub
181 | mul
182 | div
183 | mod
184 | neg
185 | and
186 | or
187 | xor
188 | lsh
189 | rsh
190 | ret
191 | tax
192 | txa
195 labelled
196 : label ':' { set_curr_label($1); }
200 : OP_LDB '[' 'x' '+' number ']' {
201 set_curr_instr(BPF_LD | BPF_B | BPF_IND, 0, 0, $5); }
202 | OP_LDB '[' number ']' {
203 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0, $3); }
204 | OP_LDB HOPT K_PROTO {
205 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
206 SKF_AD_OFF + SKF_AD_PROTOCOL); }
207 | OP_LDB HOPT K_TYPE {
208 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
209 SKF_AD_OFF + SKF_AD_PKTTYPE); }
210 | OP_LDB HOPT K_IFIDX {
211 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
212 SKF_AD_OFF + SKF_AD_IFINDEX); }
213 | OP_LDB HOPT K_NLATTR {
214 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
215 SKF_AD_OFF + SKF_AD_NLATTR); }
216 | OP_LDB HOPT K_NLATTR_NEST {
217 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
218 SKF_AD_OFF + SKF_AD_NLATTR_NEST); }
219 | OP_LDB HOPT K_MARK {
220 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
221 SKF_AD_OFF + SKF_AD_MARK); }
222 | OP_LDB HOPT K_QUEUE {
223 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
224 SKF_AD_OFF + SKF_AD_QUEUE); }
225 | OP_LDB HOPT K_HATYPE {
226 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
227 SKF_AD_OFF + SKF_AD_HATYPE); }
228 | OP_LDB HOPT K_RXHASH {
229 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
230 SKF_AD_OFF + SKF_AD_RXHASH); }
231 | OP_LDB HOPT K_CPU {
232 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
233 SKF_AD_OFF + SKF_AD_CPU); }
234 | OP_LDB HOPT K_VLANT {
235 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
236 SKF_AD_OFF + SKF_AD_VLAN_TAG); }
237 | OP_LDB HOPT K_VLANP {
238 set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
239 SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT); }
243 : OP_LDH '[' 'x' '+' number ']' {
244 set_curr_instr(BPF_LD | BPF_H | BPF_IND, 0, 0, $5); }
245 | OP_LDH '[' number ']' {
246 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0, $3); }
247 | OP_LDH HOPT K_PROTO {
248 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
249 SKF_AD_OFF + SKF_AD_PROTOCOL); }
250 | OP_LDH HOPT K_TYPE {
251 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
252 SKF_AD_OFF + SKF_AD_PKTTYPE); }
253 | OP_LDH HOPT K_IFIDX {
254 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
255 SKF_AD_OFF + SKF_AD_IFINDEX); }
256 | OP_LDH HOPT K_NLATTR {
257 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
258 SKF_AD_OFF + SKF_AD_NLATTR); }
259 | OP_LDH HOPT K_NLATTR_NEST {
260 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
261 SKF_AD_OFF + SKF_AD_NLATTR_NEST); }
262 | OP_LDH HOPT K_MARK {
263 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
264 SKF_AD_OFF + SKF_AD_MARK); }
265 | OP_LDH HOPT K_QUEUE {
266 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
267 SKF_AD_OFF + SKF_AD_QUEUE); }
268 | OP_LDH HOPT K_HATYPE {
269 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
270 SKF_AD_OFF + SKF_AD_HATYPE); }
271 | OP_LDH HOPT K_RXHASH {
272 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
273 SKF_AD_OFF + SKF_AD_RXHASH); }
274 | OP_LDH HOPT K_CPU {
275 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
276 SKF_AD_OFF + SKF_AD_CPU); }
277 | OP_LDH HOPT K_VLANT {
278 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
279 SKF_AD_OFF + SKF_AD_VLAN_TAG); }
280 | OP_LDH HOPT K_VLANP {
281 set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
282 SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT); }
286 : OP_LDI number {
287 set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $2); }
291 : OP_LD '#' number {
292 set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $3); }
293 | OP_LD HOPT K_PKT_LEN {
294 set_curr_instr(BPF_LD | BPF_W | BPF_LEN, 0, 0, 0); }
295 | OP_LD HOPT K_PROTO {
296 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
297 SKF_AD_OFF + SKF_AD_PROTOCOL); }
298 | OP_LD HOPT K_TYPE {
299 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
300 SKF_AD_OFF + SKF_AD_PKTTYPE); }
301 | OP_LD HOPT K_IFIDX {
302 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
303 SKF_AD_OFF + SKF_AD_IFINDEX); }
304 | OP_LD HOPT K_NLATTR {
305 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
306 SKF_AD_OFF + SKF_AD_NLATTR); }
307 | OP_LD HOPT K_NLATTR_NEST {
308 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
309 SKF_AD_OFF + SKF_AD_NLATTR_NEST); }
310 | OP_LD HOPT K_MARK {
311 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
312 SKF_AD_OFF + SKF_AD_MARK); }
313 | OP_LD HOPT K_QUEUE {
314 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
315 SKF_AD_OFF + SKF_AD_QUEUE); }
316 | OP_LD HOPT K_HATYPE {
317 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
318 SKF_AD_OFF + SKF_AD_HATYPE); }
319 | OP_LD HOPT K_RXHASH {
320 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
321 SKF_AD_OFF + SKF_AD_RXHASH); }
322 | OP_LD HOPT K_CPU {
323 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
324 SKF_AD_OFF + SKF_AD_CPU); }
325 | OP_LD HOPT K_VLANT {
326 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
327 SKF_AD_OFF + SKF_AD_VLAN_TAG); }
328 | OP_LD HOPT K_VLANP {
329 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
330 SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT); }
331 | OP_LD 'M' '[' number ']' {
332 set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); }
333 | OP_LD '[' 'x' '+' number ']' {
334 set_curr_instr(BPF_LD | BPF_W | BPF_IND, 0, 0, $5); }
335 | OP_LD '[' number ']' {
336 set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0, $3); }
339 ldxi
340 : OP_LDXI number {
341 set_curr_instr(BPF_LDX | BPF_IMM, 0, 0, $2); }
345 : OP_LDX '#' number {
346 set_curr_instr(BPF_LDX | BPF_IMM, 0, 0, $3); }
347 | OP_LDX 'M' '[' number ']' {
348 set_curr_instr(BPF_LDX | BPF_MEM, 0, 0, $4); }
349 | OP_LDXB number '*' '(' '[' number ']' '&' number ')' {
350 if ($2 != 4 || $9 != 0xf) {
351 panic("ldxb offset not supported!\n");
352 } else {
353 set_curr_instr(BPF_LDX | BPF_MSH | BPF_B, 0, 0, $6); } }
354 | OP_LDX number '*' '(' '[' number ']' '&' number ')' {
355 if ($2 != 4 || $9 != 0xf) {
356 panic("ldxb offset not supported!\n");
357 } else {
358 set_curr_instr(BPF_LDX | BPF_MSH | BPF_B, 0, 0, $6); } }
362 : OP_ST 'M' '[' number ']' {
363 set_curr_instr(BPF_ST, 0, 0, $4); }
367 : OP_STX 'M' '[' number ']' {
368 set_curr_instr(BPF_STX, 0, 0, $4); }
372 : OP_JMP label {
373 set_jmp_label($2, JKL);
374 set_curr_instr(BPF_JMP | BPF_JA, 0, 0, 0); }
378 : OP_JEQ '#' number ',' label ',' label {
379 set_jmp_label($5, JTL);
380 set_jmp_label($7, JFL);
381 set_curr_instr(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, $3); }
382 | OP_JEQ 'x' ',' label ',' label {
383 set_jmp_label($4, JTL);
384 set_jmp_label($6, JFL);
385 set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); }
386 | OP_JEQ '#' number ',' label {
387 set_jmp_label($5, JTL);
388 set_curr_instr(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, $3); }
389 | OP_JEQ 'x' ',' label {
390 set_jmp_label($4, JTL);
391 set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); }
394 jneq
395 : OP_JNEQ '#' number ',' label {
396 set_jmp_label($5, JFL);
397 set_curr_instr(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, $3); }
398 | OP_JNEQ 'x' ',' label {
399 set_jmp_label($4, JFL);
400 set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); }
404 : OP_JLT '#' number ',' label {
405 set_jmp_label($5, JFL);
406 set_curr_instr(BPF_JMP | BPF_JGE | BPF_K, 0, 0, $3); }
407 | OP_JLT 'x' ',' label {
408 set_jmp_label($4, JFL);
409 set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); }
413 : OP_JLE '#' number ',' label {
414 set_jmp_label($5, JFL);
415 set_curr_instr(BPF_JMP | BPF_JGT | BPF_K, 0, 0, $3); }
416 | OP_JLE 'x' ',' label {
417 set_jmp_label($4, JFL);
418 set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); }
422 : OP_JGT '#' number ',' label ',' label {
423 set_jmp_label($5, JTL);
424 set_jmp_label($7, JFL);
425 set_curr_instr(BPF_JMP | BPF_JGT | BPF_K, 0, 0, $3); }
426 | OP_JGT 'x' ',' label ',' label {
427 set_jmp_label($4, JTL);
428 set_jmp_label($6, JFL);
429 set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); }
430 | OP_JGT '#' number ',' label {
431 set_jmp_label($5, JTL);
432 set_curr_instr(BPF_JMP | BPF_JGT | BPF_K, 0, 0, $3); }
433 | OP_JGT 'x' ',' label {
434 set_jmp_label($4, JTL);
435 set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); }
439 : OP_JGE '#' number ',' label ',' label {
440 set_jmp_label($5, JTL);
441 set_jmp_label($7, JFL);
442 set_curr_instr(BPF_JMP | BPF_JGE | BPF_K, 0, 0, $3); }
443 | OP_JGE 'x' ',' label ',' label {
444 set_jmp_label($4, JTL);
445 set_jmp_label($6, JFL);
446 set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); }
447 | OP_JGE '#' number ',' label {
448 set_jmp_label($5, JTL);
449 set_curr_instr(BPF_JMP | BPF_JGE | BPF_K, 0, 0, $3); }
450 | OP_JGE 'x' ',' label {
451 set_jmp_label($4, JTL);
452 set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); }
455 jset
456 : OP_JSET '#' number ',' label ',' label {
457 set_jmp_label($5, JTL);
458 set_jmp_label($7, JFL);
459 set_curr_instr(BPF_JMP | BPF_JSET | BPF_K, 0, 0, $3); }
460 | OP_JSET 'x' ',' label ',' label {
461 set_jmp_label($4, JTL);
462 set_jmp_label($6, JFL);
463 set_curr_instr(BPF_JMP | BPF_JSET | BPF_X, 0, 0, 0); }
464 | OP_JSET '#' number ',' label {
465 set_jmp_label($5, JTL);
466 set_curr_instr(BPF_JMP | BPF_JSET | BPF_K, 0, 0, $3); }
467 | OP_JSET 'x' ',' label {
468 set_jmp_label($4, JTL);
469 set_curr_instr(BPF_JMP | BPF_JSET | BPF_X, 0, 0, 0); }
473 : OP_ADD '#' number {
474 set_curr_instr(BPF_ALU | BPF_ADD | BPF_K, 0, 0, $3); }
475 | OP_ADD 'x' {
476 set_curr_instr(BPF_ALU | BPF_ADD | BPF_X, 0, 0, 0); }
480 : OP_SUB '#' number {
481 set_curr_instr(BPF_ALU | BPF_SUB | BPF_K, 0, 0, $3); }
482 | OP_SUB 'x' {
483 set_curr_instr(BPF_ALU | BPF_SUB | BPF_X, 0, 0, 0); }
487 : OP_MUL '#' number {
488 set_curr_instr(BPF_ALU | BPF_MUL | BPF_K, 0, 0, $3); }
489 | OP_MUL 'x' {
490 set_curr_instr(BPF_ALU | BPF_MUL | BPF_X, 0, 0, 0); }
494 : OP_DIV '#' number {
495 set_curr_instr(BPF_ALU | BPF_DIV | BPF_K, 0, 0, $3); }
496 | OP_DIV 'x' {
497 set_curr_instr(BPF_ALU | BPF_DIV | BPF_X, 0, 0, 0); }
501 : OP_MOD '#' number {
502 set_curr_instr(BPF_ALU | BPF_MOD | BPF_K, 0, 0, $3); }
503 | OP_MOD 'x' {
504 set_curr_instr(BPF_ALU | BPF_MOD | BPF_X, 0, 0, 0); }
508 : OP_NEG {
509 set_curr_instr(BPF_ALU | BPF_NEG, 0, 0, 0); }
513 : OP_AND '#' number {
514 set_curr_instr(BPF_ALU | BPF_AND | BPF_K, 0, 0, $3); }
515 | OP_AND 'x' {
516 set_curr_instr(BPF_ALU | BPF_AND | BPF_X, 0, 0, 0); }
520 : OP_OR '#' number {
521 set_curr_instr(BPF_ALU | BPF_OR | BPF_K, 0, 0, $3); }
522 | OP_OR 'x' {
523 set_curr_instr(BPF_ALU | BPF_OR | BPF_X, 0, 0, 0); }
527 : OP_XOR '#' number {
528 set_curr_instr(BPF_ALU | BPF_XOR | BPF_K, 0, 0, $3); }
529 | OP_XOR 'x' {
530 set_curr_instr(BPF_ALU | BPF_XOR | BPF_X, 0, 0, 0); }
534 : OP_LSH '#' number {
535 set_curr_instr(BPF_ALU | BPF_LSH | BPF_K, 0, 0, $3); }
536 | OP_LSH 'x' {
537 set_curr_instr(BPF_ALU | BPF_LSH | BPF_X, 0, 0, 0); }
541 : OP_RSH '#' number {
542 set_curr_instr(BPF_ALU | BPF_RSH | BPF_K, 0, 0, $3); }
543 | OP_RSH 'x' {
544 set_curr_instr(BPF_ALU | BPF_RSH | BPF_X, 0, 0, 0); }
548 : OP_RET 'a' {
549 set_curr_instr(BPF_RET | BPF_A, 0, 0, 0); }
550 | OP_RET 'x' {
551 set_curr_instr(BPF_RET | BPF_X, 0, 0, 0); }
552 | OP_RET '#' number {
553 set_curr_instr(BPF_RET | BPF_K, 0, 0, $3); }
557 : OP_TAX {
558 set_curr_instr(BPF_MISC | BPF_TAX, 0, 0, 0); }
562 : OP_TXA {
563 set_curr_instr(BPF_MISC | BPF_TXA, 0, 0, 0); }
568 static void stage_1_inline(void)
570 yyparse();
573 static void stage_2_label_reduce(void)
575 int i, max = curr_instr, off;
577 /* 1. reduce k jumps */
578 for (i = 0; i < max; ++i) {
579 if (labels_k[i] != NULL) {
580 off = find_intr_offset_or_panic(labels_k[i]);
581 out[i].k = (uint32_t) (off - i - 1);
585 /* 1. reduce jt jumps */
586 for (i = 0; i < max; ++i) {
587 if (labels_jt[i] != NULL) {
588 off = find_intr_offset_or_panic(labels_jt[i]);
589 out[i].jt = (uint8_t) (off - i -1);
593 /* 1. reduce jf jumps */
594 for (i = 0; i < max; ++i) {
595 if (labels_jf[i] != NULL) {
596 off = find_intr_offset_or_panic(labels_jf[i]);
597 out[i].jf = (uint8_t) (off - i - 1);
602 int compile_filter(char *file, int verbose, int bypass)
604 int i;
605 struct sock_fprog res;
607 if (!strncmp("-", file, strlen("-")))
608 yyin = stdin;
609 else
610 yyin = fopen(file, "r");
611 if (!yyin)
612 panic("Cannot open file!\n");
614 memset(out, 0, sizeof(out));
615 memset(labels, 0, sizeof(labels));
616 memset(labels_jf, 0, sizeof(labels_jf));
617 memset(labels_jt, 0, sizeof(labels_jt));
618 memset(labels_k, 0, sizeof(labels_k));
620 stage_1_inline();
621 stage_2_label_reduce();
623 res.filter = out;
624 res.len = curr_instr;
626 if (verbose) {
627 printf("Generated program:\n");
628 bpf_dump_all(&res);
631 if (!bypass) {
632 if (verbose) {
633 printf("Validating: ");
634 fflush(stdout);
637 if (bpf_validate(&res) == 0) {
638 if (verbose)
639 whine("Semantic error! BPF validation "
640 "failed!\n");
641 else
642 panic("Semantic error! BPF validation failed! "
643 "Try -V for debugging output!\n");
644 } else if (verbose) {
645 printf("is runnable!\n");
649 if (verbose)
650 printf("Result:\n");
651 for (i = 0; i < res.len; ++i) {
652 printf("{ 0x%x, %u, %u, 0x%08x },\n",
653 res.filter[i].code, res.filter[i].jt,
654 res.filter[i].jf, res.filter[i].k);
655 if (labels[i] != NULL)
656 xfree(labels[i]);
657 if (labels_jt[i] != NULL)
658 xfree(labels_jt[i]);
659 if (labels_jf[i] != NULL)
660 xfree(labels_jf[i]);
661 if (labels_k[i] != NULL)
662 xfree(labels_k[i]);
665 fclose(yyin);
666 return 0;
669 void yyerror(const char *err)
671 panic("Syntax error at line %d: %s! %s!\n",
672 yylineno, yytext, err);