Browse code

- still to do action,c

Andrei Pelinescu-Onciul authored on 20/09/2001 17:17:26
Showing 11 changed files
... ...
@@ -11,8 +11,12 @@ depends= $(sources:.c=.d)
11 11
 
12 12
 NAME=sip_router
13 13
 
14
+
14 15
 CC=gcc
15 16
 CFLAGS=-O2
17
+LEX=lex
18
+YACC=bison
19
+YACC_FLAGS=-d
16 20
 # on linux and freebsd keep it empty (e.g. LIBS= )
17 21
 # on solaris add -lxnet (e.g. LIBS= -lxnet)
18 22
 LIBS=
... ...
@@ -23,12 +27,20 @@ MKDEP=gcc -M
23 23
 
24 24
 #implicit rules
25 25
 
26
+
26 27
 %.o:%.c $(ALLDEP)
27 28
 	$(CC) $(CFLAGS) -c $< -o $@
28 29
 
29 30
 %.d: %.c
30 31
 	$(MKDEP) $< >$@
31 32
 
33
+# normal rules
34
+lex.yy.c: cfg.lex $(ALLDEP)
35
+	$(LEX) $<
36
+
37
+cfg.tab.c: cfg.y
38
+	$(YACC) $(YACC_FLAGS) $<
39
+
32 40
 $(NAME): $(objs)
33 41
 	$(CC) $(CFLAGS) $(LIBS) $(objs) -o $(NAME)
34 42
 
... ...
@@ -238,7 +238,7 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
238 238
 	;
239 239
 
240 240
 net4:	ipv4 SLASH ipv4	{ $$=mk_net($1, $3); } 
241
-	| ipv4 SLASH NUMBER {	if (($3>32)|($3<1)){
241
+	| ipv4 SLASH NUMBER {	if (($3>32)|($3<0)){
242 242
 								yyerror("invalid bit number in netmask");
243 243
 								$$=0;
244 244
 							}else{
... ...
@@ -402,8 +402,10 @@ yyerror(char* s)
402 402
 			column, s);
403 403
 }
404 404
 
405
+/*
405 406
 int main(int argc, char ** argv)
406 407
 {
407 408
 	if (yyparse()!=0)
408 409
 		fprintf(stderr, "parsing error\n");
409 410
 }
411
+*/
... ...
@@ -21,4 +21,8 @@
21 21
 /* default number of child processes started */
22 22
 #define CHILD_NO    8
23 23
 
24
+#define RT_NO 10 /* routing tables number */
25
+
26
+#define MAX_REC_LEV 100 /* maximum number of recursive calls */
27
+
24 28
 #endif
25 29
new file mode 100644
... ...
@@ -0,0 +1,14 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef error_h
5
+#define error_h
6
+
7
+#define E_OUT_OF_MEM  -2
8
+#define E_BAD_RE      -3
9
+#define E_BAD_ADDRESS -4
10
+#define E_BUG         -5
11
+
12
+
13
+#endif
... ...
@@ -64,6 +64,8 @@ struct sip_msg{
64 64
 	struct msg_start first_line;
65 65
 	struct via_body via1;
66 66
 	struct via_body via2;
67
+	unsigned int src_ip;
68
+	unsigned int dst_ip;
67 69
 };
68 70
 
69 71
 
70 72
new file mode 100644
... ...
@@ -0,0 +1,143 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * proxy list & assoc. functions
4
+ *
5
+ */
6
+
7
+
8
+#include "proxy.h"
9
+#include "error.h"
10
+
11
+#include <string.h>
12
+
13
+
14
+struct proxy_l* proxies=0;
15
+
16
+
17
+
18
+/* searches for the proxy named 'name', on port 'port'
19
+   returns: pointer to proxy_l on success or 0 if not found */ 
20
+struct proxy_l* find_proxy(char *name, unsigned short port)
21
+{
22
+	struct proxy_l* t;
23
+	for(t=proxies; t; t=t->next)
24
+		if ((strcasecmp(t->name, name)==0) && (t->port==port))
25
+			break;
26
+	return t;
27
+}
28
+
29
+
30
+
31
+/* copies a hostent structure*, returns 0 on success, <0 on error*/
32
+int hostent_cpy(struct hostent *dst, struct hosten* src)
33
+{
34
+	int len, r;
35
+
36
+	/* start copying the host entry.. */
37
+	/* copy h_name */
38
+	len=strlen(src->h_name)+1;
39
+	dst->h_name=(char*)malloc(sizeof(char) * len);
40
+	if (dst->h_name) strncpy(dst->h_name,src->h_name, len);
41
+	else{
42
+		ret=E_OUT_OF_MEM;
43
+		goto error;
44
+	}
45
+
46
+	/* copy h_aliases */
47
+	for (len=0;src->h_aliases[len];len++);
48
+	dst->h_aliases=(char**)malloc(sizeof(char*)*(len+1));
49
+	if (dst->h_aliases==0){
50
+		ret=E_OUT_OF_MEM;
51
+		free(dst->h_name);
52
+		goto error;
53
+	}
54
+	memset((void*)dst->h_aliases, 0, sizeof(char*) * (len+1) );
55
+	for (i=0;i<len;i++){
56
+		len2=strlen(src->h_aliases[i])+1;
57
+		dst->.h_aliases[i]=(char*)malloc(sizeof(char)*len2);
58
+		if (dst->h_aliases==0){
59
+			ret=E_OUT_OF_MEM;
60
+			free(dst->h_name);
61
+			for(r=0; r<i; r++)	free(dst->h_aliases[r]);
62
+			free(dst->h_aliases);
63
+			goto error;
64
+		}
65
+		strncpy(dst->h_aliases[i], src->h_aliases[i], len2);
66
+	}
67
+	/* copy h_addr_list */
68
+	for (len=0;src->h_addr_list[len];len++);
69
+	dst->h_addr_list=(char**)malloc(sizeof(char*)*(len+1));
70
+	if (dst->h_addr_list==0){
71
+		ret=E_OUT_OF_MEM;
72
+		free(dst->h_name);
73
+		for(r=0; h_aliases[r]; r++)	free(dst->h_aliases[r]);
74
+		free h_aliases[r];
75
+		free(dst->h_aliases);
76
+		goto error;
77
+	}
78
+	memset((void*)dst->.h_addr_list, 0, sizeof(char*) * (len+1) );
79
+	for (i=0;i<len;i++){
80
+		dst->h_addr_list[i]=(char*)malloc(sizeof(char)*src->h_length);
81
+		if (dst->h_addr_list[i]==0){
82
+			ret=E_OUT_OF_MEM;
83
+			free(dst->h_name);
84
+			for(r=0; h_aliases[r]; r++)	free(dst->h_aliases[r]);
85
+			free h_aliases[r];
86
+			free(dst->h_aliases);
87
+			for (r=0; r<i;r++) free(dst->h_addr_list[r]);
88
+			free(dst->h_addr_list);
89
+			goto error;
90
+		}
91
+		memcpy(dst->h_addr_list[i], src->h_addr_list[i], src->h_length);
92
+	}
93
+
94
+	/* copy h_addr_type & length */
95
+	dst->h_addrtype=src->h_addrtype;
96
+	dst->host.h_length=src->h_length;
97
+	/*finished hostent copy */
98
+	
99
+	return 0;
100
+
101
+error:
102
+	LOG(L_CRIT, "ERROR: hostent_cpy: memory allocation failure\n");
103
+	return ret;
104
+}
105
+
106
+
107
+
108
+struct proxy_l* add_proxy(char* name, unsigned short port)
109
+{
110
+	proxy_l* p;
111
+	struct hostent he;
112
+	
113
+	if ((p=find_proxy(name, port))!=0) return p;
114
+	p=(struct proxy_l*) malloc(sizeof(struct proxy_l));
115
+	if (p==0){
116
+		LOG(L_CRIT, "ERROR: add_proxy: memory allocation failure\n");
117
+		goto error;
118
+	}
119
+	memset(p,0,sizeof(struct_proxy_l));
120
+	p->name=name;
121
+	p->port=port;
122
+	he=gethostbyname(name);
123
+	if (he==0){
124
+		LOG(L_CRIT, "ERROR: add_proxy: could not resolve hostname:"
125
+					" \"%s\"\n", name);
126
+		free(p);
127
+		goto error;
128
+	}
129
+	if (hostent_cpy(&(p->host), he)!=0){
130
+		free(p);
131
+		goto error;
132
+	}
133
+	p->ok=1;
134
+	/* add p to the proxy list */
135
+	p->next=proxies;
136
+	proxies=p;
137
+	return p;
138
+
139
+error:
140
+	return 0;
141
+}
142
+
0 143
new file mode 100644
... ...
@@ -0,0 +1,32 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ */
4
+
5
+#ifndef proxy_h
6
+#define proxy_h
7
+
8
+#include <netdb.h>
9
+
10
+struct proxy_l{
11
+	struct proxy_l* next;
12
+	char* name; /* original name */
13
+	struct hostent host; /* addresses */
14
+	unsigned short port;
15
+	unsigned short reserved; /*align*/
16
+	
17
+	/* socket ? */
18
+
19
+	int addr_idx;	/* crt. addr. idx. */
20
+	int ok; /* 0 on error */
21
+	/*statisticis*/
22
+	int tx;
23
+	int tx_bytes;
24
+	int errors;
25
+};
26
+
27
+extern struct proxy_l* proxies;
28
+
29
+
30
+#endif
31
+
... ...
@@ -9,20 +9,25 @@
9 9
 #include <regex.h>
10 10
 #include <netdb.h>
11 11
 #include <string.h>
12
+#include <sys/socket.h>
13
+#include <netinet/in.h>
14
+#include <arpa/inet.h>
15
+#include <netdb.h>
12 16
 
13 17
 #include "route.h"
14 18
 #include "cfg_parser.h"
15 19
 #include "dprint.h"
16 20
 
17 21
 /* main routing list */
18
-struct route_elem* rlist=0;
22
+struct route_elem* rlist[RT_NO];
19 23
 
20 24
 
21 25
 
22
-void free_re(struct route_elem* r)
26
+ void free_re(struct route_elem* r)
23 27
 {
24 28
 	int i;
25 29
 	if (r){
30
+		/*
26 31
 			regfree(&(r->method));
27 32
 			regfree(&(r->uri));
28 33
 			
... ...
@@ -37,6 +42,7 @@ void free_re(struct route_elem* r)
37 37
 					free(r->host.h_addr_list[i]);
38 38
 				free(r->host.h_addr_list);
39 39
 			}
40
+		*/
40 41
 			free(r);
41 42
 	}
42 43
 }
... ...
@@ -82,102 +88,301 @@ void clear_rlist(struct route_elem** rl)
82 82
 
83 83
 
84 84
 
85
-int add_rule(struct cfg_line* cl, struct route_elem** head)
85
+/* traverses an expr tree and compiles the REs where necessary) 
86
+ * returns: 0 for ok, <0 if errors */
87
+int fix_expr(struct expr* exp)
86 88
 {
87
-	
88
-	struct route_elem* re;
89
-	struct hostent * he;
89
+	regex_t* re;
90 90
 	int ret;
91
-	int i,len, len2;
91
+	
92
+	if (exp==0){
93
+		LOG(L_CRIT, "BUG: fix_expr: null pointer\n");
94
+		return E_BUG;
95
+	}
96
+	if (exp->type==EXP_T){
97
+		switch(exp->op){
98
+			case AND_OP:
99
+			case OR_OP:
100
+						if ((ret=fix_expr(exp->l.expr))!=0)
101
+							return ret;
102
+						ret=fix_expr(exp->r.expr);
103
+						break;
104
+			case NOT_OP:
105
+						ret=fix_expr(exp->l.expr);
106
+						break;
107
+			default:
108
+						LOG(L_CRIT, "BUG: fix_expr: unknown op %d\n",
109
+								exp->op);
110
+		}
111
+	}else if (exp->type==ELEM_T){
112
+			if (exp->op==MATCH_OP){
113
+				if (exp->subtype==STRING_ST){
114
+					re=(regex_t*)malloc(sizeof(regex_t));
115
+					if (re==0){
116
+						LOG(L_CRIT, "ERROR: fix_expr: memory allocation"
117
+								" failure\n");
118
+						return E_OUT_OF_MEM;
119
+					}
120
+					if (regcomp(re, (char*) exp->r.param,
121
+								REG_EXTENDED|REG_NOSUB|REG_ICASE) ){
122
+						LOG(L_CRIT, "ERROR: fix_expr : bad re \"%s\"\n",
123
+									(char*) exp->r.param);
124
+						free(re);
125
+						return E_BAD_RE;
126
+					}
127
+					/* replace the string with the re */
128
+					free(exp->r.param);
129
+					exp->r.param=re;
130
+					exp->subtype=RE_ST;
131
+				}else if (exp->subtype!=RE_ST){
132
+					LOG(L_CRIT, "BUG: fix_expr : invalid type for match\n");
133
+					return E_BUG;
134
+				}
135
+			}
136
+			ret=0;
137
+	}
138
+	return ret;
139
+}
92 140
 
93 141
 
94
-	re=init_re();
95
-	if (re==0) return E_OUT_OF_MEM;
96 142
 
97
-	if (regcomp(&(re->method), cl->method, REG_EXTENDED|REG_NOSUB|REG_ICASE)){
98
-		LOG(L_CRIT, "ERROR: add_rule: bad re \"%s\"\n", cl->method);
99
-		ret=E_BAD_RE;
100
-		goto error;
101
-	}
102
-	if (regcomp(&(re->uri), cl->uri, REG_EXTENDED|REG_NOSUB|REG_ICASE) ){
103
-		LOG(L_CRIT, "ERROR: add_rule: bad re \"%s\"\n", cl->uri);
104
-		ret=E_BAD_RE;
105
-		goto error;
143
+/* adds the proxies in the proxy list & resolves the hostnames */
144
+int fix_actions(struct action* a)
145
+{
146
+	struct action *t;
147
+	struct proxy* p;
148
+	char *tmp;
149
+	
150
+	for(t=a; t!=0; t=t->next){
151
+		switch(t->type){
152
+			case FORWARD_T:
153
+			case SEND_T:
154
+					switch(t->p1_type){
155
+						case NUMBER_ST:
156
+							tmp=strdup(inet_ntoa(
157
+										*(struct in_addr*)&t->p1.number));
158
+							if (tmp==0){
159
+								LOG(L_CRIT, "ERROR: fix_actions:"
160
+										"memory allocation failure\n");
161
+								return E_OUT_OF_MEM;
162
+							}
163
+							t->p1_type=STRING_ST;
164
+							t->p1.string=tmp;
165
+							/* no break */
166
+						case STRING_ST:
167
+							p=add_proxy(t->p1.string, t->p2.number);
168
+							if (p==0) return E_BAD_ADDRESS;
169
+							t->p1.data=p;
170
+							t->p1_type=PROXY_ST;
171
+							break;
172
+						default:
173
+							LOG(L_CRIT, "BUG: fix_actions: invalid type"
174
+									" (should be string or number)\n");
175
+							return E_BUG;
176
+					}
177
+					break;
178
+		}
106 179
 	}
180
+	return 0;
181
+}
182
+
107 183
 
184
+
185
+/* eval_elem helping function, returns str op param */
186
+int comp_str(char* str, void* param, int op, int subtype)
187
+{
188
+	int ret;
108 189
 	
109
-	he=gethostbyname(cl->address);
110
-	if (he==0){
111
-		LOG(L_CRIT, "ERROR: add_rule: cannot resolve \"%s\"\n", cl->address);
112
-		ret=E_BAD_ADDRESS;
190
+	ret=-1;
191
+	if (op==EQUAL_OP){
192
+		if (subtype!=STRING_ST){
193
+			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
194
+					"string expected\n", subtype);
195
+			goto error;
196
+		}
197
+		ret=(strcasecmp(str, (char*)param)==0);
198
+	}else if (op==MATCH_OP){
199
+		if (subtype!=RE_ST){
200
+			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
201
+					" RE expected\n", subtype);
202
+			goto error;
203
+		}
204
+		ret=(regexec((regex_t*)param, str, 0, 0, 0)==0);
205
+	}else{
206
+		LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op);
113 207
 		goto error;
114 208
 	}
209
+	return ret;
115 210
 	
116
-	/* start copying the host entry.. */
117
-	/* copy h_name */
118
-	len=strlen(he->h_name)+1;
119
-	re->host.h_name=(char*)malloc(sizeof(char) * len);
120
-	if (re->host.h_name) strncpy(re->host.h_name, he->h_name, len);
121
-	else{
122
-		ret=E_OUT_OF_MEM;
123
-		goto error;
211
+error:
212
+	return -1;
213
+}
214
+
215
+
216
+
217
+/* eval_elem helping function, returns a op param */
218
+int comp_ip(unsigned a, void* param, int op, int subtype)
219
+{
220
+	struct hostent* he;
221
+	char ** h;
222
+	int ret;
223
+
224
+	ret=-1;
225
+	switch(subtype){
226
+		case NET_ST:
227
+			ret=(a&((struct net*)param)->mask)==((struct net*)param)->ip;
228
+			break;
229
+		case STRING_ST:
230
+			/* 1: compare with ip2str*/
231
+			ret=comp_str(inet_ntoa(*(struct in_addr*)&a), param, op,
232
+						subtype);
233
+			if (ret==1) break;
234
+			/* 2: (slow) rev dns the address
235
+			 * and compare with all the aliases */
236
+			he=gethostbyaddr(&a, sizeof(a), AF_INET);
237
+			if (he==0){
238
+				LOG(L_DBG, "comp_ip: could not rev_resolve %x\n", a);
239
+				ret=0;
240
+			}else{
241
+				/*  compare with primayry host name */
242
+				ret=comp_str(he->h_name, param, op, subtype);
243
+				/* compare with all the aliases */
244
+				for(h=he->h_aliases; (ret!=1) && (*h); h++){
245
+					ret=comp_str(*h, param, op, subtype);
246
+				}
247
+			}
248
+			break;
249
+		default:
250
+			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
251
+						" src_ip or dst_ip (%d)\n", subtype);
252
+			ret=-1;
124 253
 	}
254
+	return ret;
255
+	
256
+error:
257
+	return -1;
258
+}
259
+
125 260
 
126
-	/* copy h_aliases */
127
-	for (len=0;he->h_aliases[len];len++);
128
-	re->host.h_aliases=(char**)malloc(sizeof(char*)*(len+1));
129
-	if (re->host.h_aliases==0){
130
-		ret=E_OUT_OF_MEM;
261
+
262
+/* returns: 0/1 (false/true) or -1 on error */
263
+int eval_elem(struct expr* e, struct sip_msg* msg)
264
+{
265
+
266
+	int ret;
267
+	
268
+	if (e->type!=ELEM_T){
269
+		LOG(L_CRIT," BUG: eval_elem: invalid type\n");
131 270
 		goto error;
132 271
 	}
133
-	memset((void*)re->host.h_aliases, 0, sizeof(char*) * (len+1) );
134
-	for (i=0;i<len;i++){
135
-		len2=strlen(he->h_aliases[i])+1;
136
-		re->host.h_aliases[i]=(char*)malloc(sizeof(char)*len2);
137
-		if (re->host.h_aliases==0){
138
-			ret=E_OUT_OF_MEM;
139
-			goto error;
140
-		}
141
-		strncpy(re->host.h_aliases[i], he->h_aliases[i], len2);
272
+	switch(e->l.operand){
273
+		case METHOD_O:
274
+				ret=comp_str(msg->first_line.u.request.method, e->r.param,
275
+								e->op, e->subtype);
276
+				break;
277
+		case URI_O:
278
+				ret=comp_str(msg->first_line.u.request.uri, e->r.param,
279
+								e->op, e->subtype);
280
+				break;
281
+		case SRCIP_O:
282
+				ret=comp_ip(msg->src_ip, e->r.param, e->op, e->subtype);
283
+				break;
284
+		case DSTIP_O:
285
+				ret=comp_ip(msg->dst_ip, e->r.param, e->op, e->subtype);
286
+				break;
287
+		case DEFAULT_O:
288
+				ret=1;
289
+				break;
290
+		default:
291
+				LOG(L_CRIT, "BUG: eval_elem: invalid operand %d\n",
292
+							e->l.operand);
142 293
 	}
143
-	/* copy h_addr_list */
144
-	for (len=0;he->h_addr_list[len];len++);
145
-	re->host.h_addr_list=(char**)malloc(sizeof(char*)*(len+1));
146
-	if (re->host.h_addr_list==0){
147
-		ret=E_OUT_OF_MEM;
148
-		goto error;
294
+	return ret;
295
+error:
296
+	return -1;
297
+}
298
+
299
+
300
+
301
+int eval_expr(struct expr* e, struct sip_msg* msg)
302
+{
303
+	static int rec_lev=0;
304
+	int ret;
305
+	
306
+	rec_lev++;
307
+	if (rec_lev>MAX_REC_LEV){
308
+		LOG(L_CRIT, "ERROR: eval_expr: too many expressions (%d)\n",
309
+				rec_lev);
310
+		ret=-1;
311
+		goto skip;
149 312
 	}
150
-	memset((void*)re->host.h_addr_list, 0, sizeof(char*) * (len+1) );
151
-	for (i=0;i<len;i++){
152
-		re->host.h_addr_list[i]=(char*)malloc(sizeof(char)*he->h_length);
153
-		if (re->host.h_addr_list[i]==0){
154
-			ret=E_OUT_OF_MEM;
155
-			goto error;
313
+	
314
+	if (e->type==ELEM_T){
315
+		ret=eval_elem(e, msg);
316
+	}else if (e->type==EXP_T){
317
+		switch(e->op){
318
+			case AND_OP:
319
+				ret=eval_expr(e->l.expr, msg);
320
+				/* if error or false stop evaluating the rest */
321
+				if (ret!=1) break;
322
+				ret=eval_expr(e->r.expr, msg); /*ret1 is 1*/
323
+				break;
324
+			case OR_OP:
325
+				ret=eval_expr(e->l.expr, msg);
326
+				/* if true or error stop evaluating the rest */
327
+				if (ret!=0) break;
328
+				ret=eval_expr(e->r.expr, msg); /* ret1 is 0 */
329
+				break;
330
+			case NOT_OP:
331
+				ret=eval_expr(e->l.expr, msg);
332
+				if (ret<0) break;
333
+				ret= ! ret;
334
+				break;
335
+			default:
336
+				LOG(L_CRIT, "BUG: eval_expr: unknown op %d\n", e->op);
337
+				ret=-1;
156 338
 		}
157
-		memcpy(re->host.h_addr_list[i], he->h_addr_list[i], he->h_length);
339
+	}else{
340
+		LOG(L_CRIT, "BUG: eval_expr: unknown type %d\n", e->type);
341
+		ret=-1;
158 342
 	}
159 343
 
160
-	/* copy h_addr_type & length */
161
-	re->host.h_addrtype=he->h_addrtype;
162
-	re->host.h_length=he->h_length;
163
-	/*finished hostent copy */
344
+skip:
345
+	rec_lev--;
346
+	return ret;
347
+}
348
+
349
+
350
+
164 351
 
352
+int add_rule(struct expr* e, struct action* a, struct route_elem** head)
353
+{
165 354
 	
166
-	re->port=cl->port;
167
-	re->current_addr_idx=0;
168
-	re->ok=1;
355
+	struct route_elem* re;
356
+	struct hostent * he;
357
+	int ret;
358
+	int i,len, len2;
169 359
 
360
+	re=init_re();
361
+	if (re==0) return E_OUT_OF_MEM;
362
+	LOG(L_DBG, "add_rule: fixing expr...\n");
363
+	if ((ret=fix_expr(e))!=0) goto error;
364
+	LOG(L_DBG, "add_rule: fixing actions...\n");
365
+	if ((ret=fix_action(a))!=0) goto error;
366
+	re->condition=e;
367
+	re->actions=a;
368
+	
170 369
 	push(re,head);
171 370
 	return 0;
172 371
 	
173 372
 error:
174
-		free_re(re);
175
-		return ret;
373
+	free_re(re);
374
+	return ret;
176 375
 }
177 376
 
178 377
 
179 378
 
180
-struct route_elem* route_match(char* method, char* uri, struct route_elem** rl)
379
+struct route_elem* route_match(struct sip_msg* msg, struct route_elem** rl)
181 380
 {
182 381
 	struct route_elem* t;
183 382
 	if (*rl==0){
... ...
@@ -185,13 +390,7 @@ struct route_elem* route_match(char* method, char* uri, struct route_elem** rl)
185 185
 		return 0;
186 186
 	}
187 187
 	for (t=*rl; t; t=t->next){
188
-		if (regexec(&(t->method), method, 0, 0, 0)==0){
189
-			/* we have a method mach !!! */
190
-			if (regexec(&(t->uri), uri, 0, 0, 0)==0){
191
-				/* we have a full match */
192
-				return t;
193
-			}
194
-		}
188
+		if (eval_expr(t->condition, msg)==1) return t;
195 189
 	}
196 190
 	/* no match :( */
197 191
 	return 0;
... ...
@@ -206,26 +405,17 @@ void print_rl()
206 206
 	int i,j;
207 207
 
208 208
 	if (rlist==0){
209
-		LOG(L_INFO, "the routing table is empty\n");
209
+		printf("the routing table is empty\n");
210 210
 		return;
211 211
 	}
212 212
 	
213
-	for (t=rlist,i=0; t; i++, t=t->next){
214
-		LOG(L_INFO, "%2d.to=%s ; route ok=%d\n", i,
215
-				t->host.h_name, t->ok);
216
-		LOG(L_INFO, "   ips: ");
217
-		for (j=0; t->host.h_addr_list[j]; j++){
218
-			LOG(L_INFO, "%d.%d.%d.%d ", 
219
-				(unsigned char) t->host.h_addr_list[j][0],
220
-				(unsigned char) t->host.h_addr_list[j][1],
221
-			    (unsigned char) t->host.h_addr_list[j][2],
222
-				(unsigned char) t->host.h_addr_list[j][3]
223
-				  );
224
-		}
225
-		LOG(L_INFO, "\n");
226
-		LOG(L_INFO, "   port:%d\n", (unsigned short)t->port);
227
-		LOG(L_INFO, "   Statistics: tx=%d, errors=%d, tx_bytes=%d, idx=%d\n",
228
-				t->tx, t->errors, t->tx_bytes, t->current_addr_idx);
213
+	for (t=rlist[0],i=0; t; i++, t=t->next){
214
+		printf("%2d.condition: ");
215
+		print_expr(t->condition);
216
+		printf("\n  -> ");
217
+		print_action(t->actions);
218
+		printf("\n    Statistics: tx=%d, errors=%d, tx_bytes=%d\n",
219
+				t->tx, t->errors, t->tx_bytes);
229 220
 	}
230 221
 
231 222
 }
... ...
@@ -9,20 +9,21 @@
9 9
 #include <regex.h>
10 10
 #include <netdb.h>
11 11
 
12
-#include "cfg_parser.h"
12
+#include "config.h"
13
+#include "error.h"
14
+#include "route_struct.h"
15
+#include "msg_parser.h"
16
+
17
+/*#include "cfg_parser.h" */
18
+
13 19
 
14
-#define E_OUT_OF_MEM  -2
15
-#define E_BAD_RE      -3
16
-#define E_BAD_ADDRESS -4
17 20
 
18 21
 struct route_elem{
19 22
 	struct route_elem* next;
20
-	regex_t method;
21
-	regex_t uri;
22
-	struct hostent host;
23
-	int current_addr_idx;
24
-	short int port;
25
-	short int reserved; /* pad */
23
+
24
+	struct expr* condition;
25
+	struct action* actions;
26
+
26 27
 	int ok; /* set to 0 if an error was found sendig a pkt*/
27 28
 	/*counters*/
28 29
 	int errors;
... ...
@@ -31,15 +32,16 @@ struct route_elem{
31 31
 };
32 32
 
33 33
 /* main "routing table" */
34
-extern struct route_elem* rlist;
34
+extern struct route_elem* rlist[RT_NO];
35 35
 
36 36
 
37 37
 void free_re(struct route_elem* re);
38 38
 struct route_elem* init_re();
39 39
 void push(struct route_elem* re, struct route_elem** head);
40 40
 void clear_rlist(struct route_elem** rl);
41
-int add_rule(struct cfg_line* cl, struct route_elem** head);
42
-struct route_elem* route_match(char* method, char* uri, struct route_elem** rl);void print_rl();
41
+int add_rule(struct expr* e, struct action* a, struct route_elem** head);
42
+struct route_elem* route_match(struct sip_msg* msg,struct route_elem** rl);
43
+void print_rl();
43 44
 
44 45
 
45 46
 
... ...
@@ -217,6 +217,12 @@ void print_action(struct action* a)
217 217
 			case ERROR_T:
218 218
 					printf("error(");
219 219
 					break;
220
+			case ROUTE_T:
221
+					printf("route(");
222
+					break;
223
+			case EXEC_T:
224
+					printf("exec(");
225
+					break;
220 226
 			default:
221 227
 					printf("UNKNOWN(");
222 228
 		}
... ...
@@ -227,6 +233,9 @@ void print_action(struct action* a)
227 227
 			case NUMBER_ST:
228 228
 					printf("%d",t->p1.number);
229 229
 					break;
230
+			case IP_ST:
231
+					print_ip(t->p1.data);
232
+					break;
230 233
 			default:
231 234
 					printf("type<%d>", t->p1_type);
232 235
 		}
... ...
@@ -9,10 +9,10 @@
9 9
 enum { EXP_T=1, ELEM_T };
10 10
 enum { AND_OP=1, OR_OP, NOT_OP };
11 11
 enum { EQUAL_OP=10, MATCH_OP };
12
-enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O };
12
+enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O };
13 13
 
14 14
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T};
15
-enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST };
15
+enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST };
16 16
 
17 17
 	
18 18
 struct expr{