... | ... |
@@ -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 |
} |
... | ... |
@@ -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 */ |
... | ... |
@@ -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 |
|
... | ... |
@@ -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; |