]> git.proxmox.com Git - mirror_iproute2.git/blame - misc/ssfilter.y
ss: remove non-functional slabinfo
[mirror_iproute2.git] / misc / ssfilter.y
CommitLineData
aba5acdf
SH
1%{
2
3#include <stdio.h>
43cc93e3 4#include <stdlib.h>
aba5acdf
SH
5#include <malloc.h>
6#include <string.h>
7#include "ssfilter.h"
8
9typedef struct ssfilter * ssfilter_t;
10
11#define YYSTYPE ssfilter_t
12
13static struct ssfilter * alloc_node(int type, void *pred)
14{
15 struct ssfilter *n = malloc(sizeof(*n));
16 if (n == NULL)
17 abort();
18 n->type = type;
19 n->pred = pred;
20 n->post = NULL;
21 return n;
22}
23
24static char **yy_argv;
25static int yy_argc;
26static FILE *yy_fp;
27static ssfilter_t *yy_ret;
7871f7db 28static int tok_type = -1;
aba5acdf
SH
29
30static int yylex(void);
31
32static void yyerror(char *s)
33{
34 fprintf(stderr, "ss: bison bellows (while parsing filter): \"%s!\"", s);
35}
36
37%}
38
ec75249b 39%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK
aba5acdf
SH
40%left '|'
41%left '&'
42%nonassoc '!'
43
44%%
b2038cc0 45applet: null exprlist
aba5acdf
SH
46 {
47 *yy_ret = $2;
48 $$ = $2;
49 }
50 | null
51 ;
52null: /* NOTHING */ { $$ = NULL; }
53 ;
b2038cc0
PS
54exprlist: expr
55 | '!' expr
56 {
57 $$ = alloc_node(SSF_NOT, $2);
58 }
59 | '(' exprlist ')'
60 {
61 $$ = $2;
62 }
63 | exprlist '|' expr
64 {
65 $$ = alloc_node(SSF_OR, $1);
66 $$->post = $3;
67 }
68 | exprlist '&' expr
69 {
70 $$ = alloc_node(SSF_AND, $1);
71 $$->post = $3;
72 }
73 | exprlist expr
74 {
75 $$ = alloc_node(SSF_AND, $1);
76 $$->post = $2;
77 }
78 ;
79
aba5acdf
SH
80expr: DCOND HOSTCOND
81 {
82 $$ = alloc_node(SSF_DCOND, $2);
83 }
84 | SCOND HOSTCOND
ae665a52 85 {
aba5acdf
SH
86 $$ = alloc_node(SSF_SCOND, $2);
87 }
88 | DPORT GEQ HOSTCOND
89 {
90 $$ = alloc_node(SSF_D_GE, $3);
91 }
92 | DPORT LEQ HOSTCOND
93 {
94 $$ = alloc_node(SSF_D_LE, $3);
95 }
96 | DPORT '>' HOSTCOND
97 {
98 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_LE, $3));
99 }
100 | DPORT '<' HOSTCOND
101 {
102 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3));
103 }
104 | DPORT '=' HOSTCOND
105 {
106 $$ = alloc_node(SSF_DCOND, $3);
107 }
108 | DPORT NEQ HOSTCOND
109 {
110 $$ = alloc_node(SSF_NOT, alloc_node(SSF_DCOND, $3));
111 }
112
113 | SPORT GEQ HOSTCOND
114 {
115 $$ = alloc_node(SSF_S_GE, $3);
116 }
117 | SPORT LEQ HOSTCOND
118 {
119 $$ = alloc_node(SSF_S_LE, $3);
120 }
121 | SPORT '>' HOSTCOND
122 {
123 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_LE, $3));
124 }
125 | SPORT '<' HOSTCOND
126 {
127 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3));
128 }
129 | SPORT '=' HOSTCOND
130 {
131 $$ = alloc_node(SSF_SCOND, $3);
132 }
133 | SPORT NEQ HOSTCOND
134 {
135 $$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));
136 }
2d293212
DA
137 | DEVNAME '=' DEVCOND
138 {
139 $$ = alloc_node(SSF_DEVCOND, $3);
140 }
141 | DEVNAME NEQ DEVCOND
142 {
143 $$ = alloc_node(SSF_NOT, alloc_node(SSF_DEVCOND, $3));
144 }
ec75249b
LC
145 | FWMARK '=' MARKMASK
146 {
147 $$ = alloc_node(SSF_MARKMASK, $3);
148 }
149 | FWMARK NEQ MARKMASK
150 {
151 $$ = alloc_node(SSF_NOT, alloc_node(SSF_MARKMASK, $3));
152 }
aba5acdf
SH
153 | AUTOBOUND
154 {
155 $$ = alloc_node(SSF_S_AUTO, NULL);
156 }
aba5acdf
SH
157;
158%%
159
160static char *get_token_from_line(char **ptr)
161{
162 char *tok, *cp = *ptr;
163
164 while (*cp == ' ' || *cp == '\t') cp++;
165
166 if (*cp == 0) {
167 *ptr = cp;
168 return NULL;
169 }
170
171 tok = cp;
172
173 while (*cp != 0 && *cp != ' ' && *cp != '\t') {
174 /* Backslash escapes everything. */
175 if (*cp == '\\') {
176 char *tp;
177 for (tp = cp; tp != tok; tp--)
178 *tp = *(tp-1);
179 cp++;
180 tok++;
181 if (*cp == 0)
182 break;
183 }
184 cp++;
185 }
186 if (*cp)
187 *cp++ = 0;
188 *ptr = cp;
189 return tok;
190}
191
192int yylex(void)
193{
194 static char argbuf[1024];
195 static char *tokptr = argbuf;
196 static int argc;
197 char *curtok;
198
199 do {
200 while (*tokptr == 0) {
201 tokptr = NULL;
202 if (argc < yy_argc) {
203 tokptr = yy_argv[argc];
204 argc++;
205 } else if (yy_fp) {
206 while (tokptr == NULL) {
50735818
SH
207 size_t len;
208
209 if (fgets(argbuf, sizeof(argbuf), yy_fp) == NULL)
aba5acdf 210 return 0;
50735818
SH
211
212 len = strnlen(argbuf, sizeof(argbuf));
213 if (len == 0) {
214 fprintf(stderr, "Invalid line\n");
215 exit(-1);
216 }
217
218 if (len >= sizeof(argbuf) - 1) {
219 fprintf(stderr, "Too long line in filter\n");
aba5acdf
SH
220 exit(-1);
221 }
50735818
SH
222 if (argbuf[len - 1] == '\n')
223 argbuf[len-1] = 0;
aba5acdf
SH
224 if (argbuf[0] == '#' || argbuf[0] == '0')
225 continue;
226 tokptr = argbuf;
227 }
228 } else {
229 return 0;
230 }
231 }
232 } while ((curtok = get_token_from_line(&tokptr)) == NULL);
233
234 if (strcmp(curtok, "!") == 0 ||
235 strcmp(curtok, "not") == 0)
236 return '!';
237 if (strcmp(curtok, "&") == 0 ||
238 strcmp(curtok, "&&") == 0 ||
239 strcmp(curtok, "and") == 0)
240 return '&';
241 if (strcmp(curtok, "|") == 0 ||
242 strcmp(curtok, "||") == 0 ||
243 strcmp(curtok, "or") == 0)
244 return '|';
245 if (strcmp(curtok, "(") == 0)
246 return '(';
247 if (strcmp(curtok, ")") == 0)
248 return ')';
7871f7db
VK
249 if (strcmp(curtok, "dst") == 0) {
250 tok_type = DCOND;
aba5acdf 251 return DCOND;
7871f7db
VK
252 }
253 if (strcmp(curtok, "src") == 0) {
254 tok_type = SCOND;
aba5acdf 255 return SCOND;
7871f7db
VK
256 }
257 if (strcmp(curtok, "dport") == 0) {
258 tok_type = DPORT;
aba5acdf 259 return DPORT;
7871f7db
VK
260 }
261 if (strcmp(curtok, "sport") == 0) {
262 tok_type = SPORT;
aba5acdf 263 return SPORT;
7871f7db 264 }
2d293212
DA
265 if (strcmp(curtok, "dev") == 0) {
266 tok_type = DEVNAME;
267 return DEVNAME;
268 }
ec75249b
LC
269 if (strcmp(curtok, "fwmark") == 0) {
270 tok_type = FWMARK;
271 return FWMARK;
272 }
aba5acdf
SH
273 if (strcmp(curtok, ">=") == 0 ||
274 strcmp(curtok, "ge") == 0 ||
275 strcmp(curtok, "geq") == 0)
276 return GEQ;
277 if (strcmp(curtok, "<=") == 0 ||
278 strcmp(curtok, "le") == 0 ||
279 strcmp(curtok, "leq") == 0)
280 return LEQ;
281 if (strcmp(curtok, "!=") == 0 ||
282 strcmp(curtok, "ne") == 0 ||
283 strcmp(curtok, "neq") == 0)
284 return NEQ;
285 if (strcmp(curtok, "=") == 0 ||
286 strcmp(curtok, "==") == 0 ||
287 strcmp(curtok, "eq") == 0)
288 return '=';
289 if (strcmp(curtok, ">") == 0 ||
290 strcmp(curtok, "gt") == 0)
291 return '>';
292 if (strcmp(curtok, "<") == 0 ||
293 strcmp(curtok, "lt") == 0)
294 return '<';
7871f7db
VK
295 if (strcmp(curtok, "autobound") == 0) {
296 tok_type = AUTOBOUND;
aba5acdf 297 return AUTOBOUND;
7871f7db 298 }
2d293212
DA
299 if (tok_type == DEVNAME) {
300 yylval = (void*)parse_devcond(curtok);
301 if (yylval == NULL) {
302 fprintf(stderr, "Cannot parse device.\n");
303 exit(1);
304 }
305 return DEVCOND;
306 }
ec75249b
LC
307 if (tok_type == FWMARK) {
308 yylval = (void*)parse_markmask(curtok);
309 if (yylval == NULL) {
310 fprintf(stderr, "Cannot parse mark %s.\n", curtok);
311 exit(1);
312 }
313 return MARKMASK;
314 }
7871f7db 315 yylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);
aba5acdf
SH
316 if (yylval == NULL) {
317 fprintf(stderr, "Cannot parse dst/src address.\n");
318 exit(1);
319 }
320 return HOSTCOND;
321}
322
323int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp)
324{
325 yy_argc = argc;
326 yy_argv = argv;
327 yy_fp = fp;
328 yy_ret = f;
329
330 if (yyparse()) {
331 fprintf(stderr, " Sorry.\n");
332 return -1;
333 }
334 return 0;
335}