... | ... |
@@ -12,7 +12,7 @@ $(yacc_f) |
12 | 12 |
objs= $(sources:.c=.o) |
13 | 13 |
depends= $(sources:.c=.d) |
14 | 14 |
|
15 |
-NAME=sip_router |
|
15 |
+NAME=ser |
|
16 | 16 |
|
17 | 17 |
# compile-time options |
18 | 18 |
# NOCR disables seeking for CRs -- breaks standard but is fast |
... | ... |
@@ -29,7 +29,7 @@ ARCH = $(shell uname -s) |
29 | 29 |
ifeq ($(ARCH), Linux) |
30 | 30 |
|
31 | 31 |
CC=gcc |
32 |
-CFLAGS=-O2 -Wcast-align #-Wmissing-prototypes -Wall |
|
32 |
+CFLAGS=-O2 -Wcast-align #-Wmissing-prototypes |
|
33 | 33 |
LEX=flex |
34 | 34 |
YACC=bison |
35 | 35 |
YACC_FLAGS=-d -b cfg |
... | ... |
@@ -1,19 +1,21 @@ |
1 | 1 |
$Id$ |
2 | 2 |
|
3 |
+( - todo, x - done) |
|
4 |
+ |
|
3 | 5 |
- better Via parsing (handle ' ' in uri, eg: foo.bar : 1234 ; received=) and |
4 | 6 |
ipv6 addresses ([fec0:aa::01]). |
5 | 7 |
|
6 | 8 |
High priority: |
7 |
-- if () {} else {} |
|
9 |
+x if () {} else {} |
|
10 |
+- ipv6 support |
|
8 | 11 |
- reply ("response line") |
9 |
-- default route ? |
|
10 | 12 |
- drop ACKs for our replies |
11 | 13 |
- icmp error handling |
12 |
-- ipv6 support |
|
13 | 14 |
- add To-tag (for the replies) |
14 | 15 |
- add User-Agent (for the replies) |
15 | 16 |
|
16 | 17 |
Low priority: |
18 |
+- command line switch for checking the config file syntax |
|
17 | 19 |
- config file version (a la sendmail) |
18 | 20 |
- loop detection |
19 | 21 |
- cfg. file reload |
... | ... |
@@ -32,9 +32,9 @@ |
32 | 32 |
int do_action(struct action* a, struct sip_msg* msg) |
33 | 33 |
{ |
34 | 34 |
int ret; |
35 |
+ int v; |
|
35 | 36 |
struct sockaddr_in* to; |
36 | 37 |
struct proxy_l* p; |
37 |
- struct route_elem* re; |
|
38 | 38 |
char* tmp; |
39 | 39 |
char *new_uri, *end, *crt; |
40 | 40 |
int len; |
... | ... |
@@ -126,14 +126,7 @@ int do_action(struct action* a, struct sip_msg* msg) |
126 | 126 |
ret=E_CFG; |
127 | 127 |
break; |
128 | 128 |
} |
129 |
- re=route_match(msg, &rlist[a->p1.number]); |
|
130 |
- if (re==0){ |
|
131 |
- LOG(L_INFO, "WARNING: do_action: route(%d): no new route" |
|
132 |
- " found\n", a->p1.number); |
|
133 |
- ret=1; |
|
134 |
- break; |
|
135 |
- } |
|
136 |
- ret=((ret=run_actions(re->actions, msg))<0)?ret:1; |
|
129 |
+ ret=((ret=run_actions(rlist[a->p1.number], msg))<0)?ret:1; |
|
137 | 130 |
break; |
138 | 131 |
case EXEC_T: |
139 | 132 |
if (a->p1_type!=STRING_ST){ |
... | ... |
@@ -178,7 +171,6 @@ int do_action(struct action* a, struct sip_msg* msg) |
178 | 171 |
ret=1; |
179 | 172 |
break; |
180 | 173 |
} |
181 |
- |
|
182 | 174 |
if (msg->new_uri) tmp=msg->new_uri; |
183 | 175 |
else tmp=msg->first_line.u.request.uri; |
184 | 176 |
if (parse_uri(tmp, strlen(tmp), &uri)<0){ |
... | ... |
@@ -264,7 +256,24 @@ int do_action(struct action* a, struct sip_msg* msg) |
264 | 256 |
msg->new_uri=new_uri; |
265 | 257 |
ret=1; |
266 | 258 |
break; |
267 |
- |
|
259 |
+ case IF_T: |
|
260 |
+ /* if null expr => ignore if? */ |
|
261 |
+ if ((a->p1_type==EXPR_ST)&&a->p1.data){ |
|
262 |
+ v=eval_expr((struct expr*)a->p1.data, msg); |
|
263 |
+ if (v<0){ |
|
264 |
+ LOG(L_WARN,"WARNING: do_action:" |
|
265 |
+ "error in expression\n"); |
|
266 |
+ } |
|
267 |
+ ret=1; /* default is continue */ |
|
268 |
+ if (v==1){ |
|
269 |
+ if ((a->p2_type==ACTIONS_ST)&&a->p2.data){ |
|
270 |
+ ret=run_actions((struct action*)a->p2.data, msg); |
|
271 |
+ } |
|
272 |
+ }else if ((a->p3_type==ACTIONS_ST)&&a->p3.data){ |
|
273 |
+ ret=run_actions((struct action*)a->p3.data, msg); |
|
274 |
+ } |
|
275 |
+ } |
|
276 |
+ break; |
|
268 | 277 |
default: |
269 | 278 |
LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type); |
270 | 279 |
} |
... | ... |
@@ -278,7 +287,8 @@ error_uri: |
278 | 287 |
|
279 | 288 |
|
280 | 289 |
|
281 |
-/* returns: 0 on success, -1 on error */ |
|
290 |
+/* returns: 0, or 1 on success, <0 on error */ |
|
291 |
+/* (0 if drop or break encountered, 1 if not ) */ |
|
282 | 292 |
int run_actions(struct action* a, struct sip_msg* msg) |
283 | 293 |
{ |
284 | 294 |
struct action* t; |
... | ... |
@@ -305,7 +315,7 @@ int run_actions(struct action* a, struct sip_msg* msg) |
305 | 315 |
} |
306 | 316 |
|
307 | 317 |
rec_lev--; |
308 |
- return 0; |
|
318 |
+ return ret; |
|
309 | 319 |
|
310 | 320 |
|
311 | 321 |
error: |
... | ... |
@@ -40,7 +40,7 @@ |
40 | 40 |
|
41 | 41 |
/* action keywords */ |
42 | 42 |
FORWARD forward |
43 |
-DROP drop |
|
43 |
+DROP "drop"|"break" |
|
44 | 44 |
SEND send |
45 | 45 |
LOG log |
46 | 46 |
ERROR error |
... | ... |
@@ -52,6 +52,8 @@ SET_USER "rewriteuser"|"setuser"|"setu" |
52 | 52 |
SET_USERPASS "rewriteuserpass"|"setuserpass"|"setup" |
53 | 53 |
SET_PORT "rewriteport"|"setport"|"setp" |
54 | 54 |
SET_URI "rewriteuri"|"seturi" |
55 |
+IF "if" |
|
56 |
+ELSE "else" |
|
55 | 57 |
|
56 | 58 |
|
57 | 59 |
/* condition keywords */ |
... | ... |
@@ -127,6 +129,8 @@ EAT_ABLE [\ \t\b\r] |
127 | 129 |
<INITIAL>{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; } |
128 | 130 |
<INITIAL>{SET_PORT} { count(); yylval.strval=yytext; return SET_PORT; } |
129 | 131 |
<INITIAL>{SET_URI} { count(); yylval.strval=yytext; return SET_URI; } |
132 |
+<INITIAL>{IF} { count(); yylval.strval=yytext; return IF; } |
|
133 |
+<INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; } |
|
130 | 134 |
|
131 | 135 |
<INITIAL>{METHOD} { count(); yylval.strval=yytext; return METHOD; } |
132 | 136 |
<INITIAL>{URI} { count(); yylval.strval=yytext; return URI; } |
... | ... |
@@ -166,7 +170,7 @@ EAT_ABLE [\ \t\b\r] |
166 | 170 |
<INITIAL>{SLASH} { count(); return SLASH; } |
167 | 171 |
<INITIAL>{DOT} { count(); return DOT; } |
168 | 172 |
<INITIAL>\\{CR} {count(); } /* eat the escaped CR */ |
169 |
-<INITIAL>{CR} { count(); return CR; } |
|
173 |
+<INITIAL>{CR} { count();/* return CR;*/ } |
|
170 | 174 |
|
171 | 175 |
|
172 | 176 |
<INITIAL>{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); } |
... | ... |
@@ -12,6 +12,7 @@ |
12 | 12 |
#include <sys/socket.h> |
13 | 13 |
#include <netinet/in.h> |
14 | 14 |
#include <arpa/inet.h> |
15 |
+#include <string.h> |
|
15 | 16 |
#include "route_struct.h" |
16 | 17 |
#include "globals.h" |
17 | 18 |
#include "route.h" |
... | ... |
@@ -33,7 +34,6 @@ char* tmp; |
33 | 34 |
struct expr* expr; |
34 | 35 |
struct action* action; |
35 | 36 |
struct net* net; |
36 |
- struct route_elem* route_el; |
|
37 | 37 |
} |
38 | 38 |
|
39 | 39 |
/* terminals */ |
... | ... |
@@ -53,6 +53,8 @@ char* tmp; |
53 | 53 |
%token SET_USERPASS |
54 | 54 |
%token SET_PORT |
55 | 55 |
%token SET_URI |
56 |
+%token IF |
|
57 |
+%token ELSE |
|
56 | 58 |
|
57 | 59 |
%token METHOD |
58 | 60 |
%token URI |
... | ... |
@@ -100,13 +102,14 @@ char* tmp; |
100 | 102 |
|
101 | 103 |
|
102 | 104 |
/*non-terminals */ |
103 |
-%type <expr> exp, condition, exp_elem |
|
104 |
-%type <action> action, actions, cmd |
|
105 |
+%type <expr> exp, exp_elem /*, condition*/ |
|
106 |
+%type <action> action, actions, cmd, if_cmd, stm |
|
105 | 107 |
%type <uval> ipv4 |
106 | 108 |
%type <net> net4 |
107 | 109 |
%type <strval> host |
108 |
-%type <route_el> rules; |
|
109 |
-%type <route_el> rule; |
|
110 |
+/*%type <route_el> rules; |
|
111 |
+ %type <route_el> rule; |
|
112 |
+*/ |
|
110 | 113 |
|
111 | 114 |
|
112 | 115 |
|
... | ... |
@@ -145,43 +148,55 @@ assign_stm: DEBUG EQUAL NUMBER { debug=$3; } |
145 | 148 |
| LISTEN EQUAL ipv4 { |
146 | 149 |
if (addresses_no < MAX_LISTEN){ |
147 | 150 |
tmp=inet_ntoa(*(struct in_addr*)&$3); |
148 |
- names[addresses_no]=(char*)malloc(strlen(tmp)+1); |
|
151 |
+ names[addresses_no]= |
|
152 |
+ (char*)malloc(strlen(tmp)+1); |
|
149 | 153 |
if (names[addresses_no]==0){ |
150 |
- LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n"); |
|
154 |
+ LOG(L_CRIT, "ERROR: cfg. parser: " |
|
155 |
+ "out of memory.\n"); |
|
151 | 156 |
}else{ |
152 |
- strncpy(names[addresses_no], tmp, strlen(tmp)+1); |
|
157 |
+ strncpy(names[addresses_no], tmp, |
|
158 |
+ strlen(tmp)+1); |
|
153 | 159 |
addresses_no++; |
154 | 160 |
} |
155 | 161 |
}else{ |
156 |
- LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses" |
|
162 |
+ LOG(L_CRIT, "ERROR: cfg. parser:" |
|
163 |
+ " too many listen addresses" |
|
157 | 164 |
"(max. %d).\n", MAX_LISTEN); |
158 | 165 |
} |
159 | 166 |
} |
160 | 167 |
| LISTEN EQUAL ID { |
161 | 168 |
if (addresses_no < MAX_LISTEN){ |
162 |
- names[addresses_no]=(char*)malloc(strlen($3)+1); |
|
169 |
+ names[addresses_no]= |
|
170 |
+ (char*)malloc(strlen($3)+1); |
|
163 | 171 |
if (names[addresses_no]==0){ |
164 |
- LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n"); |
|
172 |
+ LOG(L_CRIT, "ERROR: cfg. parser:" |
|
173 |
+ " out of memory.\n"); |
|
165 | 174 |
}else{ |
166 |
- strncpy(names[addresses_no], $3, strlen($3)+1); |
|
175 |
+ strncpy(names[addresses_no], $3, |
|
176 |
+ strlen($3)+1); |
|
167 | 177 |
addresses_no++; |
168 | 178 |
} |
169 | 179 |
}else{ |
170 |
- LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses" |
|
180 |
+ LOG(L_CRIT, "ERROR: cfg. parser: " |
|
181 |
+ "too many listen addresses" |
|
171 | 182 |
"(max. %d).\n", MAX_LISTEN); |
172 | 183 |
} |
173 | 184 |
} |
174 | 185 |
| LISTEN EQUAL STRING { |
175 | 186 |
if (addresses_no < MAX_LISTEN){ |
176 |
- names[addresses_no]=(char*)malloc(strlen($3)+1); |
|
187 |
+ names[addresses_no]= |
|
188 |
+ (char*)malloc(strlen($3)+1); |
|
177 | 189 |
if (names[addresses_no]==0){ |
178 |
- LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n"); |
|
190 |
+ LOG(L_CRIT, "ERROR: cfg. parser:" |
|
191 |
+ " out of memory.\n"); |
|
179 | 192 |
}else{ |
180 |
- strncpy(names[addresses_no], $3, strlen($3)+1); |
|
193 |
+ strncpy(names[addresses_no], $3, |
|
194 |
+ strlen($3)+1); |
|
181 | 195 |
addresses_no++; |
182 | 196 |
} |
183 | 197 |
}else{ |
184 |
- LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses" |
|
198 |
+ LOG(L_CRIT, "ERROR: cfg. parser: " |
|
199 |
+ "too many listen addresses" |
|
185 | 200 |
"(max. %d).\n", MAX_LISTEN); |
186 | 201 |
} |
187 | 202 |
} |
... | ... |
@@ -206,9 +221,9 @@ ipv4: NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { |
206 | 221 |
} |
207 | 222 |
; |
208 | 223 |
|
209 |
-route_stm: ROUTE LBRACE rules RBRACE { push($3, &rlist[DEFAULT_RT]); } |
|
224 |
+route_stm: ROUTE LBRACE actions RBRACE { push($3, &rlist[DEFAULT_RT]); } |
|
210 | 225 |
|
211 |
- | ROUTE LBRACK NUMBER RBRACK LBRACE rules RBRACE { |
|
226 |
+ | ROUTE LBRACK NUMBER RBRACK LBRACE actions RBRACE { |
|
212 | 227 |
if (($3<RT_NO) && ($3>=0)){ |
213 | 228 |
push($6, &rlist[$3]); |
214 | 229 |
}else{ |
... | ... |
@@ -218,7 +233,7 @@ route_stm: ROUTE LBRACE rules RBRACE { push($3, &rlist[DEFAULT_RT]); } |
218 | 233 |
} |
219 | 234 |
| ROUTE error { yyerror("invalid route statement"); } |
220 | 235 |
; |
221 |
- |
|
236 |
+/* |
|
222 | 237 |
rules: rules rule { push($2, &$1); $$=$1; } |
223 | 238 |
| rule {$$=$1; } |
224 | 239 |
| rules error { $$=0; yyerror("invalid rule"); } |
... | ... |
@@ -231,12 +246,12 @@ rule: condition actions CR { |
231 | 246 |
YYABORT; |
232 | 247 |
} |
233 | 248 |
} |
234 |
- | CR /* null rule */ { $$=0;} |
|
249 |
+ | CR { $$=0;} |
|
235 | 250 |
| condition error { $$=0; yyerror("bad actions in rule"); } |
236 | 251 |
; |
237 | 252 |
|
238 | 253 |
condition: exp {$$=$1;} |
239 |
- ; |
|
254 |
+*/ |
|
240 | 255 |
|
241 | 256 |
exp: exp AND exp { $$=mk_exp(AND_OP, $1, $3); } |
242 | 257 |
| exp OR exp { $$=mk_exp(OR_OP, $1, $3); } |
... | ... |
@@ -319,6 +334,8 @@ exp_elem: METHOD EQUAL_T STRING {$$= mk_elem( EQUAL_OP, STRING_ST, |
319 | 334 |
| DSTIP MATCH error { $$=0; yyerror ( "hostname expected" ); } |
320 | 335 |
| DSTIP error { $$=0; |
321 | 336 |
yyerror("invalid operator, == or =~ expected");} |
337 |
+ | stm { $$=mk_elem( NO_OP, ACTIONS_ST, ACTION_O, $1 ); } |
|
338 |
+ | NUMBER {$$=mk_elem( NO_OP, NUMBER_ST, NUMBER_O, (void*)$1 ); } |
|
322 | 339 |
; |
323 | 340 |
|
324 | 341 |
net4: ipv4 SLASH ipv4 { $$=mk_net($1, $3); } |
... | ... |
@@ -326,7 +343,8 @@ net4: ipv4 SLASH ipv4 { $$=mk_net($1, $3); } |
326 | 343 |
yyerror("invalid bit number in netmask"); |
327 | 344 |
$$=0; |
328 | 345 |
}else{ |
329 |
- $$=mk_net($1, htonl( ($3)?~( (1<<32-$3)-1 ):0 ) ); |
|
346 |
+ $$=mk_net($1, |
|
347 |
+ htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) ); |
|
330 | 348 |
} |
331 | 349 |
} |
332 | 350 |
| ipv4 { $$=mk_net($1, 0xffffffff); } |
... | ... |
@@ -337,8 +355,8 @@ net4: ipv4 SLASH ipv4 { $$=mk_net($1, $3); } |
337 | 355 |
host: ID { $$=$1; } |
338 | 356 |
| host DOT ID { $$=(char*)malloc(strlen($1)+1+strlen($3)+1); |
339 | 357 |
if ($$==0){ |
340 |
- LOG(L_CRIT, "ERROR: cfg. parser: memory allocation failure" |
|
341 |
- " while parsing host\n"); |
|
358 |
+ LOG(L_CRIT, "ERROR: cfg. parser: memory allocation" |
|
359 |
+ " failure while parsing host\n"); |
|
342 | 360 |
}else{ |
343 | 361 |
memcpy($$, $1, strlen($1)); |
344 | 362 |
$$[strlen($1)]='.'; |
... | ... |
@@ -351,6 +369,10 @@ host: ID { $$=$1; } |
351 | 369 |
; |
352 | 370 |
|
353 | 371 |
|
372 |
+stm: cmd { $$=$1; } |
|
373 |
+ | LBRACE actions RBRACE { $$=$2; } |
|
374 |
+ ; |
|
375 |
+ |
|
354 | 376 |
actions: actions action {$$=append_action($1, $2); } |
355 | 377 |
| action {$$=$1;} |
356 | 378 |
| actions error { $$=0; yyerror("bad command"); } |
... | ... |
@@ -361,6 +383,24 @@ action: cmd SEMICOLON {$$=$1;} |
361 | 383 |
| cmd error { $$=0; yyerror("bad command: missing ';'?"); } |
362 | 384 |
; |
363 | 385 |
|
386 |
+if_cmd: IF exp stm { $$=mk_action3( IF_T, |
|
387 |
+ EXPR_ST, |
|
388 |
+ ACTIONS_ST, |
|
389 |
+ NOSUBTYPE, |
|
390 |
+ $2, |
|
391 |
+ $3, |
|
392 |
+ 0); |
|
393 |
+ } |
|
394 |
+ | IF exp stm ELSE stm { $$=mk_action3( IF_T, |
|
395 |
+ EXPR_ST, |
|
396 |
+ ACTIONS_ST, |
|
397 |
+ ACTIONS_ST, |
|
398 |
+ $2, |
|
399 |
+ $3, |
|
400 |
+ $5); |
|
401 |
+ } |
|
402 |
+ ; |
|
403 |
+ |
|
364 | 404 |
cmd: FORWARD LPAREN host RPAREN { $$=mk_action( FORWARD_T, |
365 | 405 |
STRING_ST, |
366 | 406 |
NUMBER_ST, |
... | ... |
@@ -472,24 +512,37 @@ cmd: FORWARD LPAREN host RPAREN { $$=mk_action( FORWARD_T, |
472 | 512 |
| EXEC LPAREN STRING RPAREN { $$=mk_action( EXEC_T, STRING_ST, 0, |
473 | 513 |
$3, 0); |
474 | 514 |
} |
475 |
- | SET_HOST LPAREN STRING RPAREN { $$=mk_action( SET_HOST_T, STRING_ST, 0, $3, 0); } |
|
515 |
+ | SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, STRING_ST, |
|
516 |
+ 0, $3, 0); } |
|
476 | 517 |
| SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); } |
477 |
- | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); } |
|
478 |
- | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, STRING_ST, 0, $3, 0); } |
|
518 |
+ | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
|
519 |
+ "string expected"); } |
|
520 |
+ | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, |
|
521 |
+ STRING_ST, 0, $3, 0); } |
|
479 | 522 |
| SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); } |
480 |
- | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); } |
|
481 |
- | SET_PORT LPAREN STRING RPAREN { $$=mk_action( SET_PORT_T, STRING_ST, 0, $3, 0); } |
|
523 |
+ | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument," |
|
524 |
+ " string expected"); } |
|
525 |
+ | SET_PORT LPAREN STRING RPAREN { $$=mk_action( SET_PORT_T, STRING_ST, |
|
526 |
+ 0, $3, 0); } |
|
482 | 527 |
| SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); } |
483 |
- | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); } |
|
484 |
- | SET_USER LPAREN STRING RPAREN { $$=mk_action( SET_USER_T, STRING_ST, 0, $3, 0); } |
|
528 |
+ | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
|
529 |
+ "string expected"); } |
|
530 |
+ | SET_USER LPAREN STRING RPAREN { $$=mk_action( SET_USER_T, STRING_ST, |
|
531 |
+ 0, $3, 0); } |
|
485 | 532 |
| SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); } |
486 |
- | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); } |
|
487 |
- | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action( SET_USERPASS_T, STRING_ST, 0, $3, 0); } |
|
533 |
+ | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
|
534 |
+ "string expected"); } |
|
535 |
+ | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action( SET_USERPASS_T, |
|
536 |
+ STRING_ST, 0, $3, 0); } |
|
488 | 537 |
| SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); } |
489 |
- | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); } |
|
490 |
- | SET_URI LPAREN STRING RPAREN { $$=mk_action( SET_URI_T, STRING_ST, 0, $3, 0); } |
|
538 |
+ | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
|
539 |
+ "string expected"); } |
|
540 |
+ | SET_URI LPAREN STRING RPAREN { $$=mk_action( SET_URI_T, STRING_ST, |
|
541 |
+ 0, $3, 0); } |
|
491 | 542 |
| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); } |
492 |
- | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); } |
|
543 |
+ | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
|
544 |
+ "string expected"); } |
|
545 |
+ | if_cmd { $$=$1; } |
|
493 | 546 |
; |
494 | 547 |
|
495 | 548 |
|
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
|
31 | 31 |
|
32 | 32 |
static char id[]="@(#) $Id$"; |
33 |
-static char version[]="sip_router 0.6"; |
|
33 |
+static char version[]="ser 0.7"; |
|
34 | 34 |
static char flags[]="NOCR:" |
35 | 35 |
#ifdef NOCR |
36 | 36 |
"On" |
... | ... |
@@ -46,7 +46,7 @@ static char flags[]="NOCR:" |
46 | 46 |
; |
47 | 47 |
|
48 | 48 |
static char help_msg[]= "\ |
49 |
-Usage: sip_router -l address [-l address] [options]\n\ |
|
49 |
+Usage: ser -l address [-l address] [options]\n\ |
|
50 | 50 |
Options:\n\ |
51 | 51 |
-f file Configuration file (default " CFG_FILE ")\n\ |
52 | 52 |
-p port Listen on the specified port (default: 5060)\n\ |
... | ... |
@@ -345,6 +345,12 @@ int main(int argc, char** argv) |
345 | 345 |
|
346 | 346 |
|
347 | 347 |
print_rl(); |
348 |
+ /* fix routing lists */ |
|
349 |
+ if ( (r=fix_rls())!=0){ |
|
350 |
+ fprintf(stderr, "ERROR: error %x while trying to fix configuration\n", |
|
351 |
+ r); |
|
352 |
+ goto error; |
|
353 |
+ }; |
|
348 | 354 |
|
349 | 355 |
/* fix parameters */ |
350 | 356 |
if (port_no<=0) port_no=SIP_PORT; |
... | ... |
@@ -19,7 +19,6 @@ |
19 | 19 |
int receive_msg(char* buf, unsigned int len, unsigned long src_ip) |
20 | 20 |
{ |
21 | 21 |
struct sip_msg msg; |
22 |
- struct route_elem *re; |
|
23 | 22 |
|
24 | 23 |
memset(&msg,0, sizeof(struct sip_msg)); /* init everything to 0 */ |
25 | 24 |
/* fill in msg */ |
... | ... |
@@ -46,19 +45,10 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip) |
46 | 45 |
} |
47 | 46 |
/* check if neccesarry to add receive? */ |
48 | 47 |
|
49 |
- /* find route */ |
|
50 |
- re=route_match( &msg, &rlist[0]); |
|
51 |
- if (re==0){ |
|
52 |
- /* no route found, send back error msg? */ |
|
53 |
- LOG(L_WARN, "WARNING: receive_msg: no route found!\n"); |
|
54 |
- goto skip; |
|
55 |
- } |
|
56 |
- re->tx++; |
|
57 |
- /* send msg */ |
|
58 |
- DBG(" found route \n"); |
|
59 |
- if (run_actions(re->actions, &msg)<0){ |
|
48 |
+ /* exec routing script */ |
|
49 |
+ if (run_actions(rlist[0], &msg)<0){ |
|
60 | 50 |
LOG(L_WARN, "WARNING: receive_msg: " |
61 |
- "error while trying actions\n"); |
|
51 |
+ "error while trying script\n"); |
|
62 | 52 |
goto error; |
63 | 53 |
} |
64 | 54 |
}else if (msg.first_line.type==SIP_REPLY){ |
... | ... |
@@ -18,78 +18,17 @@ |
18 | 18 |
#include "route.h" |
19 | 19 |
#include "dprint.h" |
20 | 20 |
#include "proxy.h" |
21 |
+#include "action.h" |
|
21 | 22 |
|
22 | 23 |
#ifdef DEBUG_DMALLOC |
23 | 24 |
#include <dmalloc.h> |
24 | 25 |
#endif |
25 | 26 |
|
26 |
-/* main routing list */ |
|
27 |
-struct route_elem* rlist[RT_NO]; |
|
27 |
+/* main routing script table */ |
|
28 |
+struct action* rlist[RT_NO]; |
|
28 | 29 |
|
29 | 30 |
|
30 |
- |
|
31 |
- void free_re(struct route_elem* r) |
|
32 |
-{ |
|
33 |
- /*int i;*/ |
|
34 |
- if (r){ |
|
35 |
- /* |
|
36 |
- regfree(&(r->method)); |
|
37 |
- regfree(&(r->uri)); |
|
38 |
- |
|
39 |
- if (r->host.h_name) free(r->host.h_name); |
|
40 |
- if (r->host.h_aliases){ |
|
41 |
- for (i=0; r->host.h_aliases[i]; i++) |
|
42 |
- free(r->host.h_aliases[i]); |
|
43 |
- free(r->host.h_aliases); |
|
44 |
- } |
|
45 |
- if (r->host.h_addr_list){ |
|
46 |
- for (i=0; r->host.h_addr_list[i]; i++) |
|
47 |
- free(r->host.h_addr_list[i]); |
|
48 |
- free(r->host.h_addr_list); |
|
49 |
- } |
|
50 |
- */ |
|
51 |
- free(r); |
|
52 |
- } |
|
53 |
-} |
|
54 |
- |
|
55 |
- |
|
56 |
- |
|
57 |
-struct route_elem* init_re() |
|
58 |
-{ |
|
59 |
- struct route_elem* r; |
|
60 |
- r=(struct route_elem *) malloc(sizeof(struct route_elem)); |
|
61 |
- if (r==0) return 0; |
|
62 |
- memset((void*)r, 0, sizeof (struct route_elem)); |
|
63 |
- return r; |
|
64 |
-} |
|
65 |
- |
|
66 |
- |
|
67 |
-/* adds re list to head; re must be null terminated (last re->next=0))*/ |
|
68 |
-void push(struct route_elem* re, struct route_elem** head) |
|
69 |
-{ |
|
70 |
- struct route_elem *t; |
|
71 |
- if (*head==0){ |
|
72 |
- *head=re; |
|
73 |
- return; |
|
74 |
- } |
|
75 |
- for (t=*head; t->next;t=t->next); |
|
76 |
- t->next=re; |
|
77 |
-} |
|
78 |
- |
|
79 |
- |
|
80 |
- |
|
81 |
-void clear_rlist(struct route_elem** rl) |
|
82 |
-{ |
|
83 |
- struct route_elem *t, *u; |
|
84 |
- |
|
85 |
- if (*rl==0) return; |
|
86 |
- u=0; |
|
87 |
- for (t=*rl; t; u=t, t=t->next){ |
|
88 |
- if (u) free_re(u); |
|
89 |
- } |
|
90 |
- *rl=0; |
|
91 |
-} |
|
92 |
- |
|
31 |
+static int fix_actions(struct action* a); /*fwd declaration*/ |
|
93 | 32 |
|
94 | 33 |
|
95 | 34 |
/* traverses an expr tree and compiles the REs where necessary) |
... | ... |
@@ -99,6 +38,7 @@ static int fix_expr(struct expr* exp) |
99 | 38 |
regex_t* re; |
100 | 39 |
int ret; |
101 | 40 |
|
41 |
+ ret=E_BUG; |
|
102 | 42 |
if (exp==0){ |
103 | 43 |
LOG(L_CRIT, "BUG: fix_expr: null pointer\n"); |
104 | 44 |
return E_BUG; |
... | ... |
@@ -143,6 +83,13 @@ static int fix_expr(struct expr* exp) |
143 | 83 |
return E_BUG; |
144 | 84 |
} |
145 | 85 |
} |
86 |
+ if (exp->l.operand==ACTION_O){ |
|
87 |
+ ret=fix_actions((struct action*)exp->r.param); |
|
88 |
+ if (ret!=0){ |
|
89 |
+ LOG(L_CRIT, "ERROR: fix_expr : fix_actions error\n"); |
|
90 |
+ return ret; |
|
91 |
+ } |
|
92 |
+ } |
|
146 | 93 |
ret=0; |
147 | 94 |
} |
148 | 95 |
return ret; |
... | ... |
@@ -151,12 +98,18 @@ static int fix_expr(struct expr* exp) |
151 | 98 |
|
152 | 99 |
|
153 | 100 |
/* adds the proxies in the proxy list & resolves the hostnames */ |
101 |
+/* returns 0 if ok, <0 on error */ |
|
154 | 102 |
static int fix_actions(struct action* a) |
155 | 103 |
{ |
156 | 104 |
struct action *t; |
157 | 105 |
struct proxy_l* p; |
158 | 106 |
char *tmp; |
107 |
+ int ret; |
|
159 | 108 |
|
109 |
+ if (a==0){ |
|
110 |
+ LOG(L_CRIT,"BUG: fix_actions: null pointer\n"); |
|
111 |
+ return E_BUG; |
|
112 |
+ } |
|
160 | 113 |
for(t=a; t!=0; t=t->next){ |
161 | 114 |
switch(t->type){ |
162 | 115 |
case FORWARD_T: |
... | ... |
@@ -187,6 +140,36 @@ static int fix_actions(struct action* a) |
187 | 140 |
return E_BUG; |
188 | 141 |
} |
189 | 142 |
break; |
143 |
+ case IF_T: |
|
144 |
+ if (t->p1_type!=EXPR_ST){ |
|
145 |
+ LOG(L_CRIT, "BUG: fix_actions: invalid subtype" |
|
146 |
+ "%d for if (should be expr)\n", |
|
147 |
+ t->p1_type); |
|
148 |
+ return E_BUG; |
|
149 |
+ }else if( (t->p2_type!=ACTIONS_ST)&&(t->p2_type!=NOSUBTYPE) ){ |
|
150 |
+ LOG(L_CRIT, "BUG: fix_actions: invalid subtype" |
|
151 |
+ "%d for if() {...} (should be action)\n", |
|
152 |
+ t->p2_type); |
|
153 |
+ return E_BUG; |
|
154 |
+ }else if( (t->p3_type!=ACTIONS_ST)&&(t->p3_type!=NOSUBTYPE) ){ |
|
155 |
+ LOG(L_CRIT, "BUG: fix_actions: invalid subtype" |
|
156 |
+ "%d for if() {} else{...}(should be action)\n", |
|
157 |
+ t->p3_type); |
|
158 |
+ return E_BUG; |
|
159 |
+ } |
|
160 |
+ if (t->p1.data){ |
|
161 |
+ if ((ret=fix_expr((struct expr*)t->p1.data))<0) |
|
162 |
+ return ret; |
|
163 |
+ } |
|
164 |
+ if ( (t->p2_type==ACTIONS_ST)&&(t->p2.data) ){ |
|
165 |
+ if ((ret=fix_actions((struct action*)t->p2.data))<0) |
|
166 |
+ return ret; |
|
167 |
+ } |
|
168 |
+ if ( (t->p3_type==ACTIONS_ST)&&(t->p3.data) ){ |
|
169 |
+ if ((ret=fix_actions((struct action*)t->p3.data))<0) |
|
170 |
+ return ret; |
|
171 |
+ } |
|
172 |
+ break; |
|
190 | 173 |
} |
191 | 174 |
} |
192 | 175 |
return 0; |
... | ... |
@@ -277,6 +260,7 @@ static int eval_elem(struct expr* e, struct sip_msg* msg) |
277 | 260 |
{ |
278 | 261 |
|
279 | 262 |
int ret; |
263 |
+ ret=E_BUG; |
|
280 | 264 |
|
281 | 265 |
if (e->type!=ELEM_T){ |
282 | 266 |
LOG(L_CRIT," BUG: eval_elem: invalid type\n"); |
... | ... |
@@ -302,8 +286,11 @@ static int eval_elem(struct expr* e, struct sip_msg* msg) |
302 | 286 |
case DSTIP_O: |
303 | 287 |
ret=comp_ip(msg->dst_ip, e->r.param, e->op, e->subtype); |
304 | 288 |
break; |
305 |
- case DEFAULT_O: |
|
306 |
- ret=1; |
|
289 |
+ case NUMBER_O: |
|
290 |
+ ret=!(!e->r.intval); /* !! to transform it in {0,1} */ |
|
291 |
+ break; |
|
292 |
+ case ACTION_O: |
|
293 |
+ ret=(run_actions( (struct action*)e->r.param, msg)>=0)?1:0; |
|
307 | 294 |
break; |
308 | 295 |
default: |
309 | 296 |
LOG(L_CRIT, "BUG: eval_elem: invalid operand %d\n", |
... | ... |
@@ -316,7 +303,8 @@ error: |
316 | 303 |
|
317 | 304 |
|
318 | 305 |
|
319 |
-static int eval_expr(struct expr* e, struct sip_msg* msg) |
|
306 |
+/* ret= 0/1 (true/false) & -1 on error */ |
|
307 |
+int eval_expr(struct expr* e, struct sip_msg* msg) |
|
320 | 308 |
{ |
321 | 309 |
static int rec_lev=0; |
322 | 310 |
int ret; |
... | ... |
@@ -365,53 +353,56 @@ skip: |
365 | 353 |
} |
366 | 354 |
|
367 | 355 |
|
356 |
+/* adds an action list to head; a must be null terminated (last a->next=0))*/ |
|
357 |
+void push(struct action* a, struct action** head) |
|
358 |
+{ |
|
359 |
+ struct action *t; |
|
360 |
+ if (*head==0){ |
|
361 |
+ *head=a; |
|
362 |
+ return; |
|
363 |
+ } |
|
364 |
+ for (t=*head; t->next;t=t->next); |
|
365 |
+ t->next=a; |
|
366 |
+} |
|
367 |
+ |
|
368 |
+ |
|
368 | 369 |
|
369 | 370 |
|
370 |
-int add_rule(struct expr* e, struct action* a, struct route_elem** head) |
|
371 |
+int add_actions(struct action* a, struct action** head) |
|
371 | 372 |
{ |
372 |
- |
|
373 |
- struct route_elem* re; |
|
374 | 373 |
int ret; |
375 | 374 |
|
376 |
- re=init_re(); |
|
377 |
- if (re==0) return E_OUT_OF_MEM; |
|
378 |
- LOG(L_DBG, "add_rule: fixing expr...\n"); |
|
379 |
- if ((ret=fix_expr(e))!=0) goto error; |
|
380 |
- LOG(L_DBG, "add_rule: fixing actions...\n"); |
|
375 |
+ LOG(L_DBG, "add_actions: fixing actions...\n"); |
|
381 | 376 |
if ((ret=fix_actions(a))!=0) goto error; |
382 |
- re->condition=e; |
|
383 |
- re->actions=a; |
|
384 |
- |
|
385 |
- push(re,head); |
|
377 |
+ push(a,head); |
|
386 | 378 |
return 0; |
387 | 379 |
|
388 | 380 |
error: |
389 |
- free_re(re); |
|
390 | 381 |
return ret; |
391 | 382 |
} |
392 | 383 |
|
393 | 384 |
|
394 | 385 |
|
395 |
-struct route_elem* route_match(struct sip_msg* msg, struct route_elem** rl) |
|
386 |
+/* fixes all action tables */ |
|
387 |
+/* returns 0 if ok , <0 on error */ |
|
388 |
+int fix_rls() |
|
396 | 389 |
{ |
397 |
- struct route_elem* t; |
|
398 |
- if (*rl==0){ |
|
399 |
- LOG(L_ERR, "WARNING: route_match: empty routing table\n"); |
|
400 |
- return 0; |
|
401 |
- } |
|
402 |
- for (t=*rl; t; t=t->next){ |
|
403 |
- if (eval_expr(t->condition, msg)==1) return t; |
|
390 |
+ int i,ret; |
|
391 |
+ for(i=0;i<RT_NO;i++){ |
|
392 |
+ if(rlist[i]){ |
|
393 |
+ if ((ret=fix_actions(rlist[i]))!=0){ |
|
394 |
+ return ret; |
|
395 |
+ } |
|
396 |
+ } |
|
404 | 397 |
} |
405 |
- /* no match :( */ |
|
406 | 398 |
return 0; |
407 | 399 |
} |
408 | 400 |
|
409 | 401 |
|
410 |
- |
|
411 | 402 |
/* debug function, prints main routing table */ |
412 | 403 |
void print_rl() |
413 | 404 |
{ |
414 |
- struct route_elem* t; |
|
405 |
+ struct action* t; |
|
415 | 406 |
int i,j; |
416 | 407 |
|
417 | 408 |
for(j=0; j<RT_NO; j++){ |
... | ... |
@@ -421,15 +412,10 @@ void print_rl() |
421 | 412 |
} |
422 | 413 |
DBG("routing table %d:\n",j); |
423 | 414 |
for (t=rlist[j],i=0; t; i++, t=t->next){ |
424 |
- DBG("%2d.condition: ",i); |
|
425 |
- print_expr(t->condition); |
|
426 |
- DBG("\n -> "); |
|
427 |
- print_action(t->actions); |
|
428 |
- DBG("\n Statistics: tx=%d, errors=%d, tx_bytes=%d\n", |
|
429 |
- t->tx, t->errors, t->tx_bytes); |
|
415 |
+ print_action(t); |
|
430 | 416 |
} |
417 |
+ DBG("\n"); |
|
431 | 418 |
} |
432 |
- |
|
433 | 419 |
} |
434 | 420 |
|
435 | 421 |
|
... | ... |
@@ -17,31 +17,17 @@ |
17 | 17 |
/*#include "cfg_parser.h" */ |
18 | 18 |
|
19 | 19 |
|
20 |
+/* main "script table" */ |
|
21 |
+extern struct action* rlist[RT_NO]; |
|
20 | 22 |
|
21 |
-struct route_elem{ |
|
22 |
- struct route_elem* next; |
|
23 | 23 |
|
24 |
- struct expr* condition; |
|
25 |
- struct action* actions; |
|
26 |
- |
|
27 |
- int ok; /* set to 0 if an error was found sendig a pkt*/ |
|
28 |
- /*counters*/ |
|
29 |
- int errors; |
|
30 |
- int tx; |
|
31 |
- int tx_bytes; |
|
32 |
-}; |
|
33 |
- |
|
34 |
-/* main "routing table" */ |
|
35 |
-extern struct route_elem* rlist[RT_NO]; |
|
24 |
+void push(struct action* a, struct action** head); |
|
25 |
+int add_actions(struct action* a, struct action** head); |
|
26 |
+void print_rl(); |
|
27 |
+int fix_rls(); |
|
36 | 28 |
|
29 |
+int eval_expr(struct expr* e, struct sip_msg* msg); |
|
37 | 30 |
|
38 |
-void free_re(struct route_elem* re); |
|
39 |
-struct route_elem* init_re(); |
|
40 |
-void push(struct route_elem* re, struct route_elem** head); |
|
41 |
-void clear_rlist(struct route_elem** rl); |
|
42 |
-int add_rule(struct expr* e, struct action* a, struct route_elem** head); |
|
43 |
-struct route_elem* route_match(struct sip_msg* msg,struct route_elem** rl); |
|
44 |
-void print_rl(); |
|
45 | 31 |
|
46 | 32 |
|
47 | 33 |
|
... | ... |
@@ -72,6 +72,21 @@ error: |
72 | 72 |
} |
73 | 73 |
|
74 | 74 |
|
75 |
+struct action* mk_action3(int type, int p1_type, int p2_type, int p3_type, |
|
76 |
+ void* p1, void* p2, void* p3) |
|
77 |
+{ |
|
78 |
+ struct action* a; |
|
79 |
+ |
|
80 |
+ a=mk_action(type, p1_type, p2_type, p1, p2); |
|
81 |
+ if (a){ |
|
82 |
+ a->p3_type=p3_type; |
|
83 |
+ a->p3.data=p3; |
|
84 |
+ } |
|
85 |
+ return a; |
|
86 |
+} |
|
87 |
+ |
|
88 |
+ |
|
89 |
+ |
|
75 | 90 |
struct action* append_action(struct action* a, struct action* b) |
76 | 91 |
{ |
77 | 92 |
struct action *t; |
... | ... |
@@ -142,6 +157,11 @@ void print_expr(struct expr* exp) |
142 | 157 |
case DSTIP_O: |
143 | 158 |
DBG("dstip"); |
144 | 159 |
break; |
160 |
+ case NUMBER_O: |
|
161 |
+ break; |
|
162 |
+ case ACTION_O: |
|
163 |
+ print_action((struct action*) exp->r.param); |
|
164 |
+ break; |
|
145 | 165 |
default: |
146 | 166 |
DBG("UNKNOWN"); |
147 | 167 |
} |
... | ... |
@@ -152,6 +172,8 @@ void print_expr(struct expr* exp) |
152 | 172 |
case MATCH_OP: |
153 | 173 |
DBG("=~"); |
154 | 174 |
break; |
175 |
+ case NO_OP: |
|
176 |
+ break; |
|
155 | 177 |
default: |
156 | 178 |
DBG("<UNKNOWN>"); |
157 | 179 |
} |
... | ... |
@@ -168,6 +190,12 @@ void print_expr(struct expr* exp) |
168 | 190 |
case IP_ST: |
169 | 191 |
print_ip(exp->r.intval); |
170 | 192 |
break; |
193 |
+ case ACTIONS_ST: |
|
194 |
+ print_action((struct action*)exp->r.param); |
|
195 |
+ break; |
|
196 |
+ case NUMBER_ST: |
|
197 |
+ DBG("%d",exp->r.intval); |
|
198 |
+ break; |
|
171 | 199 |
default: |
172 | 200 |
DBG("type<%d>", exp->subtype); |
173 | 201 |
} |
... | ... |
@@ -248,6 +276,9 @@ void print_action(struct action* a) |
248 | 276 |
case SET_URI_T: |
249 | 277 |
DBG("seturi("); |
250 | 278 |
break; |
279 |
+ case IF_T: |
|
280 |
+ DBG("if ("); |
|
281 |
+ break; |
|
251 | 282 |
default: |
252 | 283 |
DBG("UNKNOWN("); |
253 | 284 |
} |
... | ... |
@@ -261,9 +292,16 @@ void print_action(struct action* a) |
261 | 292 |
case IP_ST: |
262 | 293 |
print_ip(t->p1.number); |
263 | 294 |
break; |
295 |
+ case EXPR_ST: |
|
296 |
+ print_expr((struct expr*)t->p1.data); |
|
297 |
+ break; |
|
298 |
+ case ACTIONS_ST: |
|
299 |
+ print_action((struct action*)t->p1.data); |
|
300 |
+ break; |
|
264 | 301 |
default: |
265 | 302 |
DBG("type<%d>", t->p1_type); |
266 | 303 |
} |
304 |
+ if (t->type==IF_T) DBG(") {"); |
|
267 | 305 |
switch(t->p2_type){ |
268 | 306 |
case NOSUBTYPE: |
269 | 307 |
break; |
... | ... |
@@ -273,10 +311,36 @@ void print_action(struct action* a) |
273 | 311 |
case NUMBER_ST: |
274 | 312 |
DBG(", %d",t->p2.number); |
275 | 313 |
break; |
314 |
+ case EXPR_ST: |
|
315 |
+ print_expr((struct expr*)t->p2.data); |
|
316 |
+ break; |
|
317 |
+ case ACTIONS_ST: |
|
318 |
+ print_action((struct action*)t->p2.data); |
|
319 |
+ break; |
|
276 | 320 |
default: |
277 | 321 |
DBG(", type<%d>", t->p2_type); |
278 | 322 |
} |
279 |
- DBG("); "); |
|
323 |
+ if (t->type==IF_T) DBG("} else {"); |
|
324 |
+ switch(t->p3_type){ |
|
325 |
+ case NOSUBTYPE: |
|
326 |
+ break; |
|
327 |
+ case STRING_ST: |
|
328 |
+ DBG(", \"%s\"", t->p3.string); |
|
329 |
+ break; |
|
330 |
+ case NUMBER_ST: |
|
331 |
+ DBG(", %d",t->p3.number); |
|
332 |
+ break; |
|
333 |
+ case EXPR_ST: |
|
334 |
+ print_expr((struct expr*)t->p3.data); |
|
335 |
+ break; |
|
336 |
+ case ACTIONS_ST: |
|
337 |
+ print_action((struct action*)t->p3.data); |
|
338 |
+ break; |
|
339 |
+ default: |
|
340 |
+ DBG(", type<%d>", t->p3_type); |
|
341 |
+ } |
|
342 |
+ if (t->type==IF_T) DBG("}; "); |
|
343 |
+ else DBG("); "); |
|
280 | 344 |
} |
281 | 345 |
} |
282 | 346 |
|
... | ... |
@@ -8,12 +8,14 @@ |
8 | 8 |
|
9 | 9 |
enum { EXP_T=1, ELEM_T }; |
10 | 10 |
enum { AND_OP=1, OR_OP, NOT_OP }; |
11 |
-enum { EQUAL_OP=10, MATCH_OP }; |
|
12 |
-enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O }; |
|
11 |
+enum { EQUAL_OP=10, MATCH_OP, NO_OP }; |
|
12 |
+enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O, ACTION_O, NUMBER_O}; |
|
13 | 13 |
|
14 |
-enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, |
|
15 |
- SET_USERPASS_T, SET_PORT_T, SET_URI_T}; |
|
16 |
-enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST }; |
|
14 |
+enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, |
|
15 |
+ SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T, |
|
16 |
+ SET_PORT_T, SET_URI_T, IF_T }; |
|
17 |
+enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST, |
|
18 |
+ EXPR_ST, ACTIONS_ST }; |
|
17 | 19 |
|
18 | 20 |
|
19 | 21 |
struct expr{ |
... | ... |
@@ -36,11 +38,12 @@ struct action{ |
36 | 38 |
int type; /* forward, drop, log, send ...*/ |
37 | 39 |
int p1_type; |
38 | 40 |
int p2_type; |
41 |
+ int p3_type; |
|
39 | 42 |
union { |
40 | 43 |
int number; |
41 | 44 |
char* string; |
42 | 45 |
void* data; |
43 |
- }p1, p2; |
|
46 |
+ }p1, p2, p3; |
|
44 | 47 |
struct action* next; |
45 | 48 |
}; |
46 | 49 |
|
... | ... |
@@ -52,7 +55,10 @@ struct net{ |
52 | 55 |
|
53 | 56 |
struct expr* mk_exp(int op, struct expr* left, struct expr* right); |
54 | 57 |
struct expr* mk_elem(int op, int subtype, int operand, void* param); |
55 |
-struct action* mk_action(int type, int p1_type, int p2_type, void* p1, void* p2); |
|
58 |
+struct action* mk_action(int type, int p1_type, int p2_type, |
|
59 |
+ void* p1, void* p2); |
|
60 |
+struct action* mk_action3(int type, int p1_type, int p2_type, int p3_type, |
|
61 |
+ void* p1, void* p2, void* p3); |
|
56 | 62 |
struct action* append_action(struct action* a, struct action* b); |
57 | 63 |
|
58 | 64 |
|