- added rewrite support (sethost setuser, setuserpass, sethost, setport, sethostport)
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 25 Sep 2001 23:06:39 +0000 (23:06 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 25 Sep 2001 23:06:39 +0000 (23:06 +0000)
- 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

15 files changed:
action.c
cfg.lex
cfg.y
config.h
forward.c
globals.h
main.c
msg_parser.c
msg_parser.h
receive.c
route.c
route_struct.c
route_struct.h
test/bad_via1.sip
test/req1.sip

index 39324e4..c56039b 100644 (file)
--- a/action.c
+++ b/action.c
@@ -12,6 +12,7 @@
 #include "forward.h"
 #include "udp_server.h"
 #include "route.h"
+#include "msg_parser.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 
 
-/* ret= 0 if action -> end of lis t(e.g DROP), >0
-   and >0 on error */
+/* ret= 0! if action -> end of list(e.g DROP), 
+      > 0 to continue processing next actions
+   and <0 on error */
 int do_action(struct action* a, struct sip_msg* msg)
 {
        int ret;
        struct sockaddr_in* to;
        struct proxy_l* p;
        struct route_elem* re;
+       char* tmp;
+       char *new_uri, *end, *crt;
+       int len;
+       struct sip_uri uri;
 
        ret=E_BUG;
        switch (a->type){
@@ -139,10 +145,119 @@ int do_action(struct action* a, struct sip_msg* msg)
                        }
                        ret=1;
                        break;
+               case SET_HOST_T:
+               case SET_HOSTPORT_T:
+               case SET_USER_T:
+               case SET_USERPASS_T:
+               case SET_PORT_T:
+               case SET_URI_T:
+                               if (a->p1_type!=STRING_ST){
+                                       LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
+                                                       a->p1_type);
+                                       ret=E_BUG;
+                                       break;
+                               }
+                               if (a->type==SET_URI_T){
+                                       if (msg->new_uri) free(msg->new_uri);
+                                       len=strlen(a->p1.string);
+                                       msg->new_uri=malloc(len+1);
+                                       if (msg->new_uri==0){
+                                               LOG(L_ERR, "ERROR: do_action: memory allocation failure\n");
+                                               ret=E_OUT_OF_MEM;
+                                               break;
+                                       }
+                                       memcpy(msg->new_uri, a->p1.string, len);
+                                       msg->new_uri[len]=0;
+                                       ret=1;
+                                       break;
+                               }
+
+                               if (msg->new_uri) tmp=msg->new_uri;
+                               else tmp=msg->first_line.u.request.uri;
+                               if (parse_uri(tmp, strlen(tmp), &uri)<0){
+                                       LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping packet\n", tmp);
+                                       ret=E_UNSPEC;
+                                       break;
+                               }
+                               
+                               new_uri=malloc(MAX_URI_SIZE);
+                               if (new_uri==0){
+                                       LOG(L_ERR, "ERROR: do_action: memory allocation failure\n");
+                                       ret=E_OUT_OF_MEM;
+                                       break;
+                               }
+                               end=new_uri+MAX_URI_SIZE;
+                               crt=new_uri;
+                               /* begin copying */
+                               len=strlen("sip:"); if(crt+len>end) goto error_uri;
+                               memcpy(crt,"sip:",len);crt+=len;
+                               /* user */
+                               if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) tmp=a->p1.string;
+                               else tmp=uri.user;
+                               if (tmp){
+                                       len=strlen(tmp); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,tmp,len);crt+=len;
+                               }
+                               if (a->type==SET_USERPASS_T) tmp=0;
+                               else tmp=uri.passwd;
+                               /* passwd */
+                               if (tmp){
+                                       len=strlen(":"); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,":",len);crt+=len;
+                                       len=strlen(tmp); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,tmp,len);crt+=len;
+                               }
+                               /* host */
+                               len=strlen("@"); if(crt+len>end) goto error_uri;
+                               memcpy(crt,"@",len);crt+=len;
+                               if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) tmp=a->p1.string;
+                               else tmp=uri.host;
+                               if (tmp){
+                                       len=strlen(tmp); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,tmp,len);crt+=len;
+                               }
+                               /* port */
+                               if (a->type==SET_HOSTPORT_T) tmp=0;
+                               else if (a->type==SET_PORT_T) tmp=a->p1.string;
+                               else tmp=uri.port;
+                               if (tmp){
+                                       len=strlen(":"); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,":",len);crt+=len;
+                                       len=strlen(tmp); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,tmp,len);crt+=len;
+                               }
+                               /* params */
+                               tmp=uri.params;
+                               if (tmp){
+                                       len=strlen(";"); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,";",len);crt+=len;
+                                       len=strlen(tmp); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,tmp,len);crt+=len;
+                               }
+                               /* headers */
+                               tmp=uri.headers;
+                               if (tmp){
+                                       len=strlen("?"); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,"?",len);crt+=len;
+                                       len=strlen(tmp); if(crt+len>end) goto error_uri;
+                                       memcpy(crt,tmp,len);crt+=len;
+                               }
+                               *crt=0; /* null terminate the thing */
+                               /* copy it to the msg */
+                               if (msg->new_uri) free(msg->new_uri);
+                               msg->new_uri=new_uri;
+                               ret=1;
+                               break;
+
                default:
                        LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
        }
        return ret;
+       
+error_uri:
+       LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
+       if (new_uri) free(new_uri);
+       return E_UNSPEC;
 }
 
 
diff --git a/cfg.lex b/cfg.lex
index 086af11..49f395f 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -7,6 +7,7 @@
 
 %{
        #include "cfg.tab.h"
+       #include "dprint.h"
        #include <string.h>
 
        /* states */
@@ -40,6 +41,14 @@ LOG          log
 ERROR  error
 ROUTE  route
 EXEC   exec
+SET_HOST               "rewritehost"|"sethost"|"seth"
+SET_HOSTPORT   "rewritehostport"|"sethostport"|"sethp"
+SET_USER               "rewriteuser"|"setuser"|"setu"
+SET_USERPASS   "rewriteuserpass"|"setuserpass"|"setup"
+SET_PORT               "rewriteport"|"setport"|"setp"
+SET_URI                        "rewriteuri"|"seturi"
+
+
 /* condition keywords */
 METHOD method
 URI            uri
@@ -48,7 +57,7 @@ DSTIP dst_ip
 /* operators */
 EQUAL  =
 EQUAL_T        ==
-MATCH  ~=
+MATCH  =~
 NOT            !|"not"
 AND            "and"|"&&"|"&"
 OR             "or"|"||"|"|"
@@ -60,6 +69,9 @@ LOGSTDERROR   log_stderror
 LISTEN         listen
 DNS             dns
 REV_DNS         rev_dns
+PORT   port
+CHILDREN children
+CHECK_VIA      check_via
 
 /* values */
 YES                    "yes"|"true"|"on"|"enable"
@@ -100,10 +112,16 @@ EAT_ABLE  [\ \t\b\r]
 <INITIAL>{FORWARD}     {count(); yylval.strval=yytext; return FORWARD; }
 <INITIAL>{DROP}        { count(); yylval.strval=yytext; return DROP; }
 <INITIAL>{SEND}        { count(); yylval.strval=yytext; return SEND; }
-<INITIAL>{LOG} { count(); yylval.strval=yytext; return LOG; }
+<INITIAL>{LOG} { count(); yylval.strval=yytext; return LOG_TOK; }
 <INITIAL>{ERROR}       { count(); yylval.strval=yytext; return ERROR; }
 <INITIAL>{ROUTE}       { count(); yylval.strval=yytext; return ROUTE; }
 <INITIAL>{EXEC}        { count(); yylval.strval=yytext; return EXEC; }
+<INITIAL>{SET_HOST}    { count(); yylval.strval=yytext; return SET_HOST; }
+<INITIAL>{SET_HOSTPORT}        { count(); yylval.strval=yytext; return SET_HOSTPORT; }
+<INITIAL>{SET_USER}    { count(); yylval.strval=yytext; return SET_USER; }
+<INITIAL>{SET_USERPASS}        { count(); yylval.strval=yytext; return SET_USERPASS; }
+<INITIAL>{SET_PORT}    { count(); yylval.strval=yytext; return SET_PORT; }
+<INITIAL>{SET_URI}     { count(); yylval.strval=yytext; return SET_URI; }
 
 <INITIAL>{METHOD}      { count(); yylval.strval=yytext; return METHOD; }
 <INITIAL>{URI} { count(); yylval.strval=yytext; return URI; }
@@ -116,6 +134,9 @@ EAT_ABLE    [\ \t\b\r]
 <INITIAL>{LISTEN}      { count(); yylval.strval=yytext; return LISTEN; }
 <INITIAL>{DNS} { count(); yylval.strval=yytext; return DNS; }
 <INITIAL>{REV_DNS}     { count(); yylval.strval=yytext; return REV_DNS; }
+<INITIAL>{PORT}        { count(); yylval.strval=yytext; return PORT; }
+<INITIAL>{CHILDREN}    { count(); yylval.strval=yytext; return CHILDREN; }
+<INITIAL>{CHECK_VIA}   { count(); yylval.strval=yytext; return CHECK_VIA; }
 
 <INITIAL>{EQUAL}       { count(); return EQUAL; }
 <INITIAL>{EQUAL_T}     { count(); return EQUAL_T; }
@@ -150,17 +171,11 @@ EAT_ABLE  [\ \t\b\r]
 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
                                                yytext[yyleng-1]=0; yyleng--;
                                                addstr(yytext, &str);
-                                               if (str){
-                                                       printf("Found string1 <%s>\n", str);
-                                               }else{
-                                                       printf("WARNING: empty string\n");
-                                               }
                                                yylval.strval=str; str=0;
                                                return STRING;
                                        }
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
                                                yytext[yyleng-1]=0; yyleng--;
-                                               printf("Found string1 <%s>\n", yytext);
                                                addstr(yytext, &str);
                                                yylval.strval=str;
                                                str=0;
@@ -196,14 +211,17 @@ EAT_ABLE  [\ \t\b\r]
 <<EOF>>                                                        {
                                                                        switch(state){
                                                                                case STRING_S: 
-                                                                                       printf("Unexpected EOF: closed string\n");
+                                                                                       LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
+                                                                                                               " unclosed string\n");
                                                                                        if (str) {free(str); str=0;}
                                                                                        break;
                                                                                case COMMENT_S:
-                                                                                       printf("Unexpected EOF:%d comments open\n", comment_nest);
+                                                                                       LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
+                                                                                                               " %d comments open\n", comment_nest);
                                                                                        break;
                                                                                case COMMENT_LN_S:
-                                                                                       printf("Unexpected EOF: comment line open\n");
+                                                                                       LOG(L_CRIT, "ERROR: unexpected EOF:"
+                                                                                                               "comment line open\n");
                                                                                        break;
                                                                        }
                                                                        return 0;
@@ -231,7 +249,7 @@ static char* addstr(char * src, char ** dest)
        }
        return *dest;
 error:
-       fprintf(stderr, "lex:addstr: memory allocation error\n");
+       LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
        return 0;
 }
 
diff --git a/cfg.y b/cfg.y
index 89e130e..9bfa75a 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -8,11 +8,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include "route_struct.h"
 #include "globals.h"
 #include "route.h"
+#include "dprint.h"
 
 void yyerror(char* s);
+char* tmp;
 
 %}
 
@@ -33,10 +38,16 @@ void yyerror(char* s);
 %token FORWARD
 %token SEND
 %token DROP
-%token LOG
+%token LOG_TOK
 %token ERROR
 %token ROUTE
 %token EXEC
+%token SET_HOST
+%token SET_HOSTPORT
+%token SET_USER
+%token SET_USERPASS
+%token SET_PORT
+%token SET_URI
 
 %token METHOD
 %token URI
@@ -50,6 +61,10 @@ void yyerror(char* s);
 %token LISTEN
 %token DNS
 %token REV_DNS
+%token PORT
+%token CHILDREN
+%token CHECK_VIA
+
 
 
 /* operators */
@@ -101,24 +116,70 @@ statements:       statements statement {}
                | statements error { yyerror(""); YYABORT;}
        ;
 
-statement:     assign_stm CR
-               | route_stm CR
+statement:     assign_stm 
+               | route_stm 
                | CR    /* null statement*/
        ;
 
-assign_stm:    DEBUG EQUAL NUMBER 
+assign_stm:    DEBUG EQUAL NUMBER { debug=$3; }
                | DEBUG EQUAL error  { yyerror("number  expected"); }
-               | FORK  EQUAL NUMBER
+               | FORK  EQUAL NUMBER { dont_fork= ! $3; }
                | FORK  EQUAL error  { yyerror("boolean value expected"); }
-               | LOGSTDERROR EQUAL NUMBER 
+               | LOGSTDERROR EQUAL NUMBER { log_stderr=$3; }
                | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
-               | DNS EQUAL NUMBER
+               | DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
                | DNS EQUAL error { yyerror("boolean value expected"); }
-               | REV_DNS EQUAL NUMBER 
+               | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
                | REV_DNS EQUAL error { yyerror("boolean value expected"); }
-               | LISTEN EQUAL ipv4 
-               | LISTEN EQUAL ID 
-               | LISTEN EQUAL STRING
+               | PORT EQUAL NUMBER   { port_no=$3; }
+               | PORT EQUAL error    { yyerror("number expected"); } 
+               | CHILDREN EQUAL NUMBER { children_no=$3; }
+               | CHILDREN EQUAL error { yyerror("number expected"); } 
+               | CHECK_VIA EQUAL NUMBER { check_via=$3; }
+               | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
+               | LISTEN EQUAL ipv4  {
+                                                               if (addresses_no < MAX_LISTEN){
+                                                                       tmp=inet_ntoa(*(struct in_addr*)&$3);
+                                                                       names[addresses_no]=(char*)malloc(strlen(tmp)+1);
+                                                                       if (names[addresses_no]==0){
+                                                                               LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
+                                                                       }else{
+                                                                               strncpy(names[addresses_no], tmp, strlen(tmp)+1);
+                                                                               addresses_no++;
+                                                                       }
+                                                               }else{
+                                                                       LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses"
+                                                                                               "(max. %d).\n", MAX_LISTEN);
+                                                               }
+                                                         }
+               | LISTEN EQUAL ID        {
+                                                               if (addresses_no < MAX_LISTEN){
+                                                                       names[addresses_no]=(char*)malloc(strlen($3)+1);
+                                                                       if (names[addresses_no]==0){
+                                                                               LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
+                                                                       }else{
+                                                                               strncpy(names[addresses_no], $3, strlen($3)+1);
+                                                                               addresses_no++;
+                                                                       }
+                                                               }else{
+                                                                       LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses"
+                                                                                               "(max. %d).\n", MAX_LISTEN);
+                                                               }
+                                                         }
+               | LISTEN EQUAL STRING {
+                                                               if (addresses_no < MAX_LISTEN){
+                                                                       names[addresses_no]=(char*)malloc(strlen($3)+1);
+                                                                       if (names[addresses_no]==0){
+                                                                               LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
+                                                                       }else{
+                                                                               strncpy(names[addresses_no], $3, strlen($3)+1);
+                                                                               addresses_no++;
+                                                                       }
+                                                               }else{
+                                                                       LOG(L_CRIT, "ERROR: cfg. parser: too many listen addresses"
+                                                                                               "(max. %d).\n", MAX_LISTEN);
+                                                               }
+                                                         }
                | LISTEN EQUAL  error { yyerror("ip address or hostname"
                                                "expected"); }
                | error EQUAL { yyerror("unknown config variable"); }
@@ -153,26 +214,19 @@ route_stm:        ROUTE LBRACE rules RBRACE { push($3, &rlist[DEFAULT_RT]); }
                | ROUTE error { yyerror("invalid  route  statement"); }
        ;
 
-rules: rules rule { push($2, &$1); $$=$1; 
-                                               printf(": rules->rules(%x) rule(%x)\n", $1,$2);}
-       | rule {$$=$1; printf(": rules->rule (%x)\n",$1); }
+rules: rules rule { push($2, &$1); $$=$1; }
+       | rule {$$=$1; }
        | rules error { $$=0; yyerror("invalid rule"); }
         ;
 
 rule:  condition       actions CR {
-                                                               printf("Got a new rule!\n");
-                                                               printf("expr: "); print_expr($1);
-                                                               printf("\n  -> actions: ");
-                                                               print_action($2); printf("\n");
-
                                                                $$=0;
                                                                if (add_rule($1, $2, &$$)<0) {
                                                                        yyerror("error calling add_rule");
                                                                        YYABORT;
                                                                }
-                                                               printf(": rule -> condition actions CR\n");
                                                          }
-       | CR  /* null rule */           { $$=0; printf(": rule-> CR!\n"); }
+       | CR  /* null rule */           { $$=0;}
        | condition error { $$=0; yyerror("bad actions in rule"); }
        ;
 
@@ -201,7 +255,7 @@ exp_elem:   METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                                                        }
                | METHOD MATCH error { $$=0; yyerror("string expected"); }
                | METHOD error  { $$=0; yyerror("invalid operator,"
-                                                                               "== or ~= expected");
+                                                                               "== or =~ expected");
                                                }
                | URI EQUAL_T STRING    {$$ = mk_elem(  EQUAL_OP, STRING_ST,
                                                                                                URI_O, $3); 
@@ -218,7 +272,7 @@ exp_elem:   METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                                                        }
                | URI MATCH error {  $$=0; yyerror("string expected"); }
                | URI error     { $$=0; yyerror("invalid operator,"
-                                                                       " == or ~= expected");
+                                                                       " == or =~ expected");
                                        }
                | SRCIP EQUAL_T net4    { $$=mk_elem(   EQUAL_OP, NET_ST,
                                                                                                SRCIP_O, $3);
@@ -239,7 +293,7 @@ exp_elem:   METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                                                                }
                | SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
                | SRCIP error  { $$=0; 
-                                                yyerror("invalid operator, == or ~= expected");}
+                                                yyerror("invalid operator, == or =~ expected");}
                | DSTIP EQUAL_T net4    { $$=mk_elem(   EQUAL_OP, NET_ST,
                                                                                                DSTIP_O, $3);
                                                                }
@@ -259,7 +313,7 @@ exp_elem:   METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                                                        }
                | DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
                | DSTIP error { $$=0; 
-                                               yyerror("invalid operator, == or ~= expected");}
+                                               yyerror("invalid operator, == or =~ expected");}
        ;
 
 net4:  ipv4 SLASH ipv4 { $$=mk_net($1, $3); } 
@@ -278,7 +332,7 @@ net4:       ipv4 SLASH ipv4 { $$=mk_net($1, $3); }
 host:  ID                              { $$=$1; }
        | host DOT ID           { $$=(char*)malloc(strlen($1)+1+strlen($3)+1);
                                                  if ($$==0){
-                                                       fprintf(stderr, "memory allocation failure"
+                                                       LOG(L_CRIT, "ERROR: cfg. parser: memory allocation failure"
                                                                                " while parsing host\n");
                                                  }else{
                                                        memcpy($$, $1, strlen($1));
@@ -382,17 +436,17 @@ cmd:              FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                                                                                                        "argument"); }
                | DROP LPAREN RPAREN    {$$=mk_action(DROP_T,0, 0, 0, 0); }
                | DROP                                  {$$=mk_action(DROP_T,0, 0, 0, 0); }
-               | LOG LPAREN STRING RPAREN      {$$=mk_action(  LOG_T, NUMBER_ST, 
+               | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(  LOG_T, NUMBER_ST, 
                                                                                                        STRING_ST,(void*)4,$3);
                                                                        }
-               | LOG LPAREN NUMBER COMMA STRING RPAREN {$$=mk_action(  LOG_T,
+               | LOG_TOK LPAREN NUMBER COMMA STRING RPAREN     {$$=mk_action(  LOG_T,
                                                                                                                                NUMBER_ST, 
                                                                                                                                STRING_ST,
                                                                                                                                (void*)$3,
                                                                                                                                $5);
                                                                                                }
-               | LOG error { $$=0; yyerror("missing '(' or ')' ?"); }
-               | LOG LPAREN error RPAREN { $$=0; yyerror("bad log"
+               | LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
                                                                        "argument"); }
                | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
                                                                                                                                STRING_ST, 
@@ -413,6 +467,24 @@ cmd:               FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                | EXEC LPAREN STRING RPAREN     { $$=mk_action( EXEC_T, STRING_ST, 0,
                                                                                                        $3, 0);
                                                                        }
+               | SET_HOST LPAREN STRING RPAREN { $$=mk_action( SET_HOST_T, STRING_ST, 0, $3, 0); }
+               | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
+               | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, STRING_ST, 0, $3, 0); }
+               | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
+               | SET_PORT LPAREN STRING RPAREN { $$=mk_action( SET_PORT_T, STRING_ST, 0, $3, 0); }
+               | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
+               | SET_USER LPAREN STRING RPAREN { $$=mk_action( SET_USER_T, STRING_ST, 0, $3, 0); }
+               | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
+               | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action( SET_USERPASS_T, STRING_ST, 0, $3, 0); }
+               | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
+               | SET_URI LPAREN STRING RPAREN { $$=mk_action( SET_URI_T, STRING_ST, 0, $3, 0); }
+               | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
+               | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
        ;
 
 
@@ -423,7 +495,7 @@ extern int column;
 extern int startcolumn;
 void yyerror(char* s)
 {
-       fprintf(stderr, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
+       LOG(L_CRIT, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
                        column, s);
        cfg_errors++;
 }
index 0f5a2eb..e7653af 100644 (file)
--- a/config.h
+++ b/config.h
@@ -28,4 +28,6 @@
 #define ROUTE_MAX_REC_LEV 10 /* maximum number of recursive calls
                                                           for route()*/
 
+#define MAX_URI_SIZE 1024      /* used when rewriting URIs */
+
 #endif
index 5268804..13a3119 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -63,7 +63,7 @@ int check_address(unsigned long ip, char *name, int resolver)
 
 int forward_request( struct sip_msg* msg, struct proxy_l * p)
 {
-       unsigned int len, new_len, via_len, received_len;
+       unsigned int len, new_len, via_len, received_len, uri_len;
        char line_buf[MAX_VIA_LINE_SIZE];
        char received_buf[MAX_RECEIVED_SIZE];
        char* new_buf;
@@ -96,15 +96,31 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
        }
        
        new_len=len+via_len+received_len;
+       if (msg->new_uri){ 
+               uri_len=strlen(msg->new_uri); 
+               new_len=new_len-strlen(msg->first_line.u.request.uri)+uri_len;
+       }
        new_buf=(char*)malloc(new_len+1);
        if (new_buf==0){
                LOG(L_ERR, "ERROR: forward_request: out of memory\n");
                goto error;
        }
-/* copy msg till first via */
+
        offset=s_offset=0;
-       size=msg->via1.hdr-buf;
-       memcpy(new_buf, orig, size);
+       if (msg->new_uri){
+               /* copy message up to uri */
+               size=msg->first_line.u.request.uri-buf;
+               memcpy(new_buf, orig, size);
+               offset+=size;
+               s_offset+=size;
+               /* add our uri */
+               memcpy(new_buf+offset, msg->new_uri, uri_len);
+               offset+=uri_len;
+               s_offset+=strlen(msg->first_line.u.request.uri); /* skip original uri */
+       }
+/* copy msg till first via */
+       size=msg->via1.hdr-(buf+s_offset);
+       memcpy(new_buf+offset, orig+s_offset, size);
        offset+=size;
        s_offset+=size;
  /* add our via */
index f14a40e..3c19e09 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -19,7 +19,7 @@ extern unsigned short port_no;
 extern char * names[];
 extern unsigned long addresses[];
 extern int addresses_no;
-extern int child_no;
+extern int children_no;
 extern int debug;
 extern int dont_fork;
 extern int log_stderr;
diff --git a/main.c b/main.c
index 6fb5854..c524e67 100644 (file)
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
 
 
 static char id[]="@(#) $Id$";
-static char version[]="sip_router 0.5";
+static char version[]="sip_router 0.6";
 static char help_msg[]= "\
 Usage: sip_router -l address [-l address] [options]\n\
 Options:\n\
@@ -289,6 +289,25 @@ int main(int argc, char** argv)
        
        /* fill missing arguments with the default values*/
        if (cfg_file==0) cfg_file=CFG_FILE;
+
+       /* load config file or die */
+       cfg_stream=fopen (cfg_file, "r");
+       if (cfg_stream==0){
+               fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
+                               strerror(errno));
+               goto error;
+       }
+       
+       yyin=cfg_stream;
+       if ((yyparse()!=0)||(cfg_errors)){
+               fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
+               goto error;
+       }
+       
+       
+       print_rl();
+
+       /* fix parameters */
        if (port_no<=0) port_no=SIP_PORT;
        if (children_no<=0) children_no=CHILD_NO;
        if (addresses_no==0) {
@@ -320,26 +339,6 @@ int main(int argc, char** argv)
                                inet_ntoa(*(struct in_addr*)&addresses[r]),
                                (unsigned short)port_no);
        }
-       
-       
-
-       /* load config file or die */
-       cfg_stream=fopen (cfg_file, "r");
-       if (cfg_stream==0){
-               fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
-                               strerror(errno));
-               goto error;
-       }
-       
-       yyin=cfg_stream;
-       if ((yyparse()!=0)||(cfg_errors)){
-               fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
-               goto error;
-       }
-       
-       
-       print_rl();
-
 
        /* init_daemon? */
        if (!dont_fork){
index a9210f7..c489c36 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "msg_parser.h"
 #include "parser_f.h"
+#include "error.h"
 #include "dprint.h"
 
 
@@ -118,10 +119,15 @@ error1:
 /* returns integer field name type */
 int field_name(char *s)
 {
-       if ((strcmp(s, "Via")==0 )||(strcmp(s,"v")==0))
+       int l;
+       l=strlen(s);
+       if (l<1) return HDR_OTHER;
+       else if ((l==1) && ((*s=='v')||(*s=='V')))
+               return HDR_VIA;
+       else if (strcasecmp(s, "Via")==0)
                return  HDR_VIA;
-       if ((strcmp(s, "To")==0)||(strcmp(s,"t")==0))
-               return HDR_TO;
+/*     if ((strcmp(s, "To")==0)||(strcmp(s,"t")==0))
+               return HDR_TO;*/
        return HDR_OTHER;
 }
 
@@ -137,7 +143,7 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
           (CRLF in the field body must be removed)
        */
 
-       char* tmp;
+       char* tmp, *tmp2;
        char* nl;
        char* body;
        int offset;
@@ -156,11 +162,25 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
        
        tmp=eat_token2(buffer, len, ':');
        if ((tmp==buffer) || (tmp-buffer==len) ||
-               (is_empty(buffer, tmp-buffer-1))|| (*tmp!=':')){
+               (is_empty(buffer, tmp-buffer))|| (*tmp!=':')){
                hdr_f->type=HDR_ERROR;
                goto error;
        }
        *tmp=0;
+       /* take care of possible spaces (e.g: "Via  :") */
+       tmp2=eat_token(buffer, tmp-buffer);
+       /* in the worst case tmp2=buffer+tmp-buffer=tmp */
+       *tmp2=0;
+       if (tmp2<tmp){
+               tmp2++;
+               /* catch things like: "Via foo bar:" */
+               tmp2=eat_space(tmp2, tmp-tmp2);
+               if (tmp2!=tmp){
+                       hdr_f->type=HDR_ERROR;
+                       goto error;
+               }
+       }
+
        hdr_f->type=field_name(buffer);
        body= ++tmp;
        hdr_f->name=buffer;
@@ -210,6 +230,165 @@ char* parse_hostport(char* buf, char** host, short int* port)
 
 
 
+/* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
+   len= len of uri
+returns: fills uri & returns <0 on error or 0 if ok */
+int parse_uri(char *buf, int len, struct sip_uri* uri)
+{
+       char* next, *end;
+       char *user, *passwd, *host, *port, *params, *headers;
+       int host_len, port_len, params_len, headers_len;
+       int ret;
+       
+
+       ret=0;
+       end=buf+len;
+       memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
+       /* look for "sip:"*/;
+       next=memchr(buf, ':',  len);
+       if ((next==0)||(strncmp(buf,"sip",next-buf)!=0)){
+               LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
+               ret=E_UNSPEC;
+               goto error;
+       }
+       buf=next+1; /* next char after ':' */
+       if (buf>end){
+               LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
+               ret=E_UNSPEC;
+               goto error;
+       }
+       /*look for '@' */
+       next=memchr(buf,'@', end-buf);
+       if (next==0){
+               /* no '@' found, => no userinfo */
+               uri->user=0;
+               uri->passwd=0;
+               host=buf;
+       }else{
+               /* found it */
+               user=buf;
+               /* try to find passwd */
+               passwd=memchr(user,':', next-user);
+               if (passwd==0){
+                       /* no ':' found => no password */
+                       uri->passwd=0;
+                       uri->user=(char*)malloc(next-user+1);
+                       if (uri->user==0){
+                               LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
+                               ret=E_OUT_OF_MEM;
+                               goto error;
+                       }
+                       memcpy(uri->user,user, next-user);
+                       uri->user[next-user]=0; /* null terminate it, usefull for easy printing*/
+               }else{
+                       uri->user=(char*)malloc(passwd-user+1);
+                       if (uri->user==0){
+                               LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
+                               ret=E_OUT_OF_MEM;
+                               goto error;
+                       }
+                       memcpy(uri->user,user, passwd-user);
+                       uri->user[passwd-user]=0;
+                       passwd++; /*skip ':' */
+                       uri->passwd=(char*)malloc(next-passwd+1);
+                       if (uri->passwd==0){
+                               LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
+                               ret=E_OUT_OF_MEM;
+                               goto error;
+                       }
+                       memcpy(uri->passwd,passwd, next-passwd);
+                       uri->passwd[next-passwd]=0;
+               }
+               host=next+1; /* skip '@' */
+       }
+       /* try to find the rest */
+       if(host>=end){
+               LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
+               ret=E_UNSPEC;
+               goto error;
+       }
+       headers=memchr(host,'?',end-host);
+       params=memchr(host,';',end-host);
+       port=memchr(host,':',end-host);
+       host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:end-host;
+       /* get host */
+       uri->host=malloc(host_len+1);
+       if (uri->host==0){
+               LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
+               ret=E_OUT_OF_MEM;
+               goto error;
+       }
+       memcpy(uri->host,host, host_len);
+       uri->host[host_len]=0;
+       /* get port*/
+       if ((port)&&(port+1<end)){
+               port++;
+               if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
+                       /* error -> invalid uri we found ';' or '?' before ':' */
+                       LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
+                       ret=E_UNSPEC;
+                       goto error;
+               }
+               port_len=(params)?params-port:(headers)?headers-port:end-port;
+               uri->port=malloc(port_len+1);
+               if (uri->port==0){
+                       LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
+                       ret=E_OUT_OF_MEM;
+                       goto error;
+               }
+               memcpy(uri->port, port, port_len);
+               uri->port[port_len]=0;
+       }else uri->port=0;
+       /* get params */
+       if ((params)&&(params+1<end)){
+               params++;
+               if ((headers) && (headers<params)){
+                       /* error -> invalid uri we found '?' or '?' before ';' */
+                       LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
+                       ret=E_UNSPEC;
+                       goto error;
+               }
+               params_len=(headers)?headers-params:end-params;
+               uri->params=malloc(params_len+1);
+               if (uri->params==0){
+                       LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
+                       ret=E_OUT_OF_MEM;
+                       goto error;
+               }
+               memcpy(uri->params, params, params_len);
+               uri->params[params_len]=0;
+       }else uri->params=0;
+       /*get headers */
+       if ((headers)&&(headers+1<end)){
+               headers++;
+               headers_len=end-headers;
+               uri->headers=malloc(headers_len+1);
+               if(uri->headers==0){
+                       LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
+                       ret=E_OUT_OF_MEM;
+                       goto error;
+               }
+               memcpy(uri->headers, headers, headers_len);
+               uri->headers[headers_len]=0;
+       }else uri->headers=0;
+       
+       return ret;
+error:
+       return ret;
+}
+
+
+                       
+
+                       
+                       
+       
+               
+       
+       
+
+
+
 /* parses a via body, returns next via (for compact vias) & fills vb,
  * the buffer should be null terminated! */
 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)
                                                        goto skip;
                                                }else{
                                                /*  add 1 (we don't see the trailing lf which
-                                                *  was zeroed by get_hfr_field */
+                                                *  was zeroed by get_hfr_field) */
                                                        vb1.size+=1;
                                                }
+                                               if (fl.type!=SIP_REPLY) goto skip; /* we are interested in the 2nd via 
+                                                                                                                          only in replies */
                                }else if (second_via==0){
                                                        second_via=hf.body;
                                                        vb2.hdr=hf.name;
index 869836b..74a567b 100644 (file)
@@ -72,10 +72,23 @@ struct sip_msg{
                                   via, etc. point into it */
                                   
        unsigned int len; /* message len (orig) */
+
+       /* modifications */
+       char* new_uri; /* changed first line uri*/
        
 };
 
 
+struct sip_uri{
+       char* user;
+       char* passwd;
+       char* host;
+       char* port;
+       char* params;
+       char* headers;
+};
+
+
 
 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
 char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f);
@@ -83,6 +96,7 @@ int field_name(char *s);
 char* parse_hostport(char* buf, char** host, short int* port);
 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb);
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
+int parse_uri(char *buf, int len, struct sip_uri* uri);
 
 
 
index 584aa22..f4139b6 100644 (file)
--- a/receive.c
+++ b/receive.c
@@ -18,6 +18,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
        struct sip_msg msg;
        struct route_elem *re;
 
+       memset(&msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
        /* fill in msg */
        msg.buf=buf;
        msg.len=len;
diff --git a/route.c b/route.c
index cd8c345..b54f30a 100644 (file)
--- a/route.c
+++ b/route.c
@@ -407,16 +407,16 @@ void print_rl()
 
        for(j=0; j<RT_NO; j++){
                if (rlist[j]==0){
-                       if (j==0) printf("WARNING: the main routing table is empty\n");
+                       if (j==0) DBG("WARNING: the main routing table is empty\n");
                        continue;
                }
-               printf("routing table %d:\n",j);
+               DBG("routing table %d:\n",j);
                for (t=rlist[j],i=0; t; i++, t=t->next){
-                       printf("%2d.condition: ",i);
+                       DBG("%2d.condition: ",i);
                        print_expr(t->condition);
-                       printf("\n  -> ");
+                       DBG("\n  -> ");
                        print_action(t->actions);
-                       printf("\n    Statistics: tx=%d, errors=%d, tx_bytes=%d\n",
+                       DBG("\n    Statistics: tx=%d, errors=%d, tx_bytes=%d\n",
                                        t->tx, t->errors, t->tx_bytes);
                }
        }
index 7d149d5..92efea7 100644 (file)
@@ -12,6 +12,8 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 
+#include "dprint.h"
+
 struct expr* mk_exp(int op, struct expr* left, struct expr* right)
 {
        struct expr * e;
@@ -23,7 +25,7 @@ struct expr* mk_exp(int op, struct expr* left, struct expr* right)
        e->r.expr=right;
        return e;
 error:
-       fprintf(stderr, "ERROR: mk_exp: memory allocation failure\n");
+       LOG(L_CRIT, "ERROR: mk_exp: memory allocation failure\n");
        return 0;
 }
 
@@ -40,7 +42,7 @@ struct expr* mk_elem(int op, int subtype, int operand, void* param)
        e->r.param=param;
        return e;
 error:
-       fprintf(stderr, "ERROR: mk_elem: memory allocation failure\n");
+       LOG(L_CRIT, "ERROR: mk_elem: memory allocation failure\n");
        return 0;
 }
 
@@ -60,7 +62,7 @@ struct action* mk_action(int type, int p1_type, int p2_type, void* p1, void* p2)
        return a;
        
 error:
-       fprintf(stderr, "ERROR: mk_action: memory allocation failure\n");
+       LOG(L_CRIT, "ERROR: mk_action: memory allocation failure\n");
        return 0;
 
 }
@@ -89,7 +91,7 @@ struct net* mk_net(unsigned long ip, unsigned long mask)
        n->mask=mask;
        return n;
 error:
-       fprintf(stderr, "ERROR: mk_net_mask: memory allocation failure\n");
+       LOG(L_CRIT, "ERROR: mk_net_mask: memory allocation failure\n");
        return 0;
 }
 
@@ -98,7 +100,7 @@ error:
 
 void print_ip(unsigned ip)
 {
-       printf("%d.%d.%d.%d", ((unsigned char*)&ip)[0],
+       DBG("%d.%d.%d.%d", ((unsigned char*)&ip)[0],
                                                  ((unsigned char*)&ip)[1],
                                                  ((unsigned char*)&ip)[2],
                                                  ((unsigned char*)&ip)[3]);
@@ -108,10 +110,10 @@ void print_ip(unsigned ip)
 void print_net(struct net* net)
 {
        if (net==0){
-               fprintf(stderr, "ERROR: print net: null pointer\n");
+               LOG(L_WARN, "ERROR: print net: null pointer\n");
                return;
        }
-       print_ip(net->ip); printf("/"); print_ip(net->mask);
+       print_ip(net->ip); DBG("/"); print_ip(net->mask);
 }
 
 
@@ -119,42 +121,42 @@ void print_net(struct net* net)
 void print_expr(struct expr* exp)
 {
        if (exp==0){
-               fprintf(stderr, "ERROR: print_expr: null expression!\n");
+               LOG(L_CRIT, "ERROR: print_expr: null expression!\n");
                return;
        }
        if (exp->type==ELEM_T){
                switch(exp->l.operand){
                        case METHOD_O:
-                               printf("method");
+                               DBG("method");
                                break;
                        case URI_O:
-                               printf("uri");
+                               DBG("uri");
                                break;
                        case SRCIP_O:
-                               printf("srcip");
+                               DBG("srcip");
                                break;
                        case DSTIP_O:
-                               printf("dstip");
+                               DBG("dstip");
                                break;
                        default:
-                               printf("UNKNOWN");
+                               DBG("UNKNOWN");
                }
                switch(exp->op){
                        case EQUAL_OP:
-                               printf("==");
+                               DBG("==");
                                break;
                        case MATCH_OP:
-                               printf("~=");
+                               DBG("=~");
                                break;
                        default:
-                               printf("<UNKNOWN>");
+                               DBG("<UNKNOWN>");
                }
                switch(exp->subtype){
                        case NOSUBTYPE: 
-                                       printf("N/A");
+                                       DBG("N/A");
                                        break;
                        case STRING_ST:
-                                       printf("\"%s\"", (char*)exp->r.param);
+                                       DBG("\"%s\"", (char*)exp->r.param);
                                        break;
                        case NET_ST:
                                        print_net((struct net*)exp->r.param);
@@ -163,35 +165,35 @@ void print_expr(struct expr* exp)
                                        print_ip(exp->r.intval);
                                        break;
                        default:
-                                       printf("type<%d>", exp->subtype);
+                                       DBG("type<%d>", exp->subtype);
                }
        }else if (exp->type==EXP_T){
                switch(exp->op){
                        case AND_OP:
-                                       printf("AND( ");
+                                       DBG("AND( ");
                                        print_expr(exp->l.expr);
-                                       printf(", ");
+                                       DBG(", ");
                                        print_expr(exp->r.expr);
-                                       printf(" )");
+                                       DBG(" )");
                                        break;
                        case OR_OP:
-                                       printf("OR( ");
+                                       DBG("OR( ");
                                        print_expr(exp->l.expr);
-                                       printf(", ");
+                                       DBG(", ");
                                        print_expr(exp->r.expr);
-                                       printf(" )");
+                                       DBG(" )");
                                        break;
                        case NOT_OP:    
-                                       printf("NOT( ");
+                                       DBG("NOT( ");
                                        print_expr(exp->l.expr);
-                                       printf(" )");
+                                       DBG(" )");
                                        break;
                        default:
-                                       printf("UNKNOWN_EXP ");
+                                       DBG("UNKNOWN_EXP ");
                }
                                        
        }else{
-               printf("ERROR:print_expr: unknown type\n");
+               DBG("ERROR:print_expr: unknown type\n");
        }
 }
                                        
@@ -204,55 +206,73 @@ void print_action(struct action* a)
        for(t=a; t!=0;t=t->next){
                switch(t->type){
                        case FORWARD_T:
-                                       printf("forward(");
+                                       DBG("forward(");
                                        break;
                        case SEND_T:
-                                       printf("send(");
+                                       DBG("send(");
                                        break;
                        case DROP_T:
-                                       printf("drop(");
+                                       DBG("drop(");
                                        break;
                        case LOG_T:
-                                       printf("log(");
+                                       DBG("log(");
                                        break;
                        case ERROR_T:
-                                       printf("error(");
+                                       DBG("error(");
                                        break;
                        case ROUTE_T:
-                                       printf("route(");
+                                       DBG("route(");
                                        break;
                        case EXEC_T:
-                                       printf("exec(");
+                                       DBG("exec(");
+                                       break;
+                       case SET_HOST_T:
+                                       DBG("sethost(");
+                                       break;
+                       case SET_HOSTPORT_T:
+                                       DBG("sethostport(");
+                                       break;
+                       case SET_USER_T:
+                                       DBG("setuser(");
+                                       break;
+                       case SET_USERPASS_T:
+                                       DBG("setuserpass(");
+                                       break;
+                       case SET_PORT_T:
+                                       DBG("setport(");
+                                       break;
+                       case SET_URI_T:
+                                       DBG("seturi(");
                                        break;
                        default:
-                                       printf("UNKNOWN(");
+                                       DBG("UNKNOWN(");
                }
                switch(t->p1_type){
                        case STRING_ST:
-                                       printf("\"%s\"", t->p1.string);
+                                       DBG("\"%s\"", t->p1.string);
                                        break;
                        case NUMBER_ST:
-                                       printf("%d",t->p1.number);
+                                       DBG("%d",t->p1.number);
                                        break;
                        case IP_ST:
                                        print_ip(t->p1.number);
                                        break;
                        default:
-                                       printf("type<%d>", t->p1_type);
+                                       DBG("type<%d>", t->p1_type);
                }
                switch(t->p2_type){
                        case NOSUBTYPE:
                                        break;
                        case STRING_ST:
-                                       printf(", \"%s\"", t->p2.string);
+                                       DBG(", \"%s\"", t->p2.string);
                                        break;
                        case NUMBER_ST:
-                                       printf(", %d",t->p2.number);
+                                       DBG(", %d",t->p2.number);
                                        break;
                        default:
-                                       printf(", type<%d>", t->p2_type);
+                                       DBG(", type<%d>", t->p2_type);
                }
-               printf("); ");
+               DBG("); ");
        }
 }
                        
index 1f8fe8f..87bc311 100644 (file)
@@ -11,13 +11,14 @@ enum { AND_OP=1, OR_OP, NOT_OP };
 enum { EQUAL_OP=10, MATCH_OP };
 enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O };
 
-enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T};
+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, 
+               SET_USERPASS_T, SET_PORT_T, SET_URI_T};
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST };
 
        
 struct expr{
        int type; /* exp, exp_elem */
-       int op; /* and, or, not | ==,  ~= */
+       int op; /* and, or, not | ==,  =~ */
        int  subtype;
        union {
                struct expr* expr;
index ce03260..fbb81af 100644 (file)
@@ -1,5 +1,5 @@
-INVITE sip:x@y.z SIP/2.0/UDP
-Via  : SIP  /   2.0
+INVITE sip:x@y.z SIP/2.0
+Via : SIP  /   2.0
  /UDP
     193.175.133.193
 
index 80343b0..c92085c 100644 (file)
@@ -1,4 +1,4 @@
-INVITE sip:andrei@localhost SIP/2.0/UDP
+INVITE sip:andrei@localhost:5061;a=b?c=d SIP/2.0
 Via: SIP/2.0/UDP localhost