/src/kamailio/src/core/route_struct.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * route structures helping functions |
3 | | * |
4 | | * Copyright (C) 2001-2003 FhG Fokus |
5 | | * |
6 | | * This file is part of Kamailio, a free SIP server. |
7 | | * |
8 | | * Kamailio is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 2 of the License, or |
11 | | * (at your option) any later version |
12 | | * |
13 | | * Kamailio is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | */ |
22 | | |
23 | | /*! |
24 | | * \file |
25 | | * \brief Kamailio core :: route structures helping functions |
26 | | * \ingroup core |
27 | | * Module: \ref core |
28 | | */ |
29 | | |
30 | | |
31 | | #include "route_struct.h" |
32 | | |
33 | | #include <stdio.h> |
34 | | #include <stdlib.h> |
35 | | #include <string.h> |
36 | | #include <stdarg.h> |
37 | | |
38 | | #include "dprint.h" |
39 | | #include "ip_addr.h" |
40 | | #include "mem/mem.h" |
41 | | #include "usr_avp.h" |
42 | | #include "ut.h" /* ZSW() */ |
43 | | |
44 | | |
45 | | /** joins to cfg file positions into a new one. */ |
46 | | void cfg_pos_join( |
47 | | struct cfg_pos *res, struct cfg_pos *pos1, struct cfg_pos *pos2) |
48 | 0 | { |
49 | 0 | struct cfg_pos ret; |
50 | 0 | ret = *pos1; |
51 | 0 | if((ret.s_line == 0) || (ret.s_line > pos2->s_line)) { |
52 | 0 | ret.s_line = pos2->s_line; |
53 | 0 | ret.s_col = pos2->s_col; |
54 | 0 | } else if((ret.s_line == pos2->s_line) && (ret.s_col > pos2->s_col)) { |
55 | 0 | ret.s_col = pos2->s_col; |
56 | 0 | } |
57 | 0 | if((ret.e_line == 0) || (ret.e_line < pos2->e_line)) { |
58 | 0 | ret.e_line = pos2->e_line; |
59 | 0 | ret.e_col = pos2->e_col; |
60 | 0 | } else if((ret.e_line == pos2->e_line) && (ret.e_col < pos2->e_col)) { |
61 | 0 | ret.e_col = pos2->e_col; |
62 | 0 | } |
63 | 0 | *res = ret; |
64 | 0 | } |
65 | | |
66 | | |
67 | | struct expr *mk_exp(int op, struct expr *left, struct expr *right) |
68 | 0 | { |
69 | 0 | struct expr *e; |
70 | 0 | e = (struct expr *)pkg_malloc(sizeof(struct expr)); |
71 | 0 | if(e == 0) |
72 | 0 | goto error; |
73 | 0 | e->type = EXP_T; |
74 | 0 | e->op = op; |
75 | 0 | e->l.expr = left; |
76 | 0 | e->r.expr = right; |
77 | 0 | return e; |
78 | 0 | error: |
79 | 0 | PKG_MEM_CRITICAL; |
80 | 0 | return 0; |
81 | 0 | } |
82 | | |
83 | | |
84 | | struct expr *mk_elem(int op, expr_l_type ltype, void *lparam, expr_r_type rtype, |
85 | | void *rparam) |
86 | 0 | { |
87 | 0 | struct expr *e; |
88 | 0 | e = (struct expr *)pkg_malloc(sizeof(struct expr)); |
89 | 0 | if(e == 0) |
90 | 0 | goto error; |
91 | 0 | e->type = ELEM_T; |
92 | 0 | e->op = op; |
93 | 0 | e->l_type = ltype; |
94 | 0 | e->l.param = lparam; |
95 | 0 | e->r_type = rtype; |
96 | 0 | e->r.param = rparam; |
97 | 0 | return e; |
98 | 0 | error: |
99 | 0 | PKG_MEM_CRITICAL; |
100 | 0 | return 0; |
101 | 0 | } |
102 | | |
103 | | |
104 | | /** create an action structure (parser use). |
105 | | * @param type - type of the action |
106 | | * @param count - count of couples {param_type,val} |
107 | | * @param ... - count {param_type, val} pairs, where param_type is |
108 | | * action_param_type. |
109 | | * @return new action structure on success (pkg_malloc'ed) or 0 on error. |
110 | | */ |
111 | | struct action *mk_action(enum action_type type, int count, ...) |
112 | 0 | { |
113 | 0 | va_list args; |
114 | 0 | int i; |
115 | 0 | struct action *a; |
116 | |
|
117 | 0 | a = (struct action *)pkg_malloc(sizeof(struct action)); |
118 | 0 | if(a == 0) |
119 | 0 | goto error; |
120 | 0 | memset(a, 0, sizeof(struct action)); |
121 | 0 | a->type = type; |
122 | 0 | a->count = (count > MAX_ACTIONS) ? MAX_ACTIONS : count; |
123 | |
|
124 | 0 | va_start(args, count); |
125 | 0 | for(i = 0; i < a->count; i++) { |
126 | 0 | a->val[i].type = va_arg(args, int); |
127 | 0 | a->val[i].u.data = va_arg(args, void *); |
128 | 0 | DBG("ACTION type%d, i/count %d/%d: type %d(%x)/ data %p\n", a->type, i, |
129 | 0 | a->count, a->val[i].type, a->val[i].type, a->val[i].u.data); |
130 | 0 | } |
131 | 0 | va_end(args); |
132 | |
|
133 | 0 | a->next = 0; |
134 | 0 | return a; |
135 | | |
136 | 0 | error: |
137 | 0 | PKG_MEM_CRITICAL; |
138 | 0 | return 0; |
139 | 0 | } |
140 | | |
141 | | |
142 | | struct action *append_action(struct action *a, struct action *b) |
143 | 0 | { |
144 | 0 | struct action *t; |
145 | 0 | if(b == 0) |
146 | 0 | return a; |
147 | 0 | if(a == 0) |
148 | 0 | return b; |
149 | | |
150 | 0 | for(t = a; t->next; t = t->next) |
151 | 0 | ; |
152 | 0 | t->next = b; |
153 | 0 | return a; |
154 | 0 | } |
155 | | |
156 | | |
157 | | void print_expr(struct expr *exp) |
158 | 0 | { |
159 | 0 | if(exp == 0) { |
160 | 0 | LM_CRIT("null expression!\n"); |
161 | 0 | return; |
162 | 0 | } |
163 | 0 | if(exp->type == ELEM_T) { |
164 | 0 | switch(exp->l_type) { |
165 | 0 | case METHOD_O: |
166 | 0 | DBG("method"); |
167 | 0 | break; |
168 | 0 | case URI_O: |
169 | 0 | DBG("uri"); |
170 | 0 | break; |
171 | 0 | case FROM_URI_O: |
172 | 0 | DBG("from_uri"); |
173 | 0 | break; |
174 | 0 | case TO_URI_O: |
175 | 0 | DBG("to_uri"); |
176 | 0 | break; |
177 | 0 | case SRCIP_O: |
178 | 0 | DBG("srcip"); |
179 | 0 | break; |
180 | 0 | case SRCPORT_O: |
181 | 0 | DBG("srcport"); |
182 | 0 | break; |
183 | 0 | case DSTIP_O: |
184 | 0 | DBG("dstip"); |
185 | 0 | break; |
186 | 0 | case DSTPORT_O: |
187 | 0 | DBG("dstport"); |
188 | 0 | break; |
189 | 0 | case PROTO_O: |
190 | 0 | DBG("proto"); |
191 | 0 | break; |
192 | 0 | case AF_O: |
193 | 0 | DBG("af"); |
194 | 0 | break; |
195 | 0 | case MSGLEN_O: |
196 | 0 | DBG("msglen"); |
197 | 0 | break; |
198 | 0 | case ACTION_O: |
199 | 0 | break; |
200 | 0 | case NUMBER_O: |
201 | 0 | break; |
202 | 0 | case AVP_O: |
203 | 0 | DBG("avp"); |
204 | 0 | break; |
205 | 0 | case SNDIP_O: |
206 | 0 | DBG("sndip"); |
207 | 0 | break; |
208 | 0 | case SNDPORT_O: |
209 | 0 | DBG("sndport"); |
210 | 0 | break; |
211 | 0 | case TOIP_O: |
212 | 0 | DBG("toip"); |
213 | 0 | break; |
214 | 0 | case TOPORT_O: |
215 | 0 | DBG("toport"); |
216 | 0 | break; |
217 | 0 | case SNDPROTO_O: |
218 | 0 | DBG("sndproto"); |
219 | 0 | break; |
220 | 0 | case SNDAF_O: |
221 | 0 | DBG("sndaf"); |
222 | 0 | break; |
223 | 0 | case RETCODE_O: |
224 | 0 | DBG("retcode"); |
225 | 0 | break; |
226 | 0 | case SELECT_O: |
227 | 0 | DBG("select"); |
228 | 0 | break; |
229 | 0 | case RVEXP_O: |
230 | 0 | DBG("rval"); |
231 | 0 | break; |
232 | | |
233 | 0 | default: |
234 | 0 | DBG("UNKNOWN"); |
235 | 0 | } |
236 | 0 | switch(exp->op) { |
237 | 0 | case EQUAL_OP: |
238 | 0 | DBG("=="); |
239 | 0 | break; |
240 | 0 | case MATCH_OP: |
241 | 0 | DBG("=~"); |
242 | 0 | break; |
243 | 0 | case NO_OP: |
244 | 0 | break; |
245 | 0 | case GT_OP: |
246 | 0 | DBG(">"); |
247 | 0 | break; |
248 | 0 | case GTE_OP: |
249 | 0 | DBG(">="); |
250 | 0 | break; |
251 | 0 | case LT_OP: |
252 | 0 | DBG("<"); |
253 | 0 | break; |
254 | 0 | case LTE_OP: |
255 | 0 | DBG("<="); |
256 | 0 | break; |
257 | 0 | case DIFF_OP: |
258 | 0 | DBG("!="); |
259 | 0 | break; |
260 | 0 | default: |
261 | 0 | DBG("<UNKNOWN>"); |
262 | 0 | } |
263 | 0 | switch(exp->r_type) { |
264 | 0 | case NOSUBTYPE: |
265 | 0 | DBG("N/A"); |
266 | 0 | break; |
267 | 0 | case STRING_ST: |
268 | 0 | DBG("\"%s\"", ZSW((char *)exp->r.param)); |
269 | 0 | break; |
270 | 0 | case NET_ST: |
271 | 0 | print_net((struct net *)exp->r.param); |
272 | 0 | break; |
273 | 0 | case IP_ST: |
274 | 0 | print_ip("", (struct ip_addr *)exp->r.param, ""); |
275 | 0 | break; |
276 | 0 | case ACTIONS_ST: |
277 | 0 | print_actions((struct action *)exp->r.param); |
278 | 0 | break; |
279 | 0 | case NUMBER_ST: |
280 | 0 | DBG("%ld", exp->r.numval); |
281 | 0 | break; |
282 | 0 | case MYSELF_ST: |
283 | 0 | DBG("_myself_"); |
284 | 0 | break; |
285 | 0 | case AVP_ST: |
286 | 0 | DBG("attr"); |
287 | 0 | break; |
288 | 0 | case SELECT_ST: |
289 | 0 | DBG("select"); |
290 | 0 | break; |
291 | 0 | default: |
292 | 0 | DBG("type<%d>", exp->r_type); |
293 | 0 | } |
294 | 0 | } else if(exp->type == EXP_T) { |
295 | 0 | switch(exp->op) { |
296 | 0 | case LOGAND_OP: |
297 | 0 | DBG("AND( "); |
298 | 0 | print_expr(exp->l.expr); |
299 | 0 | DBG(", "); |
300 | 0 | print_expr(exp->r.expr); |
301 | 0 | DBG(" )"); |
302 | 0 | break; |
303 | 0 | case LOGOR_OP: |
304 | 0 | DBG("OR( "); |
305 | 0 | print_expr(exp->l.expr); |
306 | 0 | DBG(", "); |
307 | 0 | print_expr(exp->r.expr); |
308 | 0 | DBG(" )"); |
309 | 0 | break; |
310 | 0 | case NOT_OP: |
311 | 0 | DBG("NOT( "); |
312 | 0 | print_expr(exp->l.expr); |
313 | 0 | DBG(" )"); |
314 | 0 | break; |
315 | 0 | default: |
316 | 0 | DBG("UNKNOWN_EXP "); |
317 | 0 | } |
318 | |
|
319 | 0 | } else { |
320 | 0 | DBG("ERROR:print_expr: unknown type\n"); |
321 | 0 | } |
322 | 0 | } |
323 | | |
324 | | |
325 | | void print_action(struct action *t) |
326 | 0 | { |
327 | 0 | switch(t->type) { |
328 | 0 | case FORWARD_T: |
329 | 0 | DBG("forward("); |
330 | 0 | break; |
331 | 0 | case FORWARD_TCP_T: |
332 | 0 | DBG("forward_tcp("); |
333 | 0 | break; |
334 | 0 | case FORWARD_UDP_T: |
335 | 0 | DBG("forward_udp("); |
336 | 0 | break; |
337 | 0 | case DROP_T: |
338 | 0 | DBG("drop("); |
339 | 0 | break; |
340 | 0 | case LOG_T: |
341 | 0 | DBG("log("); |
342 | 0 | break; |
343 | 0 | case ERROR_T: |
344 | 0 | DBG("error("); |
345 | 0 | break; |
346 | 0 | case ROUTE_T: |
347 | 0 | DBG("route("); |
348 | 0 | break; |
349 | 0 | case EXEC_T: |
350 | 0 | DBG("exec("); |
351 | 0 | break; |
352 | 0 | case REVERT_URI_T: |
353 | 0 | DBG("revert_uri("); |
354 | 0 | break; |
355 | 0 | case STRIP_T: |
356 | 0 | DBG("strip("); |
357 | 0 | break; |
358 | 0 | case APPEND_BRANCH_T: |
359 | 0 | DBG("append_branch("); |
360 | 0 | break; |
361 | 0 | case PREFIX_T: |
362 | 0 | DBG("prefix("); |
363 | 0 | break; |
364 | 0 | case LEN_GT_T: |
365 | 0 | DBG("len_gt("); |
366 | 0 | break; |
367 | 0 | case SETFLAG_T: |
368 | 0 | DBG("setflag("); |
369 | 0 | break; |
370 | 0 | case RESETFLAG_T: |
371 | 0 | DBG("resetflag("); |
372 | 0 | break; |
373 | 0 | case ISFLAGSET_T: |
374 | 0 | DBG("isflagset("); |
375 | 0 | break; |
376 | 0 | case AVPFLAG_OPER_T: |
377 | 0 | DBG("avpflagoper("); |
378 | 0 | break; |
379 | 0 | case SET_HOST_T: |
380 | 0 | DBG("sethost("); |
381 | 0 | break; |
382 | 0 | case SET_HOSTPORT_T: |
383 | 0 | DBG("sethostport("); |
384 | 0 | break; |
385 | 0 | case SET_HOSTPORTTRANS_T: |
386 | 0 | DBG("sethostporttrans("); |
387 | 0 | break; |
388 | 0 | case SET_USER_T: |
389 | 0 | DBG("setuser("); |
390 | 0 | break; |
391 | 0 | case SET_USERPASS_T: |
392 | 0 | DBG("setuserpass("); |
393 | 0 | break; |
394 | 0 | case SET_PORT_T: |
395 | 0 | DBG("setport("); |
396 | 0 | break; |
397 | 0 | case SET_URI_T: |
398 | 0 | DBG("seturi("); |
399 | 0 | break; |
400 | 0 | case IF_T: |
401 | 0 | DBG("if ("); |
402 | 0 | break; |
403 | 0 | case MODULE0_T: |
404 | 0 | case MODULE1_T: |
405 | 0 | case MODULE2_T: |
406 | 0 | case MODULE3_T: |
407 | 0 | case MODULE4_T: |
408 | 0 | case MODULE5_T: |
409 | 0 | case MODULE6_T: |
410 | 0 | case MODULEX_T: |
411 | 0 | case MODULE1_RVE_T: |
412 | 0 | case MODULE2_RVE_T: |
413 | 0 | case MODULE3_RVE_T: |
414 | 0 | case MODULE4_RVE_T: |
415 | 0 | case MODULE5_RVE_T: |
416 | 0 | case MODULE6_RVE_T: |
417 | 0 | case MODULEX_RVE_T: |
418 | 0 | DBG(" external_module_call("); |
419 | 0 | break; |
420 | 0 | case FORCE_RPORT_T: |
421 | 0 | DBG("force_rport("); |
422 | 0 | break; |
423 | 0 | case SET_ADV_ADDR_T: |
424 | 0 | DBG("set_advertised_address("); |
425 | 0 | break; |
426 | 0 | case SET_ADV_PORT_T: |
427 | 0 | DBG("set_advertised_port("); |
428 | 0 | break; |
429 | 0 | case FORCE_TCP_ALIAS_T: |
430 | 0 | DBG("force_tcp_alias("); |
431 | 0 | break; |
432 | 0 | case LOAD_AVP_T: |
433 | 0 | DBG("load_avp("); |
434 | 0 | break; |
435 | 0 | case AVP_TO_URI_T: |
436 | 0 | DBG("avp_to_attr"); |
437 | 0 | break; |
438 | 0 | case FORCE_SEND_SOCKET_T: |
439 | 0 | DBG("force_send_socket"); |
440 | 0 | break; |
441 | 0 | case ASSIGN_T: |
442 | 0 | DBG("assign("); |
443 | 0 | break; |
444 | 0 | case ADD_T: |
445 | 0 | DBG("assign_add("); |
446 | 0 | break; |
447 | 0 | default: |
448 | 0 | DBG("UNKNOWN("); |
449 | 0 | } |
450 | 0 | switch(t->val[0].type) { |
451 | 0 | case STRING_ST: |
452 | 0 | DBG("\"%s\"", ZSW(t->val[0].u.string)); |
453 | 0 | break; |
454 | 0 | case NUMBER_ST: |
455 | 0 | DBG("%lu", t->val[0].u.number); |
456 | 0 | break; |
457 | 0 | case IP_ST: |
458 | 0 | print_ip("", (struct ip_addr *)t->val[0].u.data, ""); |
459 | 0 | break; |
460 | 0 | case EXPR_ST: |
461 | 0 | print_expr((struct expr *)t->val[0].u.data); |
462 | 0 | break; |
463 | 0 | case ACTIONS_ST: |
464 | 0 | print_actions((struct action *)t->val[0].u.data); |
465 | 0 | break; |
466 | 0 | case MODEXP_ST: |
467 | 0 | DBG("f_ptr<%p>", t->val[0].u.data); |
468 | 0 | break; |
469 | 0 | case SOCKID_ST: |
470 | 0 | DBG("%d:%s:%d", ((struct socket_id *)t->val[0].u.data)->proto, |
471 | 0 | ZSW(((struct socket_id *)t->val[0].u.data)->addr_lst->name), |
472 | 0 | ((struct socket_id *)t->val[0].u.data)->port); |
473 | 0 | break; |
474 | 0 | case AVP_ST: |
475 | 0 | DBG("avp(%u,%.*s)", t->val[0].u.attr->type, |
476 | 0 | t->val[0].u.attr->name.s.len, |
477 | 0 | ZSW(t->val[0].u.attr->name.s.s)); |
478 | 0 | break; |
479 | 0 | case SELECT_ST: |
480 | 0 | DBG("select"); |
481 | 0 | break; |
482 | 0 | default: |
483 | 0 | DBG("type<%d>", t->val[0].type); |
484 | 0 | } |
485 | 0 | if(t->type == IF_T) |
486 | 0 | DBG(") {"); |
487 | 0 | switch(t->val[1].type) { |
488 | 0 | case NOSUBTYPE: |
489 | 0 | break; |
490 | 0 | case STRING_ST: |
491 | 0 | DBG(", \"%s\"", ZSW(t->val[1].u.string)); |
492 | 0 | break; |
493 | 0 | case NUMBER_ST: |
494 | 0 | DBG(", %lu", t->val[1].u.number); |
495 | 0 | break; |
496 | 0 | case EXPR_ST: |
497 | 0 | print_expr((struct expr *)t->val[1].u.data); |
498 | 0 | break; |
499 | 0 | case ACTION_ST: |
500 | 0 | case ACTIONS_ST: |
501 | 0 | print_actions((struct action *)t->val[1].u.data); |
502 | 0 | break; |
503 | | |
504 | 0 | case SOCKID_ST: |
505 | 0 | DBG("%d:%s:%d", ((struct socket_id *)t->val[0].u.data)->proto, |
506 | 0 | ZSW(((struct socket_id *)t->val[0].u.data)->addr_lst->name), |
507 | 0 | ((struct socket_id *)t->val[0].u.data)->port); |
508 | 0 | break; |
509 | 0 | case AVP_ST: |
510 | 0 | DBG(", avp(%u,%.*s)", t->val[1].u.attr->type, |
511 | 0 | t->val[1].u.attr->name.s.len, |
512 | 0 | ZSW(t->val[1].u.attr->name.s.s)); |
513 | 0 | break; |
514 | 0 | case SELECT_ST: |
515 | 0 | DBG("select"); |
516 | 0 | break; |
517 | 0 | default: |
518 | 0 | DBG(", type<%d>", t->val[1].type); |
519 | 0 | } |
520 | 0 | if(t->type == IF_T) |
521 | 0 | DBG("} else {"); |
522 | 0 | switch(t->val[2].type) { |
523 | 0 | case NOSUBTYPE: |
524 | 0 | break; |
525 | 0 | case STRING_ST: |
526 | 0 | DBG(", \"%s\"", ZSW(t->val[2].u.string)); |
527 | 0 | break; |
528 | 0 | case NUMBER_ST: |
529 | 0 | DBG(", %lu", t->val[2].u.number); |
530 | 0 | break; |
531 | 0 | case EXPR_ST: |
532 | 0 | print_expr((struct expr *)t->val[2].u.data); |
533 | 0 | break; |
534 | 0 | case ACTIONS_ST: |
535 | 0 | print_actions((struct action *)t->val[2].u.data); |
536 | 0 | break; |
537 | 0 | case SOCKID_ST: |
538 | 0 | DBG("%d:%s:%d", ((struct socket_id *)t->val[0].u.data)->proto, |
539 | 0 | ZSW(((struct socket_id *)t->val[0].u.data)->addr_lst->name), |
540 | 0 | ((struct socket_id *)t->val[0].u.data)->port); |
541 | 0 | break; |
542 | 0 | default: |
543 | 0 | DBG(", type<%d>", t->val[2].type); |
544 | 0 | } |
545 | 0 | if(t->type == IF_T) |
546 | 0 | DBG("}; "); |
547 | 0 | else |
548 | 0 | DBG("); "); |
549 | 0 | } |
550 | | |
551 | | void print_actions(struct action *a) |
552 | 0 | { |
553 | 0 | while(a) { |
554 | 0 | print_action(a); |
555 | 0 | a = a->next; |
556 | 0 | } |
557 | 0 | } |
558 | | |
559 | | /** |
560 | | * get the pointer to action structure from parameter |
561 | | */ |
562 | | struct action *get_action_from_param(void **param, int param_no) |
563 | 0 | { |
564 | 0 | cfg_action_t *ac; |
565 | 0 | action_u_t *au; |
566 | | /* param points to au->u.string, get pointer to au */ |
567 | 0 | au = ksr_container_of(param, action_u_t, u.string); |
568 | 0 | au = au - 1 - param_no; |
569 | | /* au points to ac->val, get pointer to ac */ |
570 | 0 | ac = ksr_container_of(au, cfg_action_t, val); |
571 | 0 | return ac; |
572 | 0 | } |