Browse code

- added rewrite support (sethost setuser, setuserpass, sethost, setport, sethostport) - allow spaces in header names (e.g: "via :") - case insensitive header name parsing - do not look anymore for the second via for requests (jiri) - fixed config match operator (was ~=, now is =~) - added config file suport for all the command line options (except -f :)) - bumped the version number

Andrei Pelinescu-Onciul authored on 25/09/2001 23:06:39
Showing 15 changed files
... ...
@@ -12,6 +12,7 @@
12 12
 #include "forward.h"
13 13
 #include "udp_server.h"
14 14
 #include "route.h"
15
+#include "msg_parser.h"
15 16
 
16 17
 #include <sys/types.h>
17 18
 #include <sys/socket.h>
... ...
@@ -21,14 +22,19 @@
21 22
 #include <arpa/inet.h>
22 23
 
23 24
 
24
-/* ret= 0 if action -> end of lis t(e.g DROP), >0
25
-   and >0 on error */
25
+/* ret= 0! if action -> end of list(e.g DROP), 
26
+      > 0 to continue processing next actions
27
+   and <0 on error */
26 28
 int do_action(struct action* a, struct sip_msg* msg)
27 29
 {
28 30
 	int ret;
29 31
 	struct sockaddr_in* to;
30 32
 	struct proxy_l* p;
31 33
 	struct route_elem* re;
34
+	char* tmp;
35
+	char *new_uri, *end, *crt;
36
+	int len;
37
+	struct sip_uri uri;
32 38
 
33 39
 	ret=E_BUG;
34 40
 	switch (a->type){
... ...
@@ -139,10 +145,119 @@ int do_action(struct action* a, struct sip_msg* msg)
139 145
 			}
140 146
 			ret=1;
141 147
 			break;
148
+		case SET_HOST_T:
149
+		case SET_HOSTPORT_T:
150
+		case SET_USER_T:
151
+		case SET_USERPASS_T:
152
+		case SET_PORT_T:
153
+		case SET_URI_T:
154
+				if (a->p1_type!=STRING_ST){
155
+					LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
156
+							a->p1_type);
157
+					ret=E_BUG;
158
+					break;
159
+				}
160
+				if (a->type==SET_URI_T){
161
+					if (msg->new_uri) free(msg->new_uri);
162
+					len=strlen(a->p1.string);
163
+					msg->new_uri=malloc(len+1);
164
+					if (msg->new_uri==0){
165
+						LOG(L_ERR, "ERROR: do_action: memory allocation failure\n");
166
+						ret=E_OUT_OF_MEM;
167
+						break;
168
+					}
169
+					memcpy(msg->new_uri, a->p1.string, len);
170
+					msg->new_uri[len]=0;
171
+					ret=1;
172
+					break;
173
+				}
174
+
175
+				if (msg->new_uri) tmp=msg->new_uri;
176
+				else tmp=msg->first_line.u.request.uri;
177
+				if (parse_uri(tmp, strlen(tmp), &uri)<0){
178
+					LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping packet\n", tmp);
179
+					ret=E_UNSPEC;
180
+					break;
181
+				}
182
+				
183
+				new_uri=malloc(MAX_URI_SIZE);
184
+				if (new_uri==0){
185
+					LOG(L_ERR, "ERROR: do_action: memory allocation failure\n");
186
+					ret=E_OUT_OF_MEM;
187
+					break;
188
+				}
189
+				end=new_uri+MAX_URI_SIZE;
190
+				crt=new_uri;
191
+				/* begin copying */
192
+				len=strlen("sip:"); if(crt+len>end) goto error_uri;
193
+				memcpy(crt,"sip:",len);crt+=len;
194
+				/* user */
195
+				if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) tmp=a->p1.string;
196
+				else tmp=uri.user;
197
+				if (tmp){
198
+					len=strlen(tmp); if(crt+len>end) goto error_uri;
199
+					memcpy(crt,tmp,len);crt+=len;
200
+				}
201
+				if (a->type==SET_USERPASS_T) tmp=0;
202
+				else tmp=uri.passwd;
203
+				/* passwd */
204
+				if (tmp){
205
+					len=strlen(":"); if(crt+len>end) goto error_uri;
206
+					memcpy(crt,":",len);crt+=len;
207
+					len=strlen(tmp); if(crt+len>end) goto error_uri;
208
+					memcpy(crt,tmp,len);crt+=len;
209
+				}
210
+				/* host */
211
+				len=strlen("@"); if(crt+len>end) goto error_uri;
212
+				memcpy(crt,"@",len);crt+=len;
213
+				if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) tmp=a->p1.string;
214
+				else tmp=uri.host;
215
+				if (tmp){
216
+					len=strlen(tmp); if(crt+len>end) goto error_uri;
217
+					memcpy(crt,tmp,len);crt+=len;
218
+				}
219
+				/* port */
220
+				if (a->type==SET_HOSTPORT_T) tmp=0;
221
+				else if (a->type==SET_PORT_T) tmp=a->p1.string;
222
+				else tmp=uri.port;
223
+				if (tmp){
224
+					len=strlen(":"); if(crt+len>end) goto error_uri;
225
+					memcpy(crt,":",len);crt+=len;
226
+					len=strlen(tmp); if(crt+len>end) goto error_uri;
227
+					memcpy(crt,tmp,len);crt+=len;
228
+				}
229
+				/* params */
230
+				tmp=uri.params;
231
+				if (tmp){
232
+					len=strlen(";"); if(crt+len>end) goto error_uri;
233
+					memcpy(crt,";",len);crt+=len;
234
+					len=strlen(tmp); if(crt+len>end) goto error_uri;
235
+					memcpy(crt,tmp,len);crt+=len;
236
+				}
237
+				/* headers */
238
+				tmp=uri.headers;
239
+				if (tmp){
240
+					len=strlen("?"); if(crt+len>end) goto error_uri;
241
+					memcpy(crt,"?",len);crt+=len;
242
+					len=strlen(tmp); if(crt+len>end) goto error_uri;
243
+					memcpy(crt,tmp,len);crt+=len;
244
+				}
245
+				*crt=0; /* null terminate the thing */
246
+				/* copy it to the msg */
247
+				if (msg->new_uri) free(msg->new_uri);
248
+				msg->new_uri=new_uri;
249
+				ret=1;
250
+				break;
251
+
142 252
 		default:
143 253
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
144 254
 	}
145 255
 	return ret;
256
+	
257
+error_uri:
258
+	LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
259
+	if (new_uri) free(new_uri);
260
+	return E_UNSPEC;
146 261
 }
147 262
 
148 263
 
... ...
@@ -7,6 +7,7 @@
7 7
 
8 8
 %{
9 9
 	#include "cfg.tab.h"
10
+	#include "dprint.h"
10 11
 	#include <string.h>
11 12
 
12 13
 	/* states */
... ...
@@ -40,6 +41,14 @@ LOG		log
40 41
 ERROR	error
41 42
 ROUTE	route
42 43
 EXEC	exec
44
+SET_HOST		"rewritehost"|"sethost"|"seth"
45
+SET_HOSTPORT	"rewritehostport"|"sethostport"|"sethp"
46
+SET_USER		"rewriteuser"|"setuser"|"setu"
47
+SET_USERPASS	"rewriteuserpass"|"setuserpass"|"setup"
48
+SET_PORT		"rewriteport"|"setport"|"setp"
49
+SET_URI			"rewriteuri"|"seturi"
50
+
51
+
43 52
 /* condition keywords */
44 53
 METHOD	method
45 54
 URI		uri
... ...
@@ -48,7 +57,7 @@ DSTIP	dst_ip
48 57
 /* operators */
49 58
 EQUAL	=
50 59
 EQUAL_T	==
51
-MATCH	~=
60
+MATCH	=~
52 61
 NOT		!|"not"
53 62
 AND		"and"|"&&"|"&"
54 63
 OR		"or"|"||"|"|"
... ...
@@ -60,6 +69,9 @@ LOGSTDERROR	log_stderror
60 69
 LISTEN		listen
61 70
 DNS		 dns
62 71
 REV_DNS	 rev_dns
72
+PORT	port
73
+CHILDREN children
74
+CHECK_VIA	check_via
63 75
 
64 76
 /* values */
65 77
 YES			"yes"|"true"|"on"|"enable"
... ...
@@ -100,10 +112,16 @@ EAT_ABLE	[\ \t\b\r]
100 112
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
101 113
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
102 114
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
103
-<INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG; }
115
+<INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
104 116
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
105 117
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
106 118
 <INITIAL>{EXEC}	{ count(); yylval.strval=yytext; return EXEC; }
119
+<INITIAL>{SET_HOST}	{ count(); yylval.strval=yytext; return SET_HOST; }
120
+<INITIAL>{SET_HOSTPORT}	{ count(); yylval.strval=yytext; return SET_HOSTPORT; }
121
+<INITIAL>{SET_USER}	{ count(); yylval.strval=yytext; return SET_USER; }
122
+<INITIAL>{SET_USERPASS}	{ count(); yylval.strval=yytext; return SET_USERPASS; }
123
+<INITIAL>{SET_PORT}	{ count(); yylval.strval=yytext; return SET_PORT; }
124
+<INITIAL>{SET_URI}	{ count(); yylval.strval=yytext; return SET_URI; }
107 125
 
108 126
 <INITIAL>{METHOD}	{ count(); yylval.strval=yytext; return METHOD; }
109 127
 <INITIAL>{URI}	{ count(); yylval.strval=yytext; return URI; }
... ...
@@ -116,6 +134,9 @@ EAT_ABLE	[\ \t\b\r]
116 134
 <INITIAL>{LISTEN}	{ count(); yylval.strval=yytext; return LISTEN; }
117 135
 <INITIAL>{DNS}	{ count(); yylval.strval=yytext; return DNS; }
118 136
 <INITIAL>{REV_DNS}	{ count(); yylval.strval=yytext; return REV_DNS; }
137
+<INITIAL>{PORT}	{ count(); yylval.strval=yytext; return PORT; }
138
+<INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
139
+<INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
119 140
 
120 141
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
121 142
 <INITIAL>{EQUAL_T}	{ count(); return EQUAL_T; }
... ...
@@ -150,17 +171,11 @@ EAT_ABLE	[\ \t\b\r]
150 171
 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
151 172
 						yytext[yyleng-1]=0; yyleng--;
152 173
 						addstr(yytext, &str);
153
-						if (str){
154
-							printf("Found string1 <%s>\n", str);
155
-						}else{
156
-							printf("WARNING: empty string\n");
157
-						}
158 174
 						yylval.strval=str; str=0;
159 175
 						return STRING;
160 176
 					}
161 177
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
162 178
 						yytext[yyleng-1]=0; yyleng--;
163
-						printf("Found string1 <%s>\n", yytext);
164 179
 						addstr(yytext, &str);
165 180
 						yylval.strval=str;
166 181
 						str=0;
... ...
@@ -196,14 +211,17 @@ EAT_ABLE	[\ \t\b\r]
196 211
 <<EOF>>							{
197 212
 									switch(state){
198 213
 										case STRING_S: 
199
-											printf("Unexpected EOF: closed string\n");
214
+											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
215
+														" unclosed string\n");
200 216
 											if (str) {free(str); str=0;}
201 217
 											break;
202 218
 										case COMMENT_S:
203
-											printf("Unexpected EOF:%d comments open\n", comment_nest);
219
+											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
220
+														" %d comments open\n", comment_nest);
204 221
 											break;
205 222
 										case COMMENT_LN_S:
206
-											printf("Unexpected EOF: comment line open\n");
223
+											LOG(L_CRIT, "ERROR: unexpected EOF:"
224
+														"comment line open\n");
207 225
 											break;
208 226
 									}
209 227
 									return 0;
... ...
@@ -231,7 +249,7 @@ static char* addstr(char * src, char ** dest)
231 249
 	}
232 250
 	return *dest;
233 251
 error:
234
-	fprintf(stderr, "lex:addstr: memory allocation error\n");
252
+	LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
235 253
 	return 0;
236 254
 }
237 255
 
... ...
@@ -8,11 +8,16 @@
8 8
 
9 9
 #include <stdlib.h>
10 10
 #include <stdio.h>
11
+#include <sys/socket.h>
12
+#include <netinet/in.h>
13
+#include <arpa/inet.h>
11 14
 #include "route_struct.h"
12 15
 #include "globals.h"
13 16
 #include "route.h"
17
+#include "dprint.h"
14 18
 
15 19
 void yyerror(char* s);
20
+char* tmp;
16 21
 
17 22
 %}
18 23
 
... ...
@@ -33,10 +38,16 @@ void yyerror(char* s);
33 38
 %token FORWARD
34 39
 %token SEND
35 40
 %token DROP
36
-%token LOG
41
+%token LOG_TOK
37 42
 %token ERROR
38 43
 %token ROUTE
39 44
 %token EXEC
45
+%token SET_HOST
46
+%token SET_HOSTPORT
47
+%token SET_USER
48
+%token SET_USERPASS
49
+%token SET_PORT
50
+%token SET_URI
40 51
 
41 52
 %token METHOD
42 53
 %token URI
... ...
@@ -50,6 +61,10 @@ void yyerror(char* s);
50 61
 %token LISTEN
51 62
 %token DNS
52 63
 %token REV_DNS
64
+%token PORT
65
+%token CHILDREN
66
+%token CHECK_VIA
67
+
53 68
 
54 69
 
55 70
 /* operators */
... ...
@@ -101,24 +116,70 @@ statements:	statements statement {}
101 116
 		| statements error { yyerror(""); YYABORT;}
102 117
 	;
103 118
 
104
-statement:	assign_stm CR
105
-		| route_stm CR
119
+statement:	assign_stm 
120
+		| route_stm 
106 121
 		| CR	/* null statement*/
107 122
 	;
108 123
 
109
-assign_stm:	DEBUG EQUAL NUMBER 
124
+assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
110 125
 		| DEBUG EQUAL error  { yyerror("number  expected"); }
111
-		| FORK  EQUAL NUMBER
126
+		| FORK  EQUAL NUMBER { dont_fork= ! $3; }
112 127
 		| FORK  EQUAL error  { yyerror("boolean value expected"); }
113
-		| LOGSTDERROR EQUAL NUMBER 
128
+		| LOGSTDERROR EQUAL NUMBER { log_stderr=$3; }
114 129
 		| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
115
-		| DNS EQUAL NUMBER
130
+		| DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
116 131
 		| DNS EQUAL error { yyerror("boolean value expected"); }
117
-		| REV_DNS EQUAL NUMBER 
132
+		| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
118 133
 		| REV_DNS EQUAL error { yyerror("boolean value expected"); }
119
-		| LISTEN EQUAL ipv4 
120
-		| LISTEN EQUAL ID 
121
-		| LISTEN EQUAL STRING
134
+		| PORT EQUAL NUMBER   { port_no=$3; }
135
+		| PORT EQUAL error    { yyerror("number expected"); } 
136
+		| CHILDREN EQUAL NUMBER { children_no=$3; }
137
+		| CHILDREN EQUAL error { yyerror("number expected"); } 
138
+		| CHECK_VIA EQUAL NUMBER { check_via=$3; }
139
+		| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
140
+		| LISTEN EQUAL ipv4  {
141
+								if (addresses_no < MAX_LISTEN){
142
+									tmp=inet_ntoa(*(struct in_addr*)&$3);
143
+									names[addresses_no]=(char*)malloc(strlen(tmp)+1);
144
+									if (names[addresses_no]==0){
145
+										LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
146
+									}else{
147
+										strncpy(names[addresses_no], tmp, strlen(tmp)+1);
148
+										addresses_no++;
149
+									}
150
+								}else{
151
+									LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses"
152
+												"(max. %d).\n", MAX_LISTEN);
153
+								}
154
+							  }
155
+		| LISTEN EQUAL ID	 {
156
+								if (addresses_no < MAX_LISTEN){
157
+									names[addresses_no]=(char*)malloc(strlen($3)+1);
158
+									if (names[addresses_no]==0){
159
+										LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
160
+									}else{
161
+										strncpy(names[addresses_no], $3, strlen($3)+1);
162
+										addresses_no++;
163
+									}
164
+								}else{
165
+									LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses"
166
+												"(max. %d).\n", MAX_LISTEN);
167
+								}
168
+							  }
169
+		| LISTEN EQUAL STRING {
170
+								if (addresses_no < MAX_LISTEN){
171
+									names[addresses_no]=(char*)malloc(strlen($3)+1);
172
+									if (names[addresses_no]==0){
173
+										LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
174
+									}else{
175
+										strncpy(names[addresses_no], $3, strlen($3)+1);
176
+										addresses_no++;
177
+									}
178
+								}else{
179
+									LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses"
180
+												"(max. %d).\n", MAX_LISTEN);
181
+								}
182
+							  }
122 183
 		| LISTEN EQUAL  error { yyerror("ip address or hostname"
123 184
 						"expected"); }
124 185
 		| error EQUAL { yyerror("unknown config variable"); }
... ...
@@ -153,26 +214,19 @@ route_stm:	ROUTE LBRACE rules RBRACE { push($3, &rlist[DEFAULT_RT]); }
153 214
 		| ROUTE error { yyerror("invalid  route  statement"); }
154 215
 	;
155 216
 
156
-rules:	rules rule { push($2, &$1); $$=$1; 
157
-						printf(": rules->rules(%x) rule(%x)\n", $1,$2);}
158
-	| rule {$$=$1; printf(": rules->rule (%x)\n",$1); }
217
+rules:	rules rule { push($2, &$1); $$=$1; }
218
+	| rule {$$=$1; }
159 219
 	| rules error { $$=0; yyerror("invalid rule"); }
160 220
 	 ;
161 221
 
162 222
 rule:	condition	actions CR {
163
-								printf("Got a new rule!\n");
164
-								printf("expr: "); print_expr($1);
165
-								printf("\n  -> actions: ");
166
-								print_action($2); printf("\n");
167
-
168 223
 								$$=0;
169 224
 								if (add_rule($1, $2, &$$)<0) {
170 225
 									yyerror("error calling add_rule");
171 226
 									YYABORT;
172 227
 								}
173
-								printf(": rule -> condition actions CR\n");
174 228
 							  }
175
-	| CR  /* null rule */		{ $$=0; printf(": rule-> CR!\n"); }
229
+	| CR  /* null rule */		{ $$=0;}
176 230
 	| condition error { $$=0; yyerror("bad actions in rule"); }
177 231
 	;
178 232
 
... ...
@@ -201,7 +255,7 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
201 255
 				 			}
202 256
 		| METHOD MATCH error { $$=0; yyerror("string expected"); }
203 257
 		| METHOD error	{ $$=0; yyerror("invalid operator,"
204
-										"== or ~= expected");
258
+										"== or =~ expected");
205 259
 						}
206 260
 		| URI EQUAL_T STRING 	{$$ = mk_elem(	EQUAL_OP, STRING_ST,
207 261
 												URI_O, $3); 
... ...
@@ -218,7 +272,7 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
218 272
 							}
219 273
 		| URI MATCH error {  $$=0; yyerror("string expected"); }
220 274
 		| URI error	{ $$=0; yyerror("invalid operator,"
221
-				  					" == or ~= expected");
275
+				  					" == or =~ expected");
222 276
 					}
223 277
 		| SRCIP EQUAL_T net4	{ $$=mk_elem(	EQUAL_OP, NET_ST,
224 278
 												SRCIP_O, $3);
... ...
@@ -239,7 +293,7 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
239 293
 								}
240 294
 		| SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
241 295
 		| SRCIP error  { $$=0; 
242
-						 yyerror("invalid operator, == or ~= expected");}
296
+						 yyerror("invalid operator, == or =~ expected");}
243 297
 		| DSTIP EQUAL_T net4	{ $$=mk_elem(	EQUAL_OP, NET_ST,
244 298
 												DSTIP_O, $3);
245 299
 								}
... ...
@@ -259,7 +313,7 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
259 313
 							}
260 314
 		| DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
261 315
 		| DSTIP error { $$=0; 
262
-						yyerror("invalid operator, == or ~= expected");}
316
+						yyerror("invalid operator, == or =~ expected");}
263 317
 	;
264 318
 
265 319
 net4:	ipv4 SLASH ipv4	{ $$=mk_net($1, $3); } 
... ...
@@ -278,7 +332,7 @@ net4:	ipv4 SLASH ipv4	{ $$=mk_net($1, $3); }
278 332
 host:	ID				{ $$=$1; }
279 333
 	| host DOT ID		{ $$=(char*)malloc(strlen($1)+1+strlen($3)+1);
280 334
 						  if ($$==0){
281
-						  	fprintf(stderr, "memory allocation failure"
335
+						  	LOG(L_CRIT, "ERROR: cfg. parser: memory allocation failure"
282 336
 						 				" while parsing host\n");
283 337
 						  }else{
284 338
 						  	memcpy($$, $1, strlen($1));
... ...
@@ -382,17 +436,17 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
382 436
 													"argument"); }
383 437
 		| DROP LPAREN RPAREN	{$$=mk_action(DROP_T,0, 0, 0, 0); }
384 438
 		| DROP					{$$=mk_action(DROP_T,0, 0, 0, 0); }
385
-		| LOG LPAREN STRING RPAREN	{$$=mk_action(	LOG_T, NUMBER_ST, 
439
+		| LOG_TOK LPAREN STRING RPAREN	{$$=mk_action(	LOG_T, NUMBER_ST, 
386 440
 													STRING_ST,(void*)4,$3);
387 441
 									}
388
-		| LOG LPAREN NUMBER COMMA STRING RPAREN	{$$=mk_action(	LOG_T,
442
+		| LOG_TOK LPAREN NUMBER COMMA STRING RPAREN	{$$=mk_action(	LOG_T,
389 443
 																NUMBER_ST, 
390 444
 																STRING_ST,
391 445
 																(void*)$3,
392 446
 																$5);
393 447
 												}
394
-		| LOG error { $$=0; yyerror("missing '(' or ')' ?"); }
395
-		| LOG LPAREN error RPAREN { $$=0; yyerror("bad log"
448
+		| LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
449
+		| LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
396 450
 									"argument"); }
397 451
 		| ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
398 452
 																STRING_ST, 
... ...
@@ -413,6 +467,24 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
413 467
 		| EXEC LPAREN STRING RPAREN	{ $$=mk_action(	EXEC_T, STRING_ST, 0,
414 468
 													$3, 0);
415 469
 									}
470
+		| SET_HOST LPAREN STRING RPAREN { $$=mk_action( SET_HOST_T, STRING_ST, 0, $3, 0); }
471
+		| SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
472
+		| SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
473
+		| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, STRING_ST, 0, $3, 0); }
474
+		| SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
475
+		| SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
476
+		| SET_PORT LPAREN STRING RPAREN { $$=mk_action( SET_PORT_T, STRING_ST, 0, $3, 0); }
477
+		| SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
478
+		| SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
479
+		| SET_USER LPAREN STRING RPAREN { $$=mk_action( SET_USER_T, STRING_ST, 0, $3, 0); }
480
+		| SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
481
+		| SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
482
+		| SET_USERPASS LPAREN STRING RPAREN { $$=mk_action( SET_USERPASS_T, STRING_ST, 0, $3, 0); }
483
+		| SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
484
+		| SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
485
+		| SET_URI LPAREN STRING RPAREN { $$=mk_action( SET_URI_T, STRING_ST, 0, $3, 0); }
486
+		| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
487
+		| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
416 488
 	;
417 489
 
418 490
 
... ...
@@ -423,7 +495,7 @@ extern int column;
423 495
 extern int startcolumn;
424 496
 void yyerror(char* s)
425 497
 {
426
-	fprintf(stderr, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
498
+	LOG(L_CRIT, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
427 499
 			column, s);
428 500
 	cfg_errors++;
429 501
 }
... ...
@@ -28,4 +28,6 @@
28 28
 #define ROUTE_MAX_REC_LEV 10 /* maximum number of recursive calls
29 29
 							   for route()*/
30 30
 
31
+#define MAX_URI_SIZE 1024	/* used when rewriting URIs */
32
+
31 33
 #endif
... ...
@@ -63,7 +63,7 @@ int check_address(unsigned long ip, char *name, int resolver)
63 63
 
64 64
 int forward_request( struct sip_msg* msg, struct proxy_l * p)
65 65
 {
66
-	unsigned int len, new_len, via_len, received_len;
66
+	unsigned int len, new_len, via_len, received_len, uri_len;
67 67
 	char line_buf[MAX_VIA_LINE_SIZE];
68 68
 	char received_buf[MAX_RECEIVED_SIZE];
69 69
 	char* new_buf;
... ...
@@ -96,15 +96,31 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
96 96
 	}
97 97
 	
98 98
 	new_len=len+via_len+received_len;
99
+	if (msg->new_uri){ 
100
+		uri_len=strlen(msg->new_uri); 
101
+		new_len=new_len-strlen(msg->first_line.u.request.uri)+uri_len;
102
+	}
99 103
 	new_buf=(char*)malloc(new_len+1);
100 104
 	if (new_buf==0){
101 105
 		LOG(L_ERR, "ERROR: forward_request: out of memory\n");
102 106
 		goto error;
103 107
 	}
104
-/* copy msg till first via */
108
+
105 109
 	offset=s_offset=0;
106
-	size=msg->via1.hdr-buf;
107
-	memcpy(new_buf, orig, size);
110
+	if (msg->new_uri){
111
+		/* copy message up to uri */
112
+		size=msg->first_line.u.request.uri-buf;
113
+		memcpy(new_buf, orig, size);
114
+		offset+=size;
115
+		s_offset+=size;
116
+		/* add our uri */
117
+		memcpy(new_buf+offset, msg->new_uri, uri_len);
118
+		offset+=uri_len;
119
+		s_offset+=strlen(msg->first_line.u.request.uri); /* skip original uri */
120
+	}
121
+/* copy msg till first via */
122
+	size=msg->via1.hdr-(buf+s_offset);
123
+	memcpy(new_buf+offset, orig+s_offset, size);
108 124
 	offset+=size;
109 125
 	s_offset+=size;
110 126
  /* add our via */
... ...
@@ -19,7 +19,7 @@ extern unsigned short port_no;
19 19
 extern char * names[];
20 20
 extern unsigned long addresses[];
21 21
 extern int addresses_no;
22
-extern int child_no;
22
+extern int children_no;
23 23
 extern int debug;
24 24
 extern int dont_fork;
25 25
 extern int log_stderr;
... ...
@@ -22,7 +22,7 @@
22 22
 
23 23
 
24 24
 static char id[]="@(#) $Id$";
25
-static char version[]="sip_router 0.5";
25
+static char version[]="sip_router 0.6";
26 26
 static char help_msg[]= "\
27 27
 Usage: sip_router -l address [-l address] [options]\n\
28 28
 Options:\n\
... ...
@@ -289,6 +289,25 @@ int main(int argc, char** argv)
289 289
 	
290 290
 	/* fill missing arguments with the default values*/
291 291
 	if (cfg_file==0) cfg_file=CFG_FILE;
292
+
293
+	/* load config file or die */
294
+	cfg_stream=fopen (cfg_file, "r");
295
+	if (cfg_stream==0){
296
+		fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
297
+				strerror(errno));
298
+		goto error;
299
+	}
300
+	
301
+	yyin=cfg_stream;
302
+	if ((yyparse()!=0)||(cfg_errors)){
303
+		fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
304
+		goto error;
305
+	}
306
+	
307
+	
308
+	print_rl();
309
+
310
+	/* fix parameters */
292 311
 	if (port_no<=0) port_no=SIP_PORT;
293 312
 	if (children_no<=0) children_no=CHILD_NO;
294 313
 	if (addresses_no==0) {
... ...
@@ -320,26 +339,6 @@ int main(int argc, char** argv)
320 339
 				inet_ntoa(*(struct in_addr*)&addresses[r]),
321 340
 				(unsigned short)port_no);
322 341
 	}
323
-	
324
-	
325
-
326
-	/* load config file or die */
327
-	cfg_stream=fopen (cfg_file, "r");
328
-	if (cfg_stream==0){
329
-		fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
330
-				strerror(errno));
331
-		goto error;
332
-	}
333
-	
334
-	yyin=cfg_stream;
335
-	if ((yyparse()!=0)||(cfg_errors)){
336
-		fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
337
-		goto error;
338
-	}
339
-	
340
-	
341
-	print_rl();
342
-
343 342
 
344 343
 	/* init_daemon? */
345 344
 	if (!dont_fork){
... ...
@@ -10,6 +10,7 @@
10 10
 
11 11
 #include "msg_parser.h"
12 12
 #include "parser_f.h"
13
+#include "error.h"
13 14
 #include "dprint.h"
14 15
 
15 16
 
... ...
@@ -118,10 +119,15 @@ error1:
118 119
 /* returns integer field name type */
119 120
 int field_name(char *s)
120 121
 {
121
-	if ((strcmp(s, "Via")==0 )||(strcmp(s,"v")==0))
122
+	int l;
123
+	l=strlen(s);
124
+	if (l<1) return HDR_OTHER;
125
+	else if ((l==1) && ((*s=='v')||(*s=='V')))
126
+		return HDR_VIA;
127
+	else if (strcasecmp(s, "Via")==0)
122 128
 		return  HDR_VIA;
123
-	if ((strcmp(s, "To")==0)||(strcmp(s,"t")==0))
124
-		return HDR_TO;
129
+/*	if ((strcmp(s, "To")==0)||(strcmp(s,"t")==0))
130
+		return HDR_TO;*/
125 131
 	return HDR_OTHER;
126 132
 }
127 133
 
... ...
@@ -137,7 +143,7 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
137 143
 	   (CRLF in the field body must be removed)
138 144
 	*/
139 145
 
140
-	char* tmp;
146
+	char* tmp, *tmp2;
141 147
 	char* nl;
142 148
 	char* body;
143 149
 	int offset;
... ...
@@ -156,11 +162,25 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
156 162
 	
157 163
 	tmp=eat_token2(buffer, len, ':');
158 164
 	if ((tmp==buffer) || (tmp-buffer==len) ||
159
-		(is_empty(buffer, tmp-buffer-1))|| (*tmp!=':')){
165
+		(is_empty(buffer, tmp-buffer))|| (*tmp!=':')){
160 166
 		hdr_f->type=HDR_ERROR;
161 167
 		goto error;
162 168
 	}
163 169
 	*tmp=0;
170
+	/* take care of possible spaces (e.g: "Via  :") */
171
+	tmp2=eat_token(buffer, tmp-buffer);
172
+	/* in the worst case tmp2=buffer+tmp-buffer=tmp */
173
+	*tmp2=0;
174
+	if (tmp2<tmp){
175
+		tmp2++;
176
+		/* catch things like: "Via foo bar:" */
177
+		tmp2=eat_space(tmp2, tmp-tmp2);
178
+		if (tmp2!=tmp){
179
+			hdr_f->type=HDR_ERROR;
180
+			goto error;
181
+		}
182
+	}
183
+
164 184
 	hdr_f->type=field_name(buffer);
165 185
 	body= ++tmp;
166 186
 	hdr_f->name=buffer;
... ...
@@ -210,6 +230,165 @@ char* parse_hostport(char* buf, char** host, short int* port)
210 230
 
211 231
 
212 232
 
233
+/* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
234
+   len= len of uri
235
+returns: fills uri & returns <0 on error or 0 if ok */
236
+int parse_uri(char *buf, int len, struct sip_uri* uri)
237
+{
238
+	char* next, *end;
239
+	char *user, *passwd, *host, *port, *params, *headers;
240
+	int host_len, port_len, params_len, headers_len;
241
+	int ret;
242
+	
243
+
244
+	ret=0;
245
+	end=buf+len;
246
+	memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
247
+	/* look for "sip:"*/;
248
+	next=memchr(buf, ':',  len);
249
+	if ((next==0)||(strncmp(buf,"sip",next-buf)!=0)){
250
+		LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
251
+		ret=E_UNSPEC;
252
+		goto error;
253
+	}
254
+	buf=next+1; /* next char after ':' */
255
+	if (buf>end){
256
+		LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
257
+		ret=E_UNSPEC;
258
+		goto error;
259
+	}
260
+	/*look for '@' */
261
+	next=memchr(buf,'@', end-buf);
262
+	if (next==0){
263
+		/* no '@' found, => no userinfo */
264
+		uri->user=0;
265
+		uri->passwd=0;
266
+		host=buf;
267
+	}else{
268
+		/* found it */
269
+		user=buf;
270
+		/* try to find passwd */
271
+		passwd=memchr(user,':', next-user);
272
+		if (passwd==0){
273
+			/* no ':' found => no password */
274
+			uri->passwd=0;
275
+			uri->user=(char*)malloc(next-user+1);
276
+			if (uri->user==0){
277
+				LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
278
+				ret=E_OUT_OF_MEM;
279
+				goto error;
280
+			}
281
+			memcpy(uri->user,user, next-user);
282
+			uri->user[next-user]=0; /* null terminate it, usefull for easy printing*/
283
+		}else{
284
+			uri->user=(char*)malloc(passwd-user+1);
285
+			if (uri->user==0){
286
+				LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
287
+				ret=E_OUT_OF_MEM;
288
+				goto error;
289
+			}
290
+			memcpy(uri->user,user, passwd-user);
291
+			uri->user[passwd-user]=0;
292
+			passwd++; /*skip ':' */
293
+			uri->passwd=(char*)malloc(next-passwd+1);
294
+			if (uri->passwd==0){
295
+				LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
296
+				ret=E_OUT_OF_MEM;
297
+				goto error;
298
+			}
299
+			memcpy(uri->passwd,passwd, next-passwd);
300
+			uri->passwd[next-passwd]=0;
301
+		}
302
+		host=next+1; /* skip '@' */
303
+	}
304
+	/* try to find the rest */
305
+	if(host>=end){
306
+		LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
307
+		ret=E_UNSPEC;
308
+		goto error;
309
+	}
310
+	headers=memchr(host,'?',end-host);
311
+	params=memchr(host,';',end-host);
312
+	port=memchr(host,':',end-host);
313
+	host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:end-host;
314
+	/* get host */
315
+	uri->host=malloc(host_len+1);
316
+	if (uri->host==0){
317
+		LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
318
+		ret=E_OUT_OF_MEM;
319
+		goto error;
320
+	}
321
+	memcpy(uri->host,host, host_len);
322
+	uri->host[host_len]=0;
323
+	/* get port*/
324
+	if ((port)&&(port+1<end)){
325
+		port++;
326
+		if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
327
+			/* error -> invalid uri we found ';' or '?' before ':' */
328
+			LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
329
+			ret=E_UNSPEC;
330
+			goto error;
331
+		}
332
+		port_len=(params)?params-port:(headers)?headers-port:end-port;
333
+		uri->port=malloc(port_len+1);
334
+		if (uri->port==0){
335
+			LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
336
+			ret=E_OUT_OF_MEM;
337
+			goto error;
338
+		}
339
+		memcpy(uri->port, port, port_len);
340
+		uri->port[port_len]=0;
341
+	}else uri->port=0;
342
+	/* get params */
343
+	if ((params)&&(params+1<end)){
344
+		params++;
345
+		if ((headers) && (headers<params)){
346
+			/* error -> invalid uri we found '?' or '?' before ';' */
347
+			LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
348
+			ret=E_UNSPEC;
349
+			goto error;
350
+		}
351
+		params_len=(headers)?headers-params:end-params;
352
+		uri->params=malloc(params_len+1);
353
+		if (uri->params==0){
354
+			LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
355
+			ret=E_OUT_OF_MEM;
356
+			goto error;
357
+		}
358
+		memcpy(uri->params, params, params_len);
359
+		uri->params[params_len]=0;
360
+	}else uri->params=0;
361
+	/*get headers */
362
+	if ((headers)&&(headers+1<end)){
363
+		headers++;
364
+		headers_len=end-headers;
365
+		uri->headers=malloc(headers_len+1);
366
+		if(uri->headers==0){
367
+			LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
368
+			ret=E_OUT_OF_MEM;
369
+			goto error;
370
+		}
371
+		memcpy(uri->headers, headers, headers_len);
372
+		uri->headers[headers_len]=0;
373
+	}else uri->headers=0;
374
+	
375
+	return ret;
376
+error:
377
+	return ret;
378
+}
379
+
380
+
381
+			
382
+
383
+			
384
+			
385
+	
386
+		
387
+	
388
+	
389
+
390
+
391
+
213 392
 /* parses a via body, returns next via (for compact vias) & fills vb,
214 393
  * the buffer should be null terminated! */
215 394
 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb)
... ...
@@ -434,9 +613,11 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
434 613
 							goto skip;
435 614
 						}else{
436 615
 						/*  add 1 (we don't see the trailing lf which
437
-						 *  was zeroed by get_hfr_field */
616
+						 *  was zeroed by get_hfr_field) */
438 617
 							vb1.size+=1;
439 618
 						}
619
+						if (fl.type!=SIP_REPLY) goto skip; /* we are interested in the 2nd via 
620
+															   only in replies */
440 621
 				}else if (second_via==0){
441 622
 							second_via=hf.body;
442 623
 							vb2.hdr=hf.name;
... ...
@@ -72,10 +72,23 @@ struct sip_msg{
72 72
 				   via, etc. point into it */
73 73
 				   
74 74
 	unsigned int len; /* message len (orig) */
75
+
76
+	/* modifications */
77
+	char* new_uri; /* changed first line uri*/
75 78
 	
76 79
 };
77 80
 
78 81
 
82
+struct sip_uri{
83
+	char* user;
84
+	char* passwd;
85
+	char* host;
86
+	char* port;
87
+	char* params;
88
+	char* headers;
89
+};
90
+
91
+
79 92
 
80 93
 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
81 94
 char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f);
... ...
@@ -83,6 +96,7 @@ int field_name(char *s);
83 96
 char* parse_hostport(char* buf, char** host, short int* port);
84 97
 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb);
85 98
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
99
+int parse_uri(char *buf, int len, struct sip_uri* uri);
86 100
 
87 101
 
88 102
 
... ...
@@ -18,6 +18,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
18 18
 	struct sip_msg msg;
19 19
 	struct route_elem *re;
20 20
 
21
+	memset(&msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
21 22
 	/* fill in msg */
22 23
 	msg.buf=buf;
23 24
 	msg.len=len;
... ...
@@ -407,16 +407,16 @@ void print_rl()
407 407
 
408 408
 	for(j=0; j<RT_NO; j++){
409 409
 		if (rlist[j]==0){
410
-			if (j==0) printf("WARNING: the main routing table is empty\n");
410
+			if (j==0) DBG("WARNING: the main routing table is empty\n");
411 411
 			continue;
412 412
 		}
413
-		printf("routing table %d:\n",j);
413
+		DBG("routing table %d:\n",j);
414 414
 		for (t=rlist[j],i=0; t; i++, t=t->next){
415
-			printf("%2d.condition: ",i);
415
+			DBG("%2d.condition: ",i);
416 416
 			print_expr(t->condition);
417
-			printf("\n  -> ");
417
+			DBG("\n  -> ");
418 418
 			print_action(t->actions);
419
-			printf("\n    Statistics: tx=%d, errors=%d, tx_bytes=%d\n",
419
+			DBG("\n    Statistics: tx=%d, errors=%d, tx_bytes=%d\n",
420 420
 					t->tx, t->errors, t->tx_bytes);
421 421
 		}
422 422
 	}
... ...
@@ -12,6 +12,8 @@
12 12
 #include <sys/types.h>
13 13
 #include <netinet/in.h>
14 14
 
15
+#include "dprint.h"
16
+
15 17
 struct expr* mk_exp(int op, struct expr* left, struct expr* right)
16 18
 {
17 19
 	struct expr * e;
... ...
@@ -23,7 +25,7 @@ struct expr* mk_exp(int op, struct expr* left, struct expr* right)
23 25
 	e->r.expr=right;
24 26
 	return e;
25 27
 error:
26
-	fprintf(stderr, "ERROR: mk_exp: memory allocation failure\n");
28
+	LOG(L_CRIT, "ERROR: mk_exp: memory allocation failure\n");
27 29
 	return 0;
28 30
 }
29 31
 
... ...
@@ -40,7 +42,7 @@ struct expr* mk_elem(int op, int subtype, int operand, void* param)
40 42
 	e->r.param=param;
41 43
 	return e;
42 44
 error:
43
-	fprintf(stderr, "ERROR: mk_elem: memory allocation failure\n");
45
+	LOG(L_CRIT, "ERROR: mk_elem: memory allocation failure\n");
44 46
 	return 0;
45 47
 }
46 48
 
... ...
@@ -60,7 +62,7 @@ struct action* mk_action(int type, int p1_type, int p2_type, void* p1, void* p2)
60 62
 	return a;
61 63
 	
62 64
 error:
63
-	fprintf(stderr, "ERROR: mk_action: memory allocation failure\n");
65
+	LOG(L_CRIT, "ERROR: mk_action: memory allocation failure\n");
64 66
 	return 0;
65 67
 
66 68
 }
... ...
@@ -89,7 +91,7 @@ struct net* mk_net(unsigned long ip, unsigned long mask)
89 91
 	n->mask=mask;
90 92
 	return n;
91 93
 error:
92
-	fprintf(stderr, "ERROR: mk_net_mask: memory allocation failure\n");
94
+	LOG(L_CRIT, "ERROR: mk_net_mask: memory allocation failure\n");
93 95
 	return 0;
94 96
 }
95 97
 
... ...
@@ -98,7 +100,7 @@ error:
98 100
 
99 101
 void print_ip(unsigned ip)
100 102
 {
101
-	printf("%d.%d.%d.%d", ((unsigned char*)&ip)[0],
103
+	DBG("%d.%d.%d.%d", ((unsigned char*)&ip)[0],
102 104
 						  ((unsigned char*)&ip)[1],
103 105
 						  ((unsigned char*)&ip)[2],
104 106
 						  ((unsigned char*)&ip)[3]);
... ...
@@ -108,10 +110,10 @@ void print_ip(unsigned ip)
108 110
 void print_net(struct net* net)
109 111
 {
110 112
 	if (net==0){
111
-		fprintf(stderr, "ERROR: print net: null pointer\n");
113
+		LOG(L_WARN, "ERROR: print net: null pointer\n");
112 114
 		return;
113 115
 	}
114
-	print_ip(net->ip); printf("/"); print_ip(net->mask);
116
+	print_ip(net->ip); DBG("/"); print_ip(net->mask);
115 117
 }
116 118
 
117 119
 
... ...
@@ -119,42 +121,42 @@ void print_net(struct net* net)
119 121
 void print_expr(struct expr* exp)
120 122
 {
121 123
 	if (exp==0){
122
-		fprintf(stderr, "ERROR: print_expr: null expression!\n");
124
+		LOG(L_CRIT, "ERROR: print_expr: null expression!\n");
123 125
 		return;
124 126
 	}
125 127
 	if (exp->type==ELEM_T){
126 128
 		switch(exp->l.operand){
127 129
 			case METHOD_O:
128
-				printf("method");
130
+				DBG("method");
129 131
 				break;
130 132
 			case URI_O:
131
-				printf("uri");
133
+				DBG("uri");
132 134
 				break;
133 135
 			case SRCIP_O:
134
-				printf("srcip");
136
+				DBG("srcip");
135 137
 				break;
136 138
 			case DSTIP_O:
137
-				printf("dstip");
139
+				DBG("dstip");
138 140
 				break;
139 141
 			default:
140
-				printf("UNKNOWN");
142
+				DBG("UNKNOWN");
141 143
 		}
142 144
 		switch(exp->op){
143 145
 			case EQUAL_OP:
144
-				printf("==");
146
+				DBG("==");
145 147
 				break;
146 148
 			case MATCH_OP:
147
-				printf("~=");
149
+				DBG("=~");
148 150
 				break;
149 151
 			default:
150
-				printf("<UNKNOWN>");
152
+				DBG("<UNKNOWN>");
151 153
 		}
152 154
 		switch(exp->subtype){
153 155
 			case NOSUBTYPE: 
154
-					printf("N/A");
156
+					DBG("N/A");
155 157
 					break;
156 158
 			case STRING_ST:
157
-					printf("\"%s\"", (char*)exp->r.param);
159
+					DBG("\"%s\"", (char*)exp->r.param);
158 160
 					break;
159 161
 			case NET_ST:
160 162
 					print_net((struct net*)exp->r.param);
... ...
@@ -163,35 +165,35 @@ void print_expr(struct expr* exp)
163 165
 					print_ip(exp->r.intval);
164 166
 					break;
165 167
 			default:
166
-					printf("type<%d>", exp->subtype);
168
+					DBG("type<%d>", exp->subtype);
167 169
 		}
168 170
 	}else if (exp->type==EXP_T){
169 171
 		switch(exp->op){
170 172
 			case AND_OP:
171
-					printf("AND( ");
173
+					DBG("AND( ");
172 174
 					print_expr(exp->l.expr);
173
-					printf(", ");
175
+					DBG(", ");
174 176
 					print_expr(exp->r.expr);
175
-					printf(" )");
177
+					DBG(" )");
176 178
 					break;
177 179
 			case OR_OP:
178
-					printf("OR( ");
180
+					DBG("OR( ");
179 181
 					print_expr(exp->l.expr);
180
-					printf(", ");
182
+					DBG(", ");
181 183
 					print_expr(exp->r.expr);
182
-					printf(" )");
184
+					DBG(" )");
183 185
 					break;
184 186
 			case NOT_OP:	
185
-					printf("NOT( ");
187
+					DBG("NOT( ");
186 188
 					print_expr(exp->l.expr);
187
-					printf(" )");
189
+					DBG(" )");
188 190
 					break;
189 191
 			default:
190
-					printf("UNKNOWN_EXP ");
192
+					DBG("UNKNOWN_EXP ");
191 193
 		}
192 194
 					
193 195
 	}else{
194
-		printf("ERROR:print_expr: unknown type\n");
196
+		DBG("ERROR:print_expr: unknown type\n");
195 197
 	}
196 198
 }
197 199
 					
... ...
@@ -204,55 +206,73 @@ void print_action(struct action* a)
204 206
 	for(t=a; t!=0;t=t->next){
205 207
 		switch(t->type){
206 208
 			case FORWARD_T:
207
-					printf("forward(");
209
+					DBG("forward(");
208 210
 					break;
209 211
 			case SEND_T:
210
-					printf("send(");
212
+					DBG("send(");
211 213
 					break;
212 214
 			case DROP_T:
213
-					printf("drop(");
215
+					DBG("drop(");
214 216
 					break;
215 217
 			case LOG_T:
216
-					printf("log(");
218
+					DBG("log(");
217 219
 					break;
218 220
 			case ERROR_T:
219
-					printf("error(");
221
+					DBG("error(");
220 222
 					break;
221 223
 			case ROUTE_T:
222
-					printf("route(");
224
+					DBG("route(");
223 225
 					break;
224 226
 			case EXEC_T:
225
-					printf("exec(");
227
+					DBG("exec(");
228
+					break;
229
+			case SET_HOST_T:
230
+					DBG("sethost(");
231
+					break;
232
+			case SET_HOSTPORT_T:
233
+					DBG("sethostport(");
234
+					break;
235
+			case SET_USER_T:
236
+					DBG("setuser(");
237
+					break;
238
+			case SET_USERPASS_T:
239
+					DBG("setuserpass(");
240
+					break;
241
+			case SET_PORT_T:
242
+					DBG("setport(");
243
+					break;
244
+			case SET_URI_T:
245
+					DBG("seturi(");
226 246
 					break;
227 247
 			default:
228
-					printf("UNKNOWN(");
248
+					DBG("UNKNOWN(");
229 249
 		}
230 250
 		switch(t->p1_type){
231 251
 			case STRING_ST:
232
-					printf("\"%s\"", t->p1.string);
252
+					DBG("\"%s\"", t->p1.string);
233 253
 					break;
234 254
 			case NUMBER_ST:
235
-					printf("%d",t->p1.number);
255
+					DBG("%d",t->p1.number);
236 256
 					break;
237 257
 			case IP_ST:
238 258
 					print_ip(t->p1.number);
239 259
 					break;
240 260
 			default:
241
-					printf("type<%d>", t->p1_type);
261
+					DBG("type<%d>", t->p1_type);
242 262
 		}
243 263
 		switch(t->p2_type){
244 264
 			case NOSUBTYPE:
245 265
 					break;
246 266
 			case STRING_ST:
247
-					printf(", \"%s\"", t->p2.string);
267
+					DBG(", \"%s\"", t->p2.string);
248 268
 					break;
249 269
 			case NUMBER_ST:
250
-					printf(", %d",t->p2.number);
270
+					DBG(", %d",t->p2.number);
251 271
 					break;
252 272
 			default:
253
-					printf(", type<%d>", t->p2_type);
273
+					DBG(", type<%d>", t->p2_type);
254 274
 		}
255
-		printf("); ");
275
+		DBG("); ");
256 276
 	}
257 277
 }
258 278
 			
... ...
@@ -11,13 +11,14 @@ enum { AND_OP=1, OR_OP, NOT_OP };
11 11
 enum { EQUAL_OP=10, MATCH_OP };
12 12
 enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O };
13 13
 
14
-enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T};
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};
15 16
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST };
16 17
 
17 18
 	
18 19
 struct expr{
19 20
 	int type; /* exp, exp_elem */
20
-	int op; /* and, or, not | ==,  ~= */
21
+	int op; /* and, or, not | ==,  =~ */
21 22
 	int  subtype;
22 23
 	union {
23 24
 		struct expr* expr;
... ...
@@ -1,5 +1,5 @@
1
-INVITE sip:x@y.z SIP/2.0/UDP
2
-Via  : SIP  /   2.0
1
+INVITE sip:x@y.z SIP/2.0
2
+Via : SIP  /   2.0
3 3
  /UDP
4 4
     193.175.133.193
5 5
 
... ...
@@ -1,4 +1,4 @@
1
-INVITE sip:andrei@localhost SIP/2.0/UDP
1
+INVITE sip:andrei@localhost:5061;a=b?c=d SIP/2.0
2 2
 Via: SIP/2.0/UDP localhost
3 3
 
4 4