9 typedef struct ssfilter * ssfilter_t;
11 #define YYSTYPE ssfilter_t
13 static struct ssfilter * alloc_node(int type, void *pred)
17 if (!ssfilter_is_supported(type)) {
18 fprintf(stderr, "It looks like such filter is not supported! Too old kernel?\n");
22 n = malloc(sizeof(*n));
31 static char **yy_argv;
34 static ssfilter_t *yy_ret;
35 static int tok_type = -1;
37 static int yylex(void);
39 static void yyerror(char *s)
41 fprintf(stderr, "ss: bison bellows (while parsing filter): \"%s!\"", s);
46 %token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK CGROUPCOND CGROUPPATH
60 null: /* NOTHING */ { $$ = NULL; }
66 $$ = alloc_node(SSF_OR, $1);
71 $$ = alloc_node(SSF_AND, $1);
76 $$ = alloc_node(SSF_AND, $1);
85 expr: '(' exprlist ')'
91 $$ = alloc_node(SSF_NOT, $2);
95 $$ = alloc_node(SSF_DCOND, $3);
99 $$ = alloc_node(SSF_SCOND, $3);
103 $$ = alloc_node(SSF_D_GE, $3);
107 $$ = alloc_node(SSF_D_LE, $3);
111 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_LE, $3));
115 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3));
119 $$ = alloc_node(SSF_DCOND, $3);
123 $$ = alloc_node(SSF_NOT, alloc_node(SSF_DCOND, $3));
128 $$ = alloc_node(SSF_S_GE, $3);
132 $$ = alloc_node(SSF_S_LE, $3);
136 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_LE, $3));
140 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3));
144 $$ = alloc_node(SSF_SCOND, $3);
148 $$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));
152 $$ = alloc_node(SSF_DEVCOND, $3);
154 | DEVNAME NEQ DEVCOND
156 $$ = alloc_node(SSF_NOT, alloc_node(SSF_DEVCOND, $3));
160 $$ = alloc_node(SSF_MARKMASK, $3);
162 | FWMARK NEQ MARKMASK
164 $$ = alloc_node(SSF_NOT, alloc_node(SSF_MARKMASK, $3));
166 | CGROUPPATH eq CGROUPCOND
168 $$ = alloc_node(SSF_CGROUPCOND, $3);
170 | CGROUPPATH NEQ CGROUPCOND
172 $$ = alloc_node(SSF_NOT, alloc_node(SSF_CGROUPCOND, $3));
176 $$ = alloc_node(SSF_S_AUTO, NULL);
181 static char *get_token_from_line(char **ptr)
183 char *tok, *cp = *ptr;
185 while (*cp == ' ' || *cp == '\t') cp++;
194 while (*cp != 0 && *cp != ' ' && *cp != '\t') {
195 /* Backslash escapes everything. */
198 for (tp = cp; tp != tok; tp--)
215 static char argbuf[1024];
216 static char *tokptr = argbuf;
221 while (*tokptr == 0) {
223 if (argc < yy_argc) {
224 tokptr = yy_argv[argc];
227 while (tokptr == NULL) {
230 if (fgets(argbuf, sizeof(argbuf), yy_fp) == NULL)
233 len = strnlen(argbuf, sizeof(argbuf));
235 fprintf(stderr, "Invalid line\n");
239 if (len >= sizeof(argbuf) - 1) {
240 fprintf(stderr, "Too long line in filter\n");
243 if (argbuf[len - 1] == '\n')
245 if (argbuf[0] == '#' || argbuf[0] == '0')
253 } while ((curtok = get_token_from_line(&tokptr)) == NULL);
255 if (strcmp(curtok, "!") == 0 ||
256 strcmp(curtok, "not") == 0)
258 if (strcmp(curtok, "&") == 0 ||
259 strcmp(curtok, "&&") == 0 ||
260 strcmp(curtok, "and") == 0)
262 if (strcmp(curtok, "|") == 0 ||
263 strcmp(curtok, "||") == 0 ||
264 strcmp(curtok, "or") == 0)
266 if (strcmp(curtok, "(") == 0)
268 if (strcmp(curtok, ")") == 0)
270 if (strcmp(curtok, "dst") == 0) {
274 if (strcmp(curtok, "src") == 0) {
278 if (strcmp(curtok, "dport") == 0) {
282 if (strcmp(curtok, "sport") == 0) {
286 if (strcmp(curtok, "dev") == 0) {
290 if (strcmp(curtok, "fwmark") == 0) {
294 if (strcmp(curtok, "cgroup") == 0) {
295 tok_type = CGROUPPATH;
298 if (strcmp(curtok, ">=") == 0 ||
299 strcmp(curtok, "ge") == 0 ||
300 strcmp(curtok, "geq") == 0)
302 if (strcmp(curtok, "<=") == 0 ||
303 strcmp(curtok, "le") == 0 ||
304 strcmp(curtok, "leq") == 0)
306 if (strcmp(curtok, "!=") == 0 ||
307 strcmp(curtok, "ne") == 0 ||
308 strcmp(curtok, "neq") == 0)
310 if (strcmp(curtok, "=") == 0 ||
311 strcmp(curtok, "==") == 0 ||
312 strcmp(curtok, "eq") == 0)
314 if (strcmp(curtok, ">") == 0 ||
315 strcmp(curtok, "gt") == 0)
317 if (strcmp(curtok, "<") == 0 ||
318 strcmp(curtok, "lt") == 0)
320 if (strcmp(curtok, "autobound") == 0) {
321 tok_type = AUTOBOUND;
324 if (tok_type == DEVNAME) {
325 yylval = (void*)parse_devcond(curtok);
326 if (yylval == NULL) {
327 fprintf(stderr, "Cannot parse device.\n");
332 if (tok_type == FWMARK) {
333 yylval = (void*)parse_markmask(curtok);
334 if (yylval == NULL) {
335 fprintf(stderr, "Cannot parse mark %s.\n", curtok);
340 if (tok_type == CGROUPPATH) {
341 yylval = (void*)parse_cgroupcond(curtok);
342 if (yylval == NULL) {
343 fprintf(stderr, "Cannot parse cgroup %s.\n", curtok);
348 yylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);
349 if (yylval == NULL) {
350 fprintf(stderr, "Cannot parse dst/src address.\n");
356 int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp)
364 fprintf(stderr, " Sorry.\n");