9 typedef struct ssfilter * ssfilter_t;
11 #define YYSTYPE ssfilter_t
13 static struct ssfilter * alloc_node(int type, void *pred)
15 struct ssfilter *n = malloc(sizeof(*n));
24 static char **yy_argv;
27 static ssfilter_t *yy_ret;
28 static int tok_type = -1;
30 static int yylex(void);
32 static void yyerror(char *s)
34 fprintf(stderr, "ss: bison bellows (while parsing filter): \"%s!\"", s);
39 %token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK
52 null: /* NOTHING */ { $$ = NULL; }
57 $$ = alloc_node(SSF_NOT, $2);
65 $$ = alloc_node(SSF_OR, $1);
70 $$ = alloc_node(SSF_AND, $1);
75 $$ = alloc_node(SSF_AND, $1);
82 $$ = alloc_node(SSF_DCOND, $2);
86 $$ = alloc_node(SSF_SCOND, $2);
90 $$ = alloc_node(SSF_D_GE, $3);
94 $$ = alloc_node(SSF_D_LE, $3);
98 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_LE, $3));
102 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3));
106 $$ = alloc_node(SSF_DCOND, $3);
110 $$ = alloc_node(SSF_NOT, alloc_node(SSF_DCOND, $3));
115 $$ = alloc_node(SSF_S_GE, $3);
119 $$ = alloc_node(SSF_S_LE, $3);
123 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_LE, $3));
127 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3));
131 $$ = alloc_node(SSF_SCOND, $3);
135 $$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));
137 | DEVNAME '=' DEVCOND
139 $$ = alloc_node(SSF_DEVCOND, $3);
141 | DEVNAME NEQ DEVCOND
143 $$ = alloc_node(SSF_NOT, alloc_node(SSF_DEVCOND, $3));
145 | FWMARK '=' MARKMASK
147 $$ = alloc_node(SSF_MARKMASK, $3);
149 | FWMARK NEQ MARKMASK
151 $$ = alloc_node(SSF_NOT, alloc_node(SSF_MARKMASK, $3));
155 $$ = alloc_node(SSF_S_AUTO, NULL);
160 static char *get_token_from_line(char **ptr)
162 char *tok, *cp = *ptr;
164 while (*cp == ' ' || *cp == '\t') cp++;
173 while (*cp != 0 && *cp != ' ' && *cp != '\t') {
174 /* Backslash escapes everything. */
177 for (tp = cp; tp != tok; tp--)
194 static char argbuf[1024];
195 static char *tokptr = argbuf;
200 while (*tokptr == 0) {
202 if (argc < yy_argc) {
203 tokptr = yy_argv[argc];
206 while (tokptr == NULL) {
209 if (fgets(argbuf, sizeof(argbuf), yy_fp) == NULL)
212 len = strnlen(argbuf, sizeof(argbuf));
214 fprintf(stderr, "Invalid line\n");
218 if (len >= sizeof(argbuf) - 1) {
219 fprintf(stderr, "Too long line in filter\n");
222 if (argbuf[len - 1] == '\n')
224 if (argbuf[0] == '#' || argbuf[0] == '0')
232 } while ((curtok = get_token_from_line(&tokptr)) == NULL);
234 if (strcmp(curtok, "!") == 0 ||
235 strcmp(curtok, "not") == 0)
237 if (strcmp(curtok, "&") == 0 ||
238 strcmp(curtok, "&&") == 0 ||
239 strcmp(curtok, "and") == 0)
241 if (strcmp(curtok, "|") == 0 ||
242 strcmp(curtok, "||") == 0 ||
243 strcmp(curtok, "or") == 0)
245 if (strcmp(curtok, "(") == 0)
247 if (strcmp(curtok, ")") == 0)
249 if (strcmp(curtok, "dst") == 0) {
253 if (strcmp(curtok, "src") == 0) {
257 if (strcmp(curtok, "dport") == 0) {
261 if (strcmp(curtok, "sport") == 0) {
265 if (strcmp(curtok, "dev") == 0) {
269 if (strcmp(curtok, "fwmark") == 0) {
273 if (strcmp(curtok, ">=") == 0 ||
274 strcmp(curtok, "ge") == 0 ||
275 strcmp(curtok, "geq") == 0)
277 if (strcmp(curtok, "<=") == 0 ||
278 strcmp(curtok, "le") == 0 ||
279 strcmp(curtok, "leq") == 0)
281 if (strcmp(curtok, "!=") == 0 ||
282 strcmp(curtok, "ne") == 0 ||
283 strcmp(curtok, "neq") == 0)
285 if (strcmp(curtok, "=") == 0 ||
286 strcmp(curtok, "==") == 0 ||
287 strcmp(curtok, "eq") == 0)
289 if (strcmp(curtok, ">") == 0 ||
290 strcmp(curtok, "gt") == 0)
292 if (strcmp(curtok, "<") == 0 ||
293 strcmp(curtok, "lt") == 0)
295 if (strcmp(curtok, "autobound") == 0) {
296 tok_type = AUTOBOUND;
299 if (tok_type == DEVNAME) {
300 yylval = (void*)parse_devcond(curtok);
301 if (yylval == NULL) {
302 fprintf(stderr, "Cannot parse device.\n");
307 if (tok_type == FWMARK) {
308 yylval = (void*)parse_markmask(curtok);
309 if (yylval == NULL) {
310 fprintf(stderr, "Cannot parse mark %s.\n", curtok);
315 yylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);
316 if (yylval == NULL) {
317 fprintf(stderr, "Cannot parse dst/src address.\n");
323 int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp)
331 fprintf(stderr, " Sorry.\n");