bpf_hla: cont. of parser
[netsniff-ng.git] / src / bpf_hla_parser.y
blob05627646cc519743839e3d22c4f4e851e0487afc
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
5 * Swiss federal institute of technology (ETH Zurich)
6 * Subject to the GPL, version 2.
7 */
9 %{
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <errno.h>
17 #include "bpf.h"
18 #include "bpf_hla_parser.tab.h"
19 #include "bpf_symtab.h"
20 #include "xmalloc.h"
21 #include "xutils.h"
22 #include "built_in.h"
23 #include "die.h"
25 #define YYERROR_VERBOSE 0
26 #define YYDEBUG 0
27 #define YYENABLE_NLS 1
28 #define YYLTYPE_IS_TRIVIAL 1
29 #define ENABLE_NLS 1
31 extern FILE *zzin;
32 extern int zzlex(void);
33 extern void zzerror(const char *);
34 extern int zzlineno;
35 extern char *zztext;
37 int compile_hla_filter(char *file, int verbose, int debug);
39 static unsigned int num_vars = 0;
43 %union {
44 int idx;
45 long int number;
48 %token K_NAME K_DEF K_PKT K_RET K_IF K_ELIF K_ELSE
49 %token K_MACRO_IPV4 K_MACRO_IPV6 K_MACRO_IP K_MACRO_UDP K_MACRO_TCP
51 %token '(' ')' '{' '}' '=' ';' '+' '-' '&' '|' '^' '!' '<' '>' '*' '/' '%' ','
53 %token number_hex number_dec number_oct number_bin
55 %type <idx> K_NAME var
56 %type <number> number_hex number_dec number_oct number_bin number
60 program
61 : declaration_list statement_list
62 | short_ret /* for short filter statements */
65 declaration_list
66 : declaration ';' { num_vars++; } declaration_list
67 | /* empty */
70 statement_list
71 : statement ';' statement_list
72 | block statement_list
73 | /* empty */
76 declaration
77 : K_DEF K_NAME {
78 if (bpf_symtab_declared($2)) {
79 panic("Variable \"%s\" already declared (l%d)\n",
80 bpf_symtab_name($2), zzlineno);
81 } else {
82 printf("; @var %s\n", bpf_symtab_name($2));
83 bpf_symtab_declare($2);
87 block
88 : condition
91 statement
92 : assignment
93 | return
96 short_ret
97 : expression
100 return
101 : K_RET { printf("ret a\n"); }
102 | K_RET number { printf("ret #%ld\n", $2); }
103 | K_RET var { printf("ret a\n"); }
104 | K_RET expression { printf("ret macro\n"); }
107 macro
108 : K_MACRO_IPV4 { printf("ipv4\n"); }
109 | K_MACRO_IPV6 { printf("ipv6\n"); }
110 | K_MACRO_IP { printf("ip\n"); }
111 | K_MACRO_UDP { printf("udp\n"); }
112 | K_MACRO_TCP { printf("tcp\n"); }
115 condition
116 : K_IF '(' expression ')' '{' statement_list '}' condition_contd
119 condition_contd
120 : K_ELIF '(' expression ')' '{' statement_list '}' condition_contd
121 | K_ELSE '{' statement_list '}'
122 | /* None */
125 assignment
126 : var '=' expression { printf("; @asn %s\n", bpf_symtab_name($1)); }
127 | var '=' K_PKT '(' number ',' number ')' {
128 switch ($7) {
129 case 1:
130 printf("ldb [%ld]\n", $5);
131 break;
132 case 2:
133 printf("ldh [%ld]\n", $5);
134 break;
135 case 4:
136 printf("ld [%ld]\n", $5);
137 break;
138 default:
139 panic("Invalid argument (l%d)\n", zzlineno);
144 expression
145 : term
146 | '!' term { printf("; @!\n"); }
147 | term '+' term { printf("; @+\n"); }
148 | term '-' term { printf("; @-\n"); }
149 | term '/' term { printf("; @/\n"); }
150 | term '*' term { printf("; @*\n"); }
151 | term '%' term { printf("; @\n"); }
152 | term '&' term { printf("; @&\n"); }
153 | term '|' term { printf("; @|\n"); }
154 | term '^' term { printf("; @^\n"); }
155 | term '<' term { printf("; @<\n"); }
156 | term '>' term { printf("; @>\n"); }
157 | term '=' '=' term { printf("; @==\n"); }
158 | term '&' '&' term { printf("; @&&\n"); }
159 | term '|' '|' term { printf("; @||\n"); }
160 | term '<' '<' term { printf("; @<<\n"); }
161 | term '>' '>' term { printf("; @>>\n"); }
164 term
165 : number { printf("; @num %ld\n", $1); }
166 | var { printf("; @var %s\n", bpf_symtab_name($1)); }
167 | macro
168 | '(' expression ')'
172 : K_NAME {
173 if (!bpf_symtab_declared($1))
174 panic("Variable \"%s\" not declared (l%d)\n",
175 bpf_symtab_name($1), zzlineno);
176 $$ = $1; }
179 number
180 : number_dec { $$ = $1; }
181 | number_hex { $$ = $1; }
182 | number_oct { $$ = $1; }
183 | number_bin { $$ = $1; }
188 static void stage_1_compile(void)
190 zzparse();
193 int compile_hla_filter(char *file, int verbose, int debug)
195 int fd;
196 fpos_t pos;
197 char file_tmp[128];
199 if (!strncmp("-", file, strlen("-")))
200 zzin = stdin;
201 else
202 zzin = fopen(file, "r");
203 if (!zzin)
204 panic("Cannot open file!\n");
205 if (!debug) {
206 fd = dup(fileno(stdout));
208 slprintf(file_tmp, sizeof(file_tmp), ".%s", file);
209 if (freopen(file_tmp, "w", stdout) == NULL)
210 panic("Cannot reopen file!\n");
213 stage_1_compile();
215 if (!debug) {
216 fflush(stdout);
217 dup2(fd, fileno(stdout));
219 close(fd);
220 clearerr(stdout);
221 fsetpos(stdout, &pos);
224 fclose(zzin);
226 bpf_symtab_cleanup();
227 if (debug)
228 die();
230 return 0;
233 void zzerror(const char *err)
235 panic("Syntax error at line %d: %s! %s!\n",
236 zzlineno, zztext, err);