route_struct.c
c07508e2
 /*
  * $Id$
  *
  * route structures helping functions
7dd0b342
  *
  * Copyright (C) 2001-2003 Fhg Fokus
  *
  * This file is part of ser, a free SIP server.
  *
  * ser is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
  * For a license to use the ser software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    info@iptel.org
  *
  * ser is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
e3dccdc9
  */
 /* History:
  * --------
  *  2003-01-29  src_port introduced (jiri)
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
3e8c3475
  *  2003-04-12  FORCE_RPORT_T added (andrei)
6bfaa042
  *  2003-10-02  added SET_ADV_ADDRESS & SET_ADV_PORT (andrei)
1bee75ad
  *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
c07508e2
  */
 
 
7dd0b342
 
c07508e2
 #include  "route_struct.h"
 
 #include <stdio.h>
3e429f5c
 #include <stdlib.h>
e22bbdb8
 #include <string.h>
c07508e2
 
7268726e
 #include "dprint.h"
4e2fdd79
 #include "ip_addr.h"
e3dccdc9
 #include "mem/mem.h"
7268726e
 
03150098
 
c07508e2
 struct expr* mk_exp(int op, struct expr* left, struct expr* right)
 {
 	struct expr * e;
e3dccdc9
 	e=(struct expr*)pkg_malloc(sizeof (struct expr));
c07508e2
 	if (e==0) goto error;
 	e->type=EXP_T;
 	e->op=op;
 	e->l.expr=left;
 	e->r.expr=right;
 	return e;
 error:
7268726e
 	LOG(L_CRIT, "ERROR: mk_exp: memory allocation failure\n");
c07508e2
 	return 0;
 }
 
 
 struct expr* mk_elem(int op, int subtype, int operand, void* param)
 {
 	struct expr * e;
e3dccdc9
 	e=(struct expr*)pkg_malloc(sizeof (struct expr));
c07508e2
 	if (e==0) goto error;
 	e->type=ELEM_T;
 	e->op=op;
 	e->subtype=subtype;
 	e->l.operand=operand;
 	e->r.param=param;
 	return e;
 error:
7268726e
 	LOG(L_CRIT, "ERROR: mk_elem: memory allocation failure\n");
c07508e2
 	return 0;
 }
 
 
 
e3fc93f4
 struct action* mk_action(int type, int p1_type, int p2_type,
 											void* p1, void* p2)
c07508e2
 {
 	struct action* a;
e3dccdc9
 	a=(struct action*)pkg_malloc(sizeof(struct action));
c07508e2
 	if (a==0) goto  error;
3bf76e49
 	memset(a,0,sizeof(struct action));
c07508e2
 	a->type=type;
 	a->p1_type=p1_type;
 	a->p2_type=p2_type;
 	a->p1.string=(char*) p1;
 	a->p2.string=(char*) p2;
 	a->next=0;
 	return a;
 	
 error:
7268726e
 	LOG(L_CRIT, "ERROR: mk_action: memory allocation failure\n");
c07508e2
 	return 0;
 
 }
 
 
f20a56a2
 struct action* mk_action3(int type, int p1_type, int p2_type, int p3_type,
 							void* p1, void* p2, void* p3)
 {
 	struct action* a;
 
 	a=mk_action(type, p1_type, p2_type, p1, p2);
 	if (a){
 			a->p3_type=p3_type;
 			a->p3.data=p3;
 	}
 	return a;
 }
 
 
 
c07508e2
 struct action* append_action(struct action* a, struct action* b)
 {
 	struct action *t;
 	if (b==0) return a;
 	if (a==0) return b;
 	
 	for(t=a;t->next;t=t->next);
 	t->next=b;
 	return a;
 }
 
09e52ebb
 
 
c07508e2
 void print_expr(struct expr* exp)
 {
 	if (exp==0){
7268726e
 		LOG(L_CRIT, "ERROR: print_expr: null expression!\n");
c07508e2
 		return;
 	}
 	if (exp->type==ELEM_T){
 		switch(exp->l.operand){
 			case METHOD_O:
7268726e
 				DBG("method");
c07508e2
 				break;
 			case URI_O:
7268726e
 				DBG("uri");
c07508e2
 				break;
 			case SRCIP_O:
7268726e
 				DBG("srcip");
c07508e2
 				break;
049f64c2
 			case SRCPORT_O:
 				DBG("srcport");
 				break;
c07508e2
 			case DSTIP_O:
7268726e
 				DBG("dstip");
c07508e2
 				break;
f20a56a2
 			case NUMBER_O:
 				break;
 			case ACTION_O:
 				print_action((struct action*) exp->r.param);
 				break;
c07508e2
 			default:
7268726e
 				DBG("UNKNOWN");
c07508e2
 		}
 		switch(exp->op){
 			case EQUAL_OP:
7268726e
 				DBG("==");
c07508e2
 				break;
 			case MATCH_OP:
7268726e
 				DBG("=~");
09e52ebb
 				break;
f20a56a2
 			case NO_OP:
 				break;
c07508e2
 			default:
7268726e
 				DBG("<UNKNOWN>");
c07508e2
 		}
 		switch(exp->subtype){
 			case NOSUBTYPE: 
7268726e
 					DBG("N/A");
c07508e2
 					break;
 			case STRING_ST:
7268726e
 					DBG("\"%s\"", (char*)exp->r.param);
c07508e2
 					break;
 			case NET_ST:
09e52ebb
 					print_net((struct net*)exp->r.param);
 					break;
 			case IP_ST:
9c01c860
 					print_ip("", (struct ip_addr*)exp->r.param, "");
c07508e2
 					break;
f20a56a2
 			case ACTIONS_ST:
 					print_action((struct action*)exp->r.param);
 					break;
 			case NUMBER_ST:
 					DBG("%d",exp->r.intval);
 					break;
855c2e68
 			case MYSELF_ST:
 					DBG("_myself_");
 					break;
c07508e2
 			default:
7268726e
 					DBG("type<%d>", exp->subtype);
c07508e2
 		}
 	}else if (exp->type==EXP_T){
 		switch(exp->op){
 			case AND_OP:
7268726e
 					DBG("AND( ");
c07508e2
 					print_expr(exp->l.expr);
7268726e
 					DBG(", ");
c07508e2
 					print_expr(exp->r.expr);
7268726e
 					DBG(" )");
c07508e2
 					break;
 			case OR_OP:
7268726e
 					DBG("OR( ");
c07508e2
 					print_expr(exp->l.expr);
7268726e
 					DBG(", ");
c07508e2
 					print_expr(exp->r.expr);
7268726e
 					DBG(" )");
c07508e2
 					break;
 			case NOT_OP:	
7268726e
 					DBG("NOT( ");
c07508e2
 					print_expr(exp->l.expr);
7268726e
 					DBG(" )");
c07508e2
 					break;
 			default:
7268726e
 					DBG("UNKNOWN_EXP ");
c07508e2
 		}
 					
 	}else{
7268726e
 		DBG("ERROR:print_expr: unknown type\n");
c07508e2
 	}
 }
 					
 
 					
 
 void print_action(struct action* a)
 {
 	struct action* t;
 	for(t=a; t!=0;t=t->next){
 		switch(t->type){
 			case FORWARD_T:
7268726e
 					DBG("forward(");
c07508e2
 					break;
0c5da34b
 			case FORWARD_TCP_T:
 					DBG("forward_tcp(");
 					break;
f2f969dd
 			case FORWARD_UDP_T:
 					DBG("forward_udp(");
 					break;
c07508e2
 			case SEND_T:
7268726e
 					DBG("send(");
c07508e2
 					break;
0c5da34b
 			case SEND_TCP_T:
 					DBG("send_tcp(");
 					break;
c07508e2
 			case DROP_T:
7268726e
 					DBG("drop(");
c07508e2
 					break;
 			case LOG_T:
7268726e
 					DBG("log(");
c07508e2
 					break;
 			case ERROR_T:
7268726e
 					DBG("error(");
c07508e2
 					break;
a15c363f
 			case ROUTE_T:
7268726e
 					DBG("route(");
a15c363f
 					break;
 			case EXEC_T:
7268726e
 					DBG("exec(");
 					break;
caf80ae6
 			case REVERT_URI_T:
 					DBG("revert_uri(");
 					break;
 			case STRIP_T:
 					DBG("strip(");
 					break;
 			case APPEND_BRANCH_T:
 					DBG("append_branch(");
 					break;
 			case PREFIX_T:
 					DBG("prefix(");
 					break;
 			case LEN_GT_T:
 					DBG("len_gt(");
 					break;
 			case SETFLAG_T:
 					DBG("setflag(");
 					break;
 			case RESETFLAG_T:
 					DBG("resetflag(");
 					break;
 			case ISFLAGSET_T:
 					DBG("isflagset(");
 					break;
7268726e
 			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(");
a15c363f
 					break;
f20a56a2
 			case IF_T:
 					DBG("if (");
 					break;
3bf76e49
 			case MODULE_T:
 					DBG(" external_module_call(");
 					break;
3e8c3475
 			case FORCE_RPORT_T:
 					DBG("force_rport(");
 					break;
6bfaa042
 			case SET_ADV_ADDR_T:
 					DBG("set_advertised_address(");
 					break;
 			case SET_ADV_PORT_T:
 					DBG("set_advertised_port(");
 					break;
59653eb8
 			case FORCE_TCP_ALIAS_T:
 					DBG("force_tcp_alias(");
 					break;
1580c821
 			case LOAD_AVP_T:
 					DBG("load_avp(");
 					break;
1bee75ad
 			case AVP_TO_URI_T:
 					DBG("avp_to_attr");
 					break;
c07508e2
 			default:
7268726e
 					DBG("UNKNOWN(");
c07508e2
 		}
 		switch(t->p1_type){
 			case STRING_ST:
7268726e
 					DBG("\"%s\"", t->p1.string);
c07508e2
 					break;
 			case NUMBER_ST:
b667b278
 					DBG("%lu",t->p1.number);
c07508e2
 					break;
a15c363f
 			case IP_ST:
9c01c860
 					print_ip("", (struct ip_addr*)t->p1.data, "");
a15c363f
 					break;
f20a56a2
 			case EXPR_ST:
 					print_expr((struct expr*)t->p1.data);
 					break;
 			case ACTIONS_ST:
 					print_action((struct action*)t->p1.data);
 					break;
3bf76e49
 			case CMDF_ST:
ea2aa0ad
 					DBG("f_ptr<%p>",t->p1.data);
3bf76e49
 					break;
c07508e2
 			default:
7268726e
 					DBG("type<%d>", t->p1_type);
c07508e2
 		}
f20a56a2
 		if (t->type==IF_T) DBG(") {");
c07508e2
 		switch(t->p2_type){
 			case NOSUBTYPE:
 					break;
 			case STRING_ST:
7268726e
 					DBG(", \"%s\"", t->p2.string);
c07508e2
 					break;
 			case NUMBER_ST:
b667b278
 					DBG(", %lu",t->p2.number);
c07508e2
 					break;
f20a56a2
 			case EXPR_ST:
 					print_expr((struct expr*)t->p2.data);
 					break;
 			case ACTIONS_ST:
 					print_action((struct action*)t->p2.data);
 					break;
c07508e2
 			default:
7268726e
 					DBG(", type<%d>", t->p2_type);
c07508e2
 		}
f20a56a2
 		if (t->type==IF_T) DBG("} else {");
 		switch(t->p3_type){
 			case NOSUBTYPE:
 					break;
 			case STRING_ST:
 					DBG(", \"%s\"", t->p3.string);
 					break;
 			case NUMBER_ST:
b667b278
 					DBG(", %lu",t->p3.number);
f20a56a2
 					break;
 			case EXPR_ST:
 					print_expr((struct expr*)t->p3.data);
 					break;
 			case ACTIONS_ST:
 					print_action((struct action*)t->p3.data);
 					break;
 			default:
 					DBG(", type<%d>", t->p3_type);
 		}
 		if (t->type==IF_T) DBG("}; ");
 		else	DBG("); ");
c07508e2
 	}
 }