diff --git a/filter/config.Y b/filter/config.Y index 1e3a1953..00aeefc1 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -227,8 +227,22 @@ set_atom: ; set_item: - set_atom { $$ = f_new_tree(); $$->from = $$->to = $1 } - | set_atom '.' '.' set_atom { $$ = f_new_tree(); $$->from = $1; $$->to = $4; } + set_atom { + $$ = f_new_tree(); + $$->from = $1; + if ($1.type != T_PREFIX) + $$->to = $1; + else { + $$->to = $1; + $$->to.val.px.ip = ipa_or( $$->to.val.px.ip, ipa_not( ipa_mkmask( $$->to.val.px.len ) )); + } + } + | set_atom '.' '.' set_atom { + $$ = f_new_tree(); + $$->from = $1; + $$->to = $4; + if (($1.type == T_PREFIX) || ($4.type == T_PREFIX)) cf_error( "You can not use prefixes for range" ); + } ; set_items: @@ -307,6 +321,7 @@ term: | term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; } | term GEQ term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $3; $$->a2.p = $1; } | term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; } + | '!' term { $$ = f_new_inst(); $$->code = '!'; $$->a1.p = $2; } | DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = P('d','e'); $$->a1.p = $3; } | constant { $$ = $1; } @@ -336,7 +351,27 @@ term: | term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; } | term '.' LEN { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_INT; } | term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; } - | function_call { $$ = $1; /* 1 shift/reduce conflict */ } +/* function_call is inlined here */ + | SYM '(' var_list ')' { + struct symbol *sym; + struct f_inst *inst = $3; + if ($1->class != SYM_FUNCTION) + cf_error("You can not call something which is not function. Really."); + DBG("You are calling function %s\n", $1->name); + $$ = f_new_inst(); + $$->code = P('c','a'); + $$->a1.p = inst; + $$->a2.p = $1->aux2; + sym = (void *) $1->aux; + while (sym || inst) { + if (!sym || !inst) + cf_error("wrong number of arguments for function %s.", $1->name); + DBG( "You should pass parameter called %s\n", sym->name); + inst->a1.p = sym; + sym = (void *) sym->aux; + inst = inst->next; + } + } ; break_command: @@ -353,12 +388,14 @@ print_one: ; print_list: /* EMPTY */ { $$ = NULL; } - | print_one print_list { + | print_one { $$ = $1; } + | print_one ',' print_list { if ($1) { - $1->next = $2; + $1->next = $3; $$ = $1; - } else $$ = $2; + } else $$ = $3; } + ; var_listn: term { diff --git a/filter/filter.c b/filter/filter.c index f0e9cd8a..8fd0f78d 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -216,6 +216,14 @@ interpret(struct f_inst *what) case '<': COMPARE(i==-1); case P('<','='): COMPARE(i!=1); + case '!': + ONEARG; + if (v1.type != T_BOOL) + runtime( "not applied to non-boolean" ); + res = v1; + res.val.i = !res.val.i; + break; + case '~': TWOARGS; res.type = T_BOOL; @@ -466,6 +474,7 @@ i_same(struct f_inst *f1, struct f_inst *f2) case '<': case P('<','='): TWOARGS; break; + case '!': ONEARG; break; case '~': TWOARGS; break; case P('d','e'): ONEARG; break; diff --git a/filter/test.conf b/filter/test.conf index 22dba293..1677cd2f 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -13,7 +13,7 @@ int local1; int local2; int i; { - printn "Function callme called arguments " arg1 " and " arg2 ":"; + printn "Function callme called arguments ", arg1, " and ", arg2, ":" ; i = arg2; case arg1 { @@ -38,23 +38,29 @@ ip p; i = 4; i = 1230 + i; i = ( i + 0 ); - print " arithmetics: 1234 = " i; + print " arithmetics: 1234 = ", i; printn " if statements "; - if i = 4 then { print "*** FAIL: if 0"; quitbird; } else printn "."; + print "what happens here?"; + printn "."; + if (i = 4) then { print "*** FAIL: if 0"; quitbird; } else printn "."; +# if !(i = 3) then { print "*** FAIL: if 0"; quitbird; } else printn "."; if 1234 = i then printn "."; else { print "*** FAIL: if 1 else"; } - if 1 <= 1 then printn "."; else { print "*** FAIL: test 3"; } +# if 1 <= 1 then printn "."; else { print "*** FAIL: test 3"; } if 1234 < 1234 then { print "*** FAIL: test 4"; quitbird; } else print "ok"; - print " data types; must be true: " 1.2.3.4 = 1.2.3.4 "," 1 ~ [1,2,3] "," 5 ~ [1..20] "," 2 ~ [ 1, 2, 3 ] "," 5 ~ [ 4 .. 7 ] "," 1.2.3.4 ~ [ 1.2.3.3..1.2.3.5 ] "," 1.2.3.4 ~ 1.0.0.0/8 "," 1.0.0.0/8 ~ 1.0.0.0/8 "," 1.0.0.0/8 ~ [ 1.0.0.0/8+ ] "," 1.2.0.0/16 ~ [ 1.0.0.0/8{ 15 , 16 } ] "," defined(1) "," defined(1.2.3.4) "," 1 != 2 "," 1 <= 2; - print " data types: must be false: " 1 ~ [ 2, 3, 4 ] "," 5 ~ [ 2, 3, 4, 7..11 ] "," 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ] "," (1,2) > (2,2) "," (1,1) > (1,1) "," 1.0.0.0/8 ~ [ 1.0.0.0/8- ] "," 1.2.0.0/17 ~ [ 1.0.0.0/8{ 15 , 16 } ]; + print " must be true: ", 1.2.0.0/16 ~ [ 1.0.0.0/8{ 15 , 17 } ]; + print " data types; must be true: ", 1.2.3.4 = 1.2.3.4, ",", 1 ~ [1,2,3], ",", 5 ~ [1..20], ",", 2 ~ [ 1, 2, 3 ], ",", 5 ~ [ 4 .. 7 ], ",", 1.2.3.4 ~ [ 1.2.3.3..1.2.3.5 ], ",", 1.2.3.4 ~ 1.0.0.0/8, ",", 1.0.0.0/8 ~ 1.0.0.0/8, ",", 1.0.0.0/8 ~ [ 1.0.0.0/8+ ]; + +# print " must be true: ", defined(1), ",", defined(1.2.3.4), ",", 1 != 2, ",", 1 <= 2; + print " data types: must be false: ", 1 ~ [ 2, 3, 4 ], ",", 5 ~ [ 2, 3, 4, 7..11 ], ",", 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ], ",", (1,2) > (2,2), ",", (1,1) > (1,1), ",", 1.0.0.0/8 ~ [ 1.0.0.0/8- ], ",", 1.2.0.0/17 ~ [ 1.0.0.0/8{ 15 , 16 } ]; px = 1.2.0.0/18; - print "Testing prefixes: 1.2.0.0/18 = " px; + print "Testing prefixes: 1.2.0.0/18 = ", px; p = 127.1.2.3; - print "Testing mask : 127.0.0.0 = " p.mask(8); - print "Testing pairs: (1,2) = " (1,2); - print "Testing enums: " RTS_DUMMY " " RTS_STATIC; + print "Testing mask : 127.0.0.0 = ", p.mask(8); + print "Testing pairs: (1,2) = ", (1,2); + print "Testing enums: ", RTS_DUMMY, " ", RTS_STATIC; - print "What will this do? " [ 1, 2, 1, 1, 1, 3, 4, 1, 1, 1, 5 ]; + print "What will this do? ", [ 1, 2, 1, 1, 1, 3, 4, 1, 1, 1, 5 ]; print "Testing functions..."; # callme ( 1, 2 ); @@ -65,7 +71,7 @@ ip p; callme ( 7, 2 ); i = fifteen(); - print "Testing function calls: 15 = " i; + print "Testing function calls: 15 = ", i; print "done"; quitbird; @@ -75,8 +81,8 @@ ip p; filter testf int j; { - print "Heya, filtering route to " net.ip " prefixlen " net.len " source " source; - print "This route was from " from; + print "Heya, filtering route to ", net.ip, " prefixlen ", net.len, " source ", source; + print "This route was from ", from; j = 7; j = 17; if rip_metric > 15 then {