Andrei Pelinescu-Onciul преди 24 години
родител
ревизия
a15c363f83
променени са 11 файла, в които са добавени 517 реда и са изтрити 107 реда
  1. 12 0
      Makefile
  2. 3 1
      cfg.y
  3. 4 0
      config.h
  4. 14 0
      error.h
  5. 2 0
      msg_parser.h
  6. 143 0
      proxy.c
  7. 32 0
      proxy.h
  8. 281 91
      route.c
  9. 15 13
      route.h
  10. 9 0
      route_struct.c
  11. 2 2
      route_struct.h

+ 12 - 0
Makefile

@@ -11,8 +11,12 @@ depends= $(sources:.c=.d)
 
 NAME=sip_router
 
+
 CC=gcc
 CFLAGS=-O2
+LEX=lex
+YACC=bison
+YACC_FLAGS=-d
 # on linux and freebsd keep it empty (e.g. LIBS= )
 # on solaris add -lxnet (e.g. LIBS= -lxnet)
 LIBS=
@@ -23,12 +27,20 @@ MKDEP=gcc -M
 
 #implicit rules
 
+
 %.o:%.c $(ALLDEP)
 	$(CC) $(CFLAGS) -c $< -o $@
 
 %.d: %.c
 	$(MKDEP) $< >$@
 
+# normal rules
+lex.yy.c: cfg.lex $(ALLDEP)
+	$(LEX) $<
+
+cfg.tab.c: cfg.y
+	$(YACC) $(YACC_FLAGS) $<
+
 $(NAME): $(objs)
 	$(CC) $(CFLAGS) $(LIBS) $(objs) -o $(NAME)
 

+ 3 - 1
cfg.y

@@ -238,7 +238,7 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
 	;
 
 net4:	ipv4 SLASH ipv4	{ $$=mk_net($1, $3); } 
-	| ipv4 SLASH NUMBER {	if (($3>32)|($3<1)){
+	| ipv4 SLASH NUMBER {	if (($3>32)|($3<0)){
 								yyerror("invalid bit number in netmask");
 								$$=0;
 							}else{
@@ -402,8 +402,10 @@ yyerror(char* s)
 			column, s);
 }
 
+/*
 int main(int argc, char ** argv)
 {
 	if (yyparse()!=0)
 		fprintf(stderr, "parsing error\n");
 }
+*/

+ 4 - 0
config.h

@@ -21,4 +21,8 @@
 /* default number of child processes started */
 #define CHILD_NO    8
 
+#define RT_NO 10 /* routing tables number */
+
+#define MAX_REC_LEV 100 /* maximum number of recursive calls */
+
 #endif

+ 14 - 0
error.h

@@ -0,0 +1,14 @@
+/*
+ * $Id$
+ */
+
+#ifndef error_h
+#define error_h
+
+#define E_OUT_OF_MEM  -2
+#define E_BAD_RE      -3
+#define E_BAD_ADDRESS -4
+#define E_BUG         -5
+
+
+#endif

+ 2 - 0
msg_parser.h

@@ -64,6 +64,8 @@ struct sip_msg{
 	struct msg_start first_line;
 	struct via_body via1;
 	struct via_body via2;
+	unsigned int src_ip;
+	unsigned int dst_ip;
 };
 
 

+ 143 - 0
proxy.c

@@ -0,0 +1,143 @@
+/*
+ * $Id$
+ *
+ * proxy list & assoc. functions
+ *
+ */
+
+
+#include "proxy.h"
+#include "error.h"
+
+#include <string.h>
+
+
+struct proxy_l* proxies=0;
+
+
+
+/* searches for the proxy named 'name', on port 'port'
+   returns: pointer to proxy_l on success or 0 if not found */ 
+struct proxy_l* find_proxy(char *name, unsigned short port)
+{
+	struct proxy_l* t;
+	for(t=proxies; t; t=t->next)
+		if ((strcasecmp(t->name, name)==0) && (t->port==port))
+			break;
+	return t;
+}
+
+
+
+/* copies a hostent structure*, returns 0 on success, <0 on error*/
+int hostent_cpy(struct hostent *dst, struct hosten* src)
+{
+	int len, r;
+
+	/* start copying the host entry.. */
+	/* copy h_name */
+	len=strlen(src->h_name)+1;
+	dst->h_name=(char*)malloc(sizeof(char) * len);
+	if (dst->h_name) strncpy(dst->h_name,src->h_name, len);
+	else{
+		ret=E_OUT_OF_MEM;
+		goto error;
+	}
+
+	/* copy h_aliases */
+	for (len=0;src->h_aliases[len];len++);
+	dst->h_aliases=(char**)malloc(sizeof(char*)*(len+1));
+	if (dst->h_aliases==0){
+		ret=E_OUT_OF_MEM;
+		free(dst->h_name);
+		goto error;
+	}
+	memset((void*)dst->h_aliases, 0, sizeof(char*) * (len+1) );
+	for (i=0;i<len;i++){
+		len2=strlen(src->h_aliases[i])+1;
+		dst->.h_aliases[i]=(char*)malloc(sizeof(char)*len2);
+		if (dst->h_aliases==0){
+			ret=E_OUT_OF_MEM;
+			free(dst->h_name);
+			for(r=0; r<i; r++)	free(dst->h_aliases[r]);
+			free(dst->h_aliases);
+			goto error;
+		}
+		strncpy(dst->h_aliases[i], src->h_aliases[i], len2);
+	}
+	/* copy h_addr_list */
+	for (len=0;src->h_addr_list[len];len++);
+	dst->h_addr_list=(char**)malloc(sizeof(char*)*(len+1));
+	if (dst->h_addr_list==0){
+		ret=E_OUT_OF_MEM;
+		free(dst->h_name);
+		for(r=0; h_aliases[r]; r++)	free(dst->h_aliases[r]);
+		free h_aliases[r];
+		free(dst->h_aliases);
+		goto error;
+	}
+	memset((void*)dst->.h_addr_list, 0, sizeof(char*) * (len+1) );
+	for (i=0;i<len;i++){
+		dst->h_addr_list[i]=(char*)malloc(sizeof(char)*src->h_length);
+		if (dst->h_addr_list[i]==0){
+			ret=E_OUT_OF_MEM;
+			free(dst->h_name);
+			for(r=0; h_aliases[r]; r++)	free(dst->h_aliases[r]);
+			free h_aliases[r];
+			free(dst->h_aliases);
+			for (r=0; r<i;r++) free(dst->h_addr_list[r]);
+			free(dst->h_addr_list);
+			goto error;
+		}
+		memcpy(dst->h_addr_list[i], src->h_addr_list[i], src->h_length);
+	}
+
+	/* copy h_addr_type & length */
+	dst->h_addrtype=src->h_addrtype;
+	dst->host.h_length=src->h_length;
+	/*finished hostent copy */
+	
+	return 0;
+
+error:
+	LOG(L_CRIT, "ERROR: hostent_cpy: memory allocation failure\n");
+	return ret;
+}
+
+
+
+struct proxy_l* add_proxy(char* name, unsigned short port)
+{
+	proxy_l* p;
+	struct hostent he;
+	
+	if ((p=find_proxy(name, port))!=0) return p;
+	p=(struct proxy_l*) malloc(sizeof(struct proxy_l));
+	if (p==0){
+		LOG(L_CRIT, "ERROR: add_proxy: memory allocation failure\n");
+		goto error;
+	}
+	memset(p,0,sizeof(struct_proxy_l));
+	p->name=name;
+	p->port=port;
+	he=gethostbyname(name);
+	if (he==0){
+		LOG(L_CRIT, "ERROR: add_proxy: could not resolve hostname:"
+					" \"%s\"\n", name);
+		free(p);
+		goto error;
+	}
+	if (hostent_cpy(&(p->host), he)!=0){
+		free(p);
+		goto error;
+	}
+	p->ok=1;
+	/* add p to the proxy list */
+	p->next=proxies;
+	proxies=p;
+	return p;
+
+error:
+	return 0;
+}
+

+ 32 - 0
proxy.h

@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef proxy_h
+#define proxy_h
+
+#include <netdb.h>
+
+struct proxy_l{
+	struct proxy_l* next;
+	char* name; /* original name */
+	struct hostent host; /* addresses */
+	unsigned short port;
+	unsigned short reserved; /*align*/
+	
+	/* socket ? */
+
+	int addr_idx;	/* crt. addr. idx. */
+	int ok; /* 0 on error */
+	/*statisticis*/
+	int tx;
+	int tx_bytes;
+	int errors;
+};
+
+extern struct proxy_l* proxies;
+
+
+#endif
+

+ 281 - 91
route.c

@@ -9,20 +9,25 @@
 #include <regex.h>
 #include <netdb.h>
 #include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
 
 #include "route.h"
 #include "cfg_parser.h"
 #include "dprint.h"
 
 /* main routing list */
-struct route_elem* rlist=0;
+struct route_elem* rlist[RT_NO];
 
 
 
-void free_re(struct route_elem* r)
+ void free_re(struct route_elem* r)
 {
 	int i;
 	if (r){
+		/*
 			regfree(&(r->method));
 			regfree(&(r->uri));
 			
@@ -37,6 +42,7 @@ void free_re(struct route_elem* r)
 					free(r->host.h_addr_list[i]);
 				free(r->host.h_addr_list);
 			}
+		*/
 			free(r);
 	}
 }
@@ -82,102 +88,301 @@ void clear_rlist(struct route_elem** rl)
 
 
 
-int add_rule(struct cfg_line* cl, struct route_elem** head)
+/* traverses an expr tree and compiles the REs where necessary) 
+ * returns: 0 for ok, <0 if errors */
+int fix_expr(struct expr* exp)
 {
-	
-	struct route_elem* re;
-	struct hostent * he;
+	regex_t* re;
 	int ret;
-	int i,len, len2;
+	
+	if (exp==0){
+		LOG(L_CRIT, "BUG: fix_expr: null pointer\n");
+		return E_BUG;
+	}
+	if (exp->type==EXP_T){
+		switch(exp->op){
+			case AND_OP:
+			case OR_OP:
+						if ((ret=fix_expr(exp->l.expr))!=0)
+							return ret;
+						ret=fix_expr(exp->r.expr);
+						break;
+			case NOT_OP:
+						ret=fix_expr(exp->l.expr);
+						break;
+			default:
+						LOG(L_CRIT, "BUG: fix_expr: unknown op %d\n",
+								exp->op);
+		}
+	}else if (exp->type==ELEM_T){
+			if (exp->op==MATCH_OP){
+				if (exp->subtype==STRING_ST){
+					re=(regex_t*)malloc(sizeof(regex_t));
+					if (re==0){
+						LOG(L_CRIT, "ERROR: fix_expr: memory allocation"
+								" failure\n");
+						return E_OUT_OF_MEM;
+					}
+					if (regcomp(re, (char*) exp->r.param,
+								REG_EXTENDED|REG_NOSUB|REG_ICASE) ){
+						LOG(L_CRIT, "ERROR: fix_expr : bad re \"%s\"\n",
+									(char*) exp->r.param);
+						free(re);
+						return E_BAD_RE;
+					}
+					/* replace the string with the re */
+					free(exp->r.param);
+					exp->r.param=re;
+					exp->subtype=RE_ST;
+				}else if (exp->subtype!=RE_ST){
+					LOG(L_CRIT, "BUG: fix_expr : invalid type for match\n");
+					return E_BUG;
+				}
+			}
+			ret=0;
+	}
+	return ret;
+}
 
 
-	re=init_re();
-	if (re==0) return E_OUT_OF_MEM;
 
-	if (regcomp(&(re->method), cl->method, REG_EXTENDED|REG_NOSUB|REG_ICASE)){
-		LOG(L_CRIT, "ERROR: add_rule: bad re \"%s\"\n", cl->method);
-		ret=E_BAD_RE;
-		goto error;
-	}
-	if (regcomp(&(re->uri), cl->uri, REG_EXTENDED|REG_NOSUB|REG_ICASE) ){
-		LOG(L_CRIT, "ERROR: add_rule: bad re \"%s\"\n", cl->uri);
-		ret=E_BAD_RE;
-		goto error;
+/* adds the proxies in the proxy list & resolves the hostnames */
+int fix_actions(struct action* a)
+{
+	struct action *t;
+	struct proxy* p;
+	char *tmp;
+	
+	for(t=a; t!=0; t=t->next){
+		switch(t->type){
+			case FORWARD_T:
+			case SEND_T:
+					switch(t->p1_type){
+						case NUMBER_ST:
+							tmp=strdup(inet_ntoa(
+										*(struct in_addr*)&t->p1.number));
+							if (tmp==0){
+								LOG(L_CRIT, "ERROR: fix_actions:"
+										"memory allocation failure\n");
+								return E_OUT_OF_MEM;
+							}
+							t->p1_type=STRING_ST;
+							t->p1.string=tmp;
+							/* no break */
+						case STRING_ST:
+							p=add_proxy(t->p1.string, t->p2.number);
+							if (p==0) return E_BAD_ADDRESS;
+							t->p1.data=p;
+							t->p1_type=PROXY_ST;
+							break;
+						default:
+							LOG(L_CRIT, "BUG: fix_actions: invalid type"
+									" (should be string or number)\n");
+							return E_BUG;
+					}
+					break;
+		}
 	}
+	return 0;
+}
+
 
+
+/* eval_elem helping function, returns str op param */
+int comp_str(char* str, void* param, int op, int subtype)
+{
+	int ret;
 	
-	he=gethostbyname(cl->address);
-	if (he==0){
-		LOG(L_CRIT, "ERROR: add_rule: cannot resolve \"%s\"\n", cl->address);
-		ret=E_BAD_ADDRESS;
+	ret=-1;
+	if (op==EQUAL_OP){
+		if (subtype!=STRING_ST){
+			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
+					"string expected\n", subtype);
+			goto error;
+		}
+		ret=(strcasecmp(str, (char*)param)==0);
+	}else if (op==MATCH_OP){
+		if (subtype!=RE_ST){
+			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
+					" RE expected\n", subtype);
+			goto error;
+		}
+		ret=(regexec((regex_t*)param, str, 0, 0, 0)==0);
+	}else{
+		LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op);
 		goto error;
 	}
+	return ret;
 	
-	/* start copying the host entry.. */
-	/* copy h_name */
-	len=strlen(he->h_name)+1;
-	re->host.h_name=(char*)malloc(sizeof(char) * len);
-	if (re->host.h_name) strncpy(re->host.h_name, he->h_name, len);
-	else{
-		ret=E_OUT_OF_MEM;
-		goto error;
+error:
+	return -1;
+}
+
+
+
+/* eval_elem helping function, returns a op param */
+int comp_ip(unsigned a, void* param, int op, int subtype)
+{
+	struct hostent* he;
+	char ** h;
+	int ret;
+
+	ret=-1;
+	switch(subtype){
+		case NET_ST:
+			ret=(a&((struct net*)param)->mask)==((struct net*)param)->ip;
+			break;
+		case STRING_ST:
+			/* 1: compare with ip2str*/
+			ret=comp_str(inet_ntoa(*(struct in_addr*)&a), param, op,
+						subtype);
+			if (ret==1) break;
+			/* 2: (slow) rev dns the address
+			 * and compare with all the aliases */
+			he=gethostbyaddr(&a, sizeof(a), AF_INET);
+			if (he==0){
+				LOG(L_DBG, "comp_ip: could not rev_resolve %x\n", a);
+				ret=0;
+			}else{
+				/*  compare with primayry host name */
+				ret=comp_str(he->h_name, param, op, subtype);
+				/* compare with all the aliases */
+				for(h=he->h_aliases; (ret!=1) && (*h); h++){
+					ret=comp_str(*h, param, op, subtype);
+				}
+			}
+			break;
+		default:
+			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
+						" src_ip or dst_ip (%d)\n", subtype);
+			ret=-1;
 	}
+	return ret;
+	
+error:
+	return -1;
+}
+
 
-	/* copy h_aliases */
-	for (len=0;he->h_aliases[len];len++);
-	re->host.h_aliases=(char**)malloc(sizeof(char*)*(len+1));
-	if (re->host.h_aliases==0){
-		ret=E_OUT_OF_MEM;
+
+/* returns: 0/1 (false/true) or -1 on error */
+int eval_elem(struct expr* e, struct sip_msg* msg)
+{
+
+	int ret;
+	
+	if (e->type!=ELEM_T){
+		LOG(L_CRIT," BUG: eval_elem: invalid type\n");
 		goto error;
 	}
-	memset((void*)re->host.h_aliases, 0, sizeof(char*) * (len+1) );
-	for (i=0;i<len;i++){
-		len2=strlen(he->h_aliases[i])+1;
-		re->host.h_aliases[i]=(char*)malloc(sizeof(char)*len2);
-		if (re->host.h_aliases==0){
-			ret=E_OUT_OF_MEM;
-			goto error;
-		}
-		strncpy(re->host.h_aliases[i], he->h_aliases[i], len2);
+	switch(e->l.operand){
+		case METHOD_O:
+				ret=comp_str(msg->first_line.u.request.method, e->r.param,
+								e->op, e->subtype);
+				break;
+		case URI_O:
+				ret=comp_str(msg->first_line.u.request.uri, e->r.param,
+								e->op, e->subtype);
+				break;
+		case SRCIP_O:
+				ret=comp_ip(msg->src_ip, e->r.param, e->op, e->subtype);
+				break;
+		case DSTIP_O:
+				ret=comp_ip(msg->dst_ip, e->r.param, e->op, e->subtype);
+				break;
+		case DEFAULT_O:
+				ret=1;
+				break;
+		default:
+				LOG(L_CRIT, "BUG: eval_elem: invalid operand %d\n",
+							e->l.operand);
 	}
-	/* copy h_addr_list */
-	for (len=0;he->h_addr_list[len];len++);
-	re->host.h_addr_list=(char**)malloc(sizeof(char*)*(len+1));
-	if (re->host.h_addr_list==0){
-		ret=E_OUT_OF_MEM;
-		goto error;
+	return ret;
+error:
+	return -1;
+}
+
+
+
+int eval_expr(struct expr* e, struct sip_msg* msg)
+{
+	static int rec_lev=0;
+	int ret;
+	
+	rec_lev++;
+	if (rec_lev>MAX_REC_LEV){
+		LOG(L_CRIT, "ERROR: eval_expr: too many expressions (%d)\n",
+				rec_lev);
+		ret=-1;
+		goto skip;
 	}
-	memset((void*)re->host.h_addr_list, 0, sizeof(char*) * (len+1) );
-	for (i=0;i<len;i++){
-		re->host.h_addr_list[i]=(char*)malloc(sizeof(char)*he->h_length);
-		if (re->host.h_addr_list[i]==0){
-			ret=E_OUT_OF_MEM;
-			goto error;
+	
+	if (e->type==ELEM_T){
+		ret=eval_elem(e, msg);
+	}else if (e->type==EXP_T){
+		switch(e->op){
+			case AND_OP:
+				ret=eval_expr(e->l.expr, msg);
+				/* if error or false stop evaluating the rest */
+				if (ret!=1) break;
+				ret=eval_expr(e->r.expr, msg); /*ret1 is 1*/
+				break;
+			case OR_OP:
+				ret=eval_expr(e->l.expr, msg);
+				/* if true or error stop evaluating the rest */
+				if (ret!=0) break;
+				ret=eval_expr(e->r.expr, msg); /* ret1 is 0 */
+				break;
+			case NOT_OP:
+				ret=eval_expr(e->l.expr, msg);
+				if (ret<0) break;
+				ret= ! ret;
+				break;
+			default:
+				LOG(L_CRIT, "BUG: eval_expr: unknown op %d\n", e->op);
+				ret=-1;
 		}
-		memcpy(re->host.h_addr_list[i], he->h_addr_list[i], he->h_length);
+	}else{
+		LOG(L_CRIT, "BUG: eval_expr: unknown type %d\n", e->type);
+		ret=-1;
 	}
 
-	/* copy h_addr_type & length */
-	re->host.h_addrtype=he->h_addrtype;
-	re->host.h_length=he->h_length;
-	/*finished hostent copy */
+skip:
+	rec_lev--;
+	return ret;
+}
+
+
+
 
+int add_rule(struct expr* e, struct action* a, struct route_elem** head)
+{
 	
-	re->port=cl->port;
-	re->current_addr_idx=0;
-	re->ok=1;
+	struct route_elem* re;
+	struct hostent * he;
+	int ret;
+	int i,len, len2;
 
+	re=init_re();
+	if (re==0) return E_OUT_OF_MEM;
+	LOG(L_DBG, "add_rule: fixing expr...\n");
+	if ((ret=fix_expr(e))!=0) goto error;
+	LOG(L_DBG, "add_rule: fixing actions...\n");
+	if ((ret=fix_action(a))!=0) goto error;
+	re->condition=e;
+	re->actions=a;
+	
 	push(re,head);
 	return 0;
 	
 error:
-		free_re(re);
-		return ret;
+	free_re(re);
+	return ret;
 }
 
 
 
-struct route_elem* route_match(char* method, char* uri, struct route_elem** rl)
+struct route_elem* route_match(struct sip_msg* msg, struct route_elem** rl)
 {
 	struct route_elem* t;
 	if (*rl==0){
@@ -185,13 +390,7 @@ struct route_elem* route_match(char* method, char* uri, struct route_elem** rl)
 		return 0;
 	}
 	for (t=*rl; t; t=t->next){
-		if (regexec(&(t->method), method, 0, 0, 0)==0){
-			/* we have a method mach !!! */
-			if (regexec(&(t->uri), uri, 0, 0, 0)==0){
-				/* we have a full match */
-				return t;
-			}
-		}
+		if (eval_expr(t->condition, msg)==1) return t;
 	}
 	/* no match :( */
 	return 0;
@@ -206,26 +405,17 @@ void print_rl()
 	int i,j;
 
 	if (rlist==0){
-		LOG(L_INFO, "the routing table is empty\n");
+		printf("the routing table is empty\n");
 		return;
 	}
 	
-	for (t=rlist,i=0; t; i++, t=t->next){
-		LOG(L_INFO, "%2d.to=%s ; route ok=%d\n", i,
-				t->host.h_name, t->ok);
-		LOG(L_INFO, "   ips: ");
-		for (j=0; t->host.h_addr_list[j]; j++){
-			LOG(L_INFO, "%d.%d.%d.%d ", 
-				(unsigned char) t->host.h_addr_list[j][0],
-				(unsigned char) t->host.h_addr_list[j][1],
-			    (unsigned char) t->host.h_addr_list[j][2],
-				(unsigned char) t->host.h_addr_list[j][3]
-				  );
-		}
-		LOG(L_INFO, "\n");
-		LOG(L_INFO, "   port:%d\n", (unsigned short)t->port);
-		LOG(L_INFO, "   Statistics: tx=%d, errors=%d, tx_bytes=%d, idx=%d\n",
-				t->tx, t->errors, t->tx_bytes, t->current_addr_idx);
+	for (t=rlist[0],i=0; t; i++, t=t->next){
+		printf("%2d.condition: ");
+		print_expr(t->condition);
+		printf("\n  -> ");
+		print_action(t->actions);
+		printf("\n    Statistics: tx=%d, errors=%d, tx_bytes=%d\n",
+				t->tx, t->errors, t->tx_bytes);
 	}
 
 }

+ 15 - 13
route.h

@@ -9,20 +9,21 @@
 #include <regex.h>
 #include <netdb.h>
 
-#include "cfg_parser.h"
+#include "config.h"
+#include "error.h"
+#include "route_struct.h"
+#include "msg_parser.h"
+
+/*#include "cfg_parser.h" */
+
 
-#define E_OUT_OF_MEM  -2
-#define E_BAD_RE      -3
-#define E_BAD_ADDRESS -4
 
 struct route_elem{
 	struct route_elem* next;
-	regex_t method;
-	regex_t uri;
-	struct hostent host;
-	int current_addr_idx;
-	short int port;
-	short int reserved; /* pad */
+
+	struct expr* condition;
+	struct action* actions;
+
 	int ok; /* set to 0 if an error was found sendig a pkt*/
 	/*counters*/
 	int errors;
@@ -31,15 +32,16 @@ struct route_elem{
 };
 
 /* main "routing table" */
-extern struct route_elem* rlist;
+extern struct route_elem* rlist[RT_NO];
 
 
 void free_re(struct route_elem* re);
 struct route_elem* init_re();
 void push(struct route_elem* re, struct route_elem** head);
 void clear_rlist(struct route_elem** rl);
-int add_rule(struct cfg_line* cl, struct route_elem** head);
-struct route_elem* route_match(char* method, char* uri, struct route_elem** rl);void print_rl();
+int add_rule(struct expr* e, struct action* a, struct route_elem** head);
+struct route_elem* route_match(struct sip_msg* msg,struct route_elem** rl);
+void print_rl();
 
 
 

+ 9 - 0
route_struct.c

@@ -217,6 +217,12 @@ void print_action(struct action* a)
 			case ERROR_T:
 					printf("error(");
 					break;
+			case ROUTE_T:
+					printf("route(");
+					break;
+			case EXEC_T:
+					printf("exec(");
+					break;
 			default:
 					printf("UNKNOWN(");
 		}
@@ -227,6 +233,9 @@ void print_action(struct action* a)
 			case NUMBER_ST:
 					printf("%d",t->p1.number);
 					break;
+			case IP_ST:
+					print_ip(t->p1.data);
+					break;
 			default:
 					printf("type<%d>", t->p1_type);
 		}

+ 2 - 2
route_struct.h

@@ -9,10 +9,10 @@
 enum { EXP_T=1, ELEM_T };
 enum { AND_OP=1, OR_OP, NOT_OP };
 enum { EQUAL_OP=10, MATCH_OP };
-enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O };
+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 { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST };
+enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST };
 
 	
 struct expr{