docs: authors: add Doug as minor contr. (thanks)
[netsniff-ng.git] / src / bpf_hla_parser.y
blob0f8402c67c9f0785f7b72a4f93e25407e8e9789b
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 /* yaac-func-prefix: zz */
12 TODO:
13 - intermediate representation
14 - code optimization (symbolic reduction?)
15 - linearization (jumps, etc)
16 - bpf emitter
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <errno.h>
27 #include "bpf.h"
28 #include "bpf_hla_parser.tab.h"
29 #include "bpf_symtab.h"
30 #include "xmalloc.h"
31 #include "xutils.h"
32 #include "built_in.h"
33 #include "die.h"
35 #define YYERROR_VERBOSE 0
36 #define YYDEBUG 0
37 #define YYENABLE_NLS 1
38 #define YYLTYPE_IS_TRIVIAL 1
39 #define ENABLE_NLS 1
41 extern FILE *zzin;
42 extern int zzlex(void);
43 extern void zzerror(const char *);
44 extern int zzlineno;
45 extern char *zztext;
47 int compile_hla_filter(char *file, int verbose, int debug);
49 static unsigned int num_vars = 0;
50 static unsigned int num_ifs = 0;
54 %union {
55 int idx;
56 long int number;
59 %token K_NAME K_DEF K_PKT K_RET K_IF K_ELIF K_ELSE
60 %token K_MACRO_IPV4 K_MACRO_IPV6 K_MACRO_IP K_MACRO_UDP K_MACRO_TCP
62 %token '(' ')' '{' '}' '=' ';' '+' '-' '&' '|' '^' '!' '<' '>' '*' '/' '%' ','
64 %token number_hex number_dec number_oct number_bin
66 %type <idx> K_NAME var
67 %type <number> number_hex number_dec number_oct number_bin number
71 program
72 : declaration_list { printf("_entry:\n"); } statement_list
73 | short_ret /* for short filter statements */
76 declaration_list
77 : declaration { num_vars++; } declaration_list
78 | /* empty */
81 statement_list
82 : statement statement_list
83 | statement
86 declaration
87 : K_DEF K_NAME ';' {
88 if (bpf_symtab_declared($2)) {
89 panic("Variable \"%s\" already declared (l%d)\n",
90 bpf_symtab_name($2), zzlineno);
91 } else {
92 printf("; @var %s\n", bpf_symtab_name($2));
93 bpf_symtab_declare($2);
97 block
98 : condition
101 statement
102 : assignment ';'
103 | return ';'
104 | block
107 short_ret
108 : expression
111 return
112 : K_RET { printf(" ret a\n"); }
113 | K_RET number { printf(" ret #%ld\n", $2); }
114 | K_RET var { printf(" ret a\n"); }
115 | K_RET expression { printf(" ret macro\n"); }
118 macro
119 : K_MACRO_IPV4 { printf("ipv4\n"); }
120 | K_MACRO_IPV6 { printf("ipv6\n"); }
121 | K_MACRO_IP { printf("ip\n"); }
122 | K_MACRO_UDP { printf("udp\n"); }
123 | K_MACRO_TCP { printf("tcp\n"); }
126 condition
127 : { num_ifs++; } K_IF '(' expression ')' '{'
128 { printf("jpt_f%u:\n", num_ifs); }
129 statement_list '}' condition_contd
132 condition_contd
133 : K_ELIF '(' expression ')' '{' statement_list '}' condition_contd
134 | K_ELSE '{' { printf("jpt_e%u:\n", num_ifs); } statement_list '}'
135 | /* None */
138 assignment
139 : var '=' expression { printf("; @asn %s\n", bpf_symtab_name($1)); }
140 | var '=' K_PKT '(' number ',' number ')' {
141 switch ($7) {
142 case 1:
143 printf(" ldb [%ld]\n", $5);
144 break;
145 case 2:
146 printf(" ldh [%ld]\n", $5);
147 break;
148 case 4:
149 printf(" ld [%ld]\n", $5);
150 break;
151 default:
152 panic("Invalid argument (l%d)\n", zzlineno);
157 expression
158 : term
159 | '!' term { printf("; @!\n"); }
160 | term '+' term { printf("; @+\n"); }
161 | term '-' term { printf("; @-\n"); }
162 | term '/' term { printf("; @/\n"); }
163 | term '*' term { printf("; @*\n"); }
164 | term '%' term { printf("; @\n"); }
165 | term '&' term { printf("; @&\n"); }
166 | term '|' term { printf("; @|\n"); }
167 | term '^' term { printf("; @^\n"); }
168 | term '<' term { printf("; @<\n"); }
169 | term '>' term { printf("; @>\n"); }
170 | term '=' '=' term { printf("; @==\n"); }
171 | term '&' '&' term { printf("; @&&\n"); }
172 | term '|' '|' term { printf("; @||\n"); }
173 | term '<' '<' term { printf("; @<<\n"); }
174 | term '>' '>' term { printf("; @>>\n"); }
177 term
178 : number { printf("; @num %ld\n", $1); }
179 | var { printf("; @var %s\n", bpf_symtab_name($1)); }
180 | macro
181 | '(' expression ')'
185 : K_NAME {
186 if (!bpf_symtab_declared($1))
187 panic("Variable \"%s\" not declared (l%d)\n",
188 bpf_symtab_name($1), zzlineno);
189 $$ = $1; }
192 number
193 : number_dec { $$ = $1; }
194 | number_hex { $$ = $1; }
195 | number_oct { $$ = $1; }
196 | number_bin { $$ = $1; }
201 static void stage_1_compile(void)
203 zzparse();
206 int compile_hla_filter(char *file, int verbose, int debug)
208 int fd;
209 fpos_t pos;
210 char file_tmp[128];
212 if (!strncmp("-", file, strlen("-")))
213 zzin = stdin;
214 else
215 zzin = fopen(file, "r");
216 if (!zzin)
217 panic("Cannot open file!\n");
218 if (!debug) {
219 fd = dup(fileno(stdout));
221 slprintf(file_tmp, sizeof(file_tmp), ".%s", file);
222 if (freopen(file_tmp, "w", stdout) == NULL)
223 panic("Cannot reopen file!\n");
226 stage_1_compile();
228 if (!debug) {
229 fflush(stdout);
230 dup2(fd, fileno(stdout));
232 close(fd);
233 clearerr(stdout);
234 fsetpos(stdout, &pos);
237 fclose(zzin);
239 bpf_symtab_cleanup();
240 if (debug)
241 die();
243 return 0;
246 void zzerror(const char *err)
248 panic("Syntax error at line %d: %s! %s!\n",
249 zzlineno, zztext, err);