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