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