static int fixup_stat(void** param, int param_no) { struct stat_or_pv *sopv; str s; long n; int err; s.s = (char*)*param; s.len = strlen(s.s); if (param_no==1) { /* var name - string or pv */ sopv = (struct stat_or_pv *)pkg_malloc(sizeof(struct stat_or_pv)); if (sopv==NULL) { LM_ERR("no more pkg mem\n"); return E_OUT_OF_MEM; } memset( sopv, 0 , sizeof(struct stat_or_pv) ); /* is it pv? */ if (s.s[0]=='$') { if (fixup_pvar(param)!=0) { LM_ERR("invalid pv %.s as parameter\n",s.s); return E_CFG; } sopv->pv = (pv_spec_t*)(*param); } else { /* it is string */ sopv->stat = get_stat( &s ); if (sopv->stat==0) { LM_ERR("variable <%s> not defined\n", s.s); return E_CFG; } } pkg_free(s.s); *param=(void*)sopv; return 0; } else if (param_no==2) { /* update value - integer */ if (s.s[0]=='-' || s.s[0]=='+') { n = str2s( s.s+1, s.len-1, &err); if (s.s[0]=='-') n = -n; } else { n = str2s( s.s, s.len, &err); } if (err==0){ if (n==0) { LM_ERR("update with 0 has no sense\n"); return E_CFG; } pkg_free(*param); *param=(void*)n; return 0; }else{ LM_ERR("bad update number <%s>\n",(char*)(*param)); return E_CFG; } } return 0; }
// checks the size of the SIM memory int check_memory(struct modem *mdm, int flag) { char answer[500]; char* posi; int laenge; int err,foo; int j, out; for(out=0,j=0;!out && j<10; j++) { if (put_command(mdm,"AT+CPMS?\r",9,answer,sizeof(answer),50,0) && (posi=strstr(answer,"+CPMS:"))!=0 ) { // Modem supports CPMS command. Read memory size if ( (posi=strchr(posi,','))!=0 ) { posi++; if ( (laenge=strcspn(posi,",\r"))!=0 ) { if (flag==USED_MEM ) { foo = str2s(posi,laenge,&err); if (err) { LM_ERR("failed to convert into integer used_memory" " from CPMS response\n"); } else { return foo; } } posi+=laenge+1; if ( (laenge=strcspn(posi,",\r"))!=0 ) { foo = str2s(posi,laenge,&err); if (err) { LM_ERR("failed to convert into integer max_memory" " from CPMS response\n"); } else { return foo; } } } } /* if(strstr) */ } /* if(put_command) */ /* if we are here -> some error happened */ if (checkmodem(mdm)!=0) { LM_WARN("something happened with the modem -> was re-init -> let's retry\n"); } else { LM_ERR("modem seems to be ok, but we had an error? I give up!\n"); out = 1; } } /* for */ if (out==0) LM_ERR("modem does not respond after 10 retries, give up!\n"); return -1; }
static int fixup_maxfwd_header(void** param, int param_no) { unsigned long code; int err; if (param_no==1){ code=str2s(*param, strlen(*param), &err); if (err==0){ if (code<1 || code>MAXFWD_UPPER_LIMIT){ LM_ERR("invalid MAXFWD number <%ld> [1,%d]\n", code,MAXFWD_UPPER_LIMIT); return E_UNSPEC; } if (code>max_limit) { LM_ERR("default value <%ld> bigger than max limit(%d)\n", code, max_limit); return E_UNSPEC; } pkg_free(*param); *param=(void*)code; return 0; }else{ LM_ERR("bad number <%s>\n",(char*)(*param)); return E_UNSPEC; } } return 0; }
int set_network_arg(struct network *net, char *arg, char *arg_end) { int err,foo; if (*(arg+1)!='=') { LM_ERR("invalid parameter syntax near [=]\n"); goto error; } switch (*arg) { case 'm': /* maximum sms per one call */ foo=str2s(arg+2,arg_end-arg-2,&err); if (err) { LM_ERR("cannot convert [m] arg to integer!\n"); goto error; } net->max_sms_per_call = foo; break; default: LM_ERR("unknown param name [%c]\n",*arg); goto error; } return 1; error: return -1; }
/* looks for the MAX FORWARDS header returns the its value, -1 if is not present or -2 for error */ int is_maxfwd_present( struct sip_msg* msg , str *foo) { int x, err; /* lookup into the message for MAX FORWARDS header*/ if ( !msg->maxforwards ) { if ( parse_headers( msg , HDR_MAXFORWARDS_F, 0 )==-1 ){ LOG( L_ERR , "ERROR:maxfwd:is_maxfwd_present :" " parsing MAX_FORWARD header failed!\n"); return -2; } if (!msg->maxforwards) { DBG("DEBUG: is_maxfwd_present: max_forwards header not found!\n"); return -1; } } /* if header is present, trim to get only the string containing numbers */ trim_len( foo->len , foo->s , msg->maxforwards->body ); /* convert from string to number */ x = str2s( foo->s,foo->len,&err); if (err){ LOG(L_ERR, "ERROR:maxfwd:is_maxfwd_present:" " unable to parse the max forwards number !\n"); return -2; } DBG("DEBUG:maxfwd:is_maxfwd_present: value = %d \n",x); return x; }
int fixup_var_str_int(void **param, int param_no) { unsigned long go_to; int ret; pv_elem_t *model; str s; if (param_no == 1) { model = NULL; s.s = (char *)(*param); s.len = strlen(s.s); if (pv_parse_format(&s, &model) < 0) { LM_ERR("wrong format[%s]!\n", (char *)(*param)); return E_UNSPEC; } if (model == NULL) { LM_ERR("empty parameter!\n"); return E_UNSPEC; } *param = (void *)model; } else if (param_no == 2) { go_to = str2s(*param, strlen(*param), &ret); if (ret == 0) { pkg_free(*param); *param = (void *)go_to; } else { LM_ERR("bad number <%s>\n", (char *)(*param)); return E_CFG; } } return 0; }
/**************************************************************************** * * Function: GetIP(char * iface) * * Purpose: To return a string representing the IP address for an interface * * Arguments: char * iface - The network interface you want to find an IP * address for. * * Returns: A char * -- make sure you call free on this when you are done * with it. * ***************************************************************************/ char *GetIP(char * iface) { struct ifreq ifr; struct sockaddr_in *addr; int s; if(iface) { /* Set up a dummy socket just so we can use ioctl to find the ip address of the interface */ s = socket(PF_INET, SOCK_DGRAM, 0); if(s == -1) { FatalError("Problem establishing socket to find IP address for interface: %s\n", iface); } strncpy(ifr.ifr_name, iface, strlen(iface) + 1); #ifndef WIN32 if(ioctl(s, SIOCGIFADDR, &ifr) < 0) return NULL; else #endif { addr = (struct sockaddr_in *) &ifr.ifr_broadaddr; } close(s); return str2s(inet_ntoa(addr->sin_addr)); } else { return "unknown"; } }
static int fixup_maxfwd_header(void** param, int param_no) { unsigned long code; int err; if (param_no==1){ code=str2s(*param, strlen(*param), &err); if (err==0){ if (code>255){ LOG(L_ERR, "ERROR:maxfwd:fixup_maxfwd_header: " "number to big <%ld> (max=255)\n",code); return E_UNSPEC; } if ( max_limit && code>max_limit) { LOG(L_ERR, "ERROR:maxfwd:fixup_maxfwd_header: " "default value <%ld> bigger than max limit(%d)\n", code, max_limit); return E_UNSPEC; } pkg_free(*param); *param=(void*)code; return 0; }else{ LOG(L_ERR, "ERROR:maxfwd:fixup_maxfwd_header: bad number <%s>\n", (char*)(*param)); return E_UNSPEC; } } return 0; }
static int attr_equals_xl(struct sip_msg* msg, char* p1, char* format) { avp_ident_t* avpid; avp_value_t avp_val; struct search_state st; str xl_val; avp_t* avp; avpid = &((fparam_t*)p1)->v.avp; if (xl_printstr(msg, (xl_elog_t*) format, &xl_val.s, &xl_val.len) > 0) { for (avp = search_avp(*avpid, &avp_val, &st); avp; avp = search_next_avp(&st, &avp_val)) { if (avp->flags & AVP_VAL_STR) { if ((avp_val.s.len == xl_val.len) && !memcmp(avp_val.s.s, xl_val.s, avp_val.s.len)) return 1; } else { if (avp_val.n == str2s(xl_val.s, xl_val.len, 0)) return 1; } } return -1; } ERR("avp_equals_xl:Error while expanding xl_format\n"); return -1; }
/* looks for the MAX FORWARDS header * returns its value, -1 if is not present or -2 for error */ int is_maxfwd_present( struct sip_msg* msg , str *foo) { int x, err; /* lookup into the message for MAX FORWARDS header*/ if ( !msg->maxforwards ) { if ( parse_headers( msg , HDR_MAXFORWARDS_F, 0 )==-1 ){ LM_ERR("parsing MAX_FORWARD header failed!\n"); return -2; } if (!msg->maxforwards) { LM_DBG("max_forwards header not found!\n"); return -1; } } else if (IS_MAXWD_STORED(msg)) { trim_len( foo->len , foo->s , msg->maxforwards->body ); return FETCH_MAXWD_VAL(msg); } /* if header is present, trim to get only the string containing numbers */ trim_len( foo->len , foo->s , msg->maxforwards->body ); /* convert from string to number */ x = str2s( foo->s,foo->len,&err); if (err){ LM_ERR("unable to parse the max forwards number\n"); return -2; } /* store the parsed values */ STORE_MAXWD_VAL(msg, x); LM_DBG("value = %d \n",x); return x; }
int get_nr_max(char *s, unsigned char *max) { unsigned short nr; int err; if ( s[0]=='*' && s[1]==0 ) { /* is '*' -> infinit ;-) */ *max = 0; return 0; } else { /* must be a positive number less than 255 */ nr = str2s(s, strlen(s), &err); if (err==0){ if (nr>255){ LM_ERR("number too big <%d> (max=255)\n",nr); return -1; } *max = (unsigned char)nr; return 0; }else{ LM_ERR("bad number <%s>\n",s); return -1; } } }
/** Get the FR_{INV}_TIMER from corresponding AVP. * @return 0 on success (use *timer) or 1 on failure (avp non-existent, * avp present but empty/0, avp value not numeric). */ static inline int avp2timer(unsigned int* timer, int type, int_str name) { struct usr_avp *avp; int_str val_istr; int err; avp = search_first_avp(type, name, &val_istr, 0); if (!avp) { /* DBG("avp2timer: AVP '%.*s' not found\n", param.s->len, ZSW(param.s->s)); */ return 1; } if (avp->flags & AVP_VAL_STR) { *timer = str2s(val_istr.s.s, val_istr.s.len, &err); if (err) { LOG(L_ERR, "avp2timer: Error while converting string to integer\n"); return -1; } } else { *timer = val_istr.n; } return *timer==0; /* 1 if 0 (use default), 0 if !=0 (use *timer) */ }
/* fixes flag params (resolves possible named flags) * use PARAM_USE_FUNC|PARAM_STRING as a param. type and create * a wrapper function that does just: * return fix_flag(type, val, "my_module", "my_param", &flag_var) * see also param_func_t. */ int fix_flag( modparam_t type, void* val, char* mod_name, char* param_name, int* flag) { int num; int err; int f, len; char* s; char *p; if ((type & PARAM_STRING)==0){ LM_CRIT("%s: fix_flag(%s): bad parameter type\n", mod_name, param_name); return -1; } s=(char*)val; len=strlen(s); f=-1; /* try to see if it's a number */ num = str2s(s, len, &err); if (err != 0) { /* see if it's in the name:<no> format */ p=strchr(s, ':'); if (p){ f= str2s(p+1, strlen(p+1), &err); if (err!=0){ LM_ERR("%s: invalid %s format: \"%s\"", mod_name, param_name, s); return -1; } *p=0; } if ((num=get_flag_no(s, len))<0){ /* not declared yet, declare it */ num=register_flag(s, f); } if (num<0){ LM_ERR("%s: bad %s %s\n", mod_name, param_name, s); return -1; } else if ((f>0) && (num!=f)){ LM_ERR("%s: flag %s already defined" " as %d (and not %d), using %s:%d\n", mod_name, s, num, f, s, num); } } *flag=num; return 0; }
int update_sock_struct_from_via( union sockaddr_union* to, struct sip_msg* msg, struct via_body* via ) { struct hostent* he; str* name; int err; unsigned short port; port=0; if(via==msg->via1){ /* _local_ reply, we ignore any rport or received value * (but we will send back to the original port if rport is * present) */ if ((msg->msg_flags&FL_FORCE_RPORT)||(via->rport)) port=msg->rcv.src_port; else port=via->port; if(via->maddr) name= &(via->maddr->value); else name=&(via->host); /* received=ip in 1st via is ignored (it's not added by us so it's bad) */ }else{ /* "normal" reply, we use rport's & received value if present */ if (via->rport && via->rport->value.s){ LM_DBG("using 'rport'\n"); port=str2s(via->rport->value.s, via->rport->value.len, &err); if (err){ LM_NOTICE("bad rport value(%.*s)\n", via->rport->value.len,via->rport->value.s); port=0; } } if (via->maddr){ name= &(via->maddr->value); if (port==0) port=via->port?via->port:SIP_PORT; } else if (via->received){ LM_DBG("using 'received'\n"); name=&(via->received->value); /* making sure that we won't do SRV lookup on "received" */ if (port==0) port=via->port?via->port:SIP_PORT; }else{ LM_DBG("using via host\n"); name=&(via->host); if (port==0) port=via->port; } } LM_DBG("trying SRV lookup\n"); he=sip_resolvehost(name, &port, &via->proto, 0, 0); if (he==0){ LM_NOTICE("resolve_host(%.*s) failure\n", name->len, name->s); return -1; } hostent2su( to, he, 0, port); return 1; }
/* on digicom the return value can be != sim */ static int fetchsms(struct modem *mdm, int sim, char* pdu) { char command[16]; char answer[512]; char* position; char* beginning; char* end; int foo,err; int clen; // Digicom reports date+time only with AT+CMGL if (mdm->mode==MODE_DIGICOM) { put_command(mdm,"AT+CMGL=\"ALL\"\r",14,answer, sizeof(answer),200,0); /* search for beginning of the answer */ position=strstr(answer,"+CMGL: "); if (position) { end=position+7; while (*end<'9' && *end>'0') end++; if (end==position+7) { foo = str2s(position+7,end-position-7,&err); if (!err) { LM_DBG("found a message at memory %i\n",foo); sim=foo; } position = 0; } position = 0; } } else { LM_DBG("trying to get stored message %i\n",sim); clen=sprintf(command,"AT+CMGR=%i\r",sim); put_command(mdm,command,clen,answer,sizeof(answer),50,0); /* search for beginning of the answer */ position=strstr(answer,"+CMGR:"); } /* keine SMS empfangen, weil Modem nicht mit +CMGR oder +CMGL geantwortet hat */ if (position==0) return 0; beginning=position+7; /* keine SMS, weil Modem mit +CMGR: 0,,0 geantwortet hat */ if (strstr(answer,",,0\r")) return 0; /* After that we have the PDU or ASCII string */ for( end=beginning ; *end && *end!='\r' ; end++ ); if ( !*end || end-beginning<4) return 0; for( end=end+1 ; *end && *end!='\r' ; end++ ); if ( !*end || end-beginning<4) return 0; /* Now we have the end of the PDU or ASCII string */ *end=0; strcpy(pdu,beginning); return sim; }
int update_sock_struct_from_via( union sockaddr_union* to, struct sip_msg* msg, struct via_body* via ) { struct hostent* he; str* name; int err; unsigned short port; char proto; port=0; if(via==msg->via1){ /* _local_ reply, we ignore any rport or received value * (but we will send back to the original port if rport is * present) */ if ((msg->msg_flags&FL_FORCE_RPORT)||(via->rport)) port=msg->rcv.src_port; else port=via->port; name=&(via->host); /* received=ip in 1st via is ignored (it's * not added by us so it's bad) */ }else{ /* "normal" reply, we use rport's & received value if present */ if (via->rport && via->rport->value.s){ LM_DBG("using 'rport'\n"); port=str2s(via->rport->value.s, via->rport->value.len, &err); if (err){ LM_ERR("bad rport value(%.*s)\n", via->rport->value.len, via->rport->value.s); port=0; } } if (via->received){ LM_DBG("using 'received'\n"); name=&(via->received->value); /* making sure that we won't do SRV lookup on "received" * (possible if no DNS_IP_HACK is used)*/ if (port==0) port=via->port?via->port:SIP_PORT; }else{ LM_DBG("using via host\n"); name=&(via->host); if (port==0) port=via->port; } } /* we do now a malloc/memcpy because gethostbyname loves \0-terminated * strings; but only if host is not null terminated (host.s[len] will * always be ok for a via) */ LM_DBG("trying SRV lookup\n"); proto=via->proto; he=sip_resolvehost(name, &port, &proto); if (he==0){ LM_NOTICE("resolve_host(%.*s) failure\n", name->len, name->s); return -1; } hostent2su(to, he, 0, port); return 1; }
static union sockaddr_union *jsonrpc_get_dst(str *ip_port) { static union sockaddr_union _su; struct hostent *hentity; char *p, bk; str host; str port; int iport; int err; if (!ip_port || !ip_port->len) { LM_ERR("no IP:port specified!\n"); return NULL; } /* search for the port */ p = memchr(ip_port->s, ':', ip_port->len); if (!p) { LM_ERR("invalid IP:port %.*s\n", ip_port->len, ip_port->s); return NULL; } host.s = ip_port->s; host.len = p - ip_port->s; /* remaining should be port */ port.s = p + 1; port.len = ip_port->len - (host.len + 1/* : */); trim(&port); iport = str2s(port.s, port.len, &err); if (iport <= 0 || err != 0 || iport > 65535) { LM_ERR("Invalid port specified [%.*s]\n", port.len, port.s); return NULL; } trim(&host); /* null terminate host */ bk = host.s[host.len]; host.s[host.len] = 0; hentity = resolvehost(host.s, 0); host.s[host.len] = bk; if (!hentity) { LM_ERR("cannot resolve host %s\n", host.s); return NULL; } if(hostent2su(&_su, hentity, 0, iport)){ LM_ERR("failed to resolve %s\n", host.s); return NULL; } return &_su; }
int mod_register(char *path, int *dlflags, void *p1, void *p2) { str dest = {0}; int ret = 0; struct sip_uri next_hop, *u; char *p; if(_km_log_engine_type==0 || _km_log_engine_data==0) return 0; if(strcasecmp(_km_log_engine_type, "udp")!=0) return 0; dest.s = _km_log_engine_data; dest.len = strlen(dest.s); init_dest_info(&_lc_udp_dst); u = &next_hop; u->port_no = 5060; u->host = dest; p = dest.s; /* detect ipv6 */ p = memchr(p, ']', dest.len); if (p) p++; else p = dest.s; p = memchr(p, ':', dest.len - (p - dest.s)); if (p) { u->host.len = p - dest.s; p++; u->port_no = str2s(p, dest.len - (p - dest.s), NULL); } ret = sip_hostport2su(&_lc_udp_dst.to, &u->host, u->port_no, &_lc_udp_dst.proto); if(ret!=0) { LM_ERR("failed to resolve [%.*s]\n", u->host.len, ZSW(u->host.s)); return -1; } sr_kemi_modules_add(sr_kemi_log_custom_exports); return 0; }
static int ds_fixup(void** param, int param_no) { long n; int err; if(param_no==1 || param_no==2) { n = str2s(*param, strlen(*param), &err); if (err == 0) { pkg_free(*param); *param=(void*)n; } else { LOG(L_ERR, "DISPATCHER:ds_fixup: Bad number <%s>\n", (char*)(*param)); return E_UNSPEC; } } return 0; }
static int fixup_sl_send_reply(void** param, int param_no) { unsigned long code; int err; if (param_no==1){ code=str2s(*param, strlen(*param), &err); if (err==0){ pkg_free(*param); *param=(void*)code; return 0; }else{ LOG(L_ERR, "SL module:fixup_sl_send_reply: bad number <%s>\n", (char*)(*param)); return E_UNSPEC; } } return 0; }
inline static int fixup_str2int( void** param, int param_no) { unsigned long go_to; int err; if (param_no==1) { go_to=str2s(*param, strlen(*param), &err ); if (err==0) { pkg_free(*param); *param=(void *)go_to; return 0; } else { LOG(L_ERR, "ERROR: fixup_str2int: bad number <%s>\n", (char *)(*param)); return E_CFG; } } return 0; }
inline static int fixup_hostport2proxy(void** param, int param_no) { unsigned int port; char *host; int err; struct proxy_l *proxy; str s; DBG("TM module: fixup_t_forward(%s, %d)\n", (char*)*param, param_no); if (param_no==1){ DBG("TM module: fixup_t_forward: param 1.. do nothing, wait for #2\n"); return 0; } else if (param_no==2) { host=(char *) (*(param-1)); port=str2s(*param, strlen(*param), &err); if (err!=0) { LOG(L_ERR, "TM module:fixup_t_forward: bad port number <%s>\n", (char*)(*param)); return E_UNSPEC; } s.s = host; s.len = strlen(host); proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */ if (proxy==0) { LOG(L_ERR, "ERROR: fixup_t_forwardv6: bad host name in URI <%s>\n", host ); return E_BAD_ADDRESS; } /* success -- fix the first parameter to proxy now ! */ /* FIXME: janakj, mk_proxy doesn't make copy of host !! */ /*pkg_free( *(param-1)); you're right --andrei*/ *(param-1)=proxy; return 0; } else { LOG(L_ERR, "ERROR: fixup_t_forwardv6 called with parameter #<>{1,2}\n"); return E_BUG; } }
/* looks for the MAX FORWARDS header returns the its value, -1 if is not present or -2 for error */ int is_maxfwd_present( struct sip_msg* msg , str *foo) { int x, err; /* hey man, run -Wall before committing ... -jiri char c; */ /* lookup into the message for MAX FORWARDS header*/ if ( !msg->maxforwards ) { DBG("DEBUG : is_maxfwd_present: searching for max_forwards header\n"); if ( parse_headers( msg , HDR_MAXFORWARDS, 0 )==-1 ){ LOG( L_ERR , "ERROR: is_maxfwd_present :" " parsing MAX_FORWARD header failed!\n"); return -2; } if (!msg->maxforwards) { DBG("DEBUG: is_maxfwd_present: max_forwards header not found!\n"); return -1; } }else{ DBG("DEBUG : is_maxfwd_present: max_forward header already found!\n"); } /* if header is present, trim to get only the string containing numbers */ trim_len( foo->len , foo->s , msg->maxforwards->body ); /* convert from string to number */ x = str2s( foo->s,foo->len,&err); if (err){ LOG(L_ERR, "ERROR: is_maxfwd_zero :" " unable to parse the max forwards number !\n"); return -2; } if (x > 255){ LOG(L_NOTICE, "is_maxfwd_present: value %d decreased to 255\n", x); x = 255; } DBG("DEBUG: is_maxfwd_present: value = %d \n",x); return x; }
/* (char *hostname, char *port_nr) ==> (struct proxy_l *, -) */ static int fixup_hostport2proxy(void** param, int param_no) { unsigned int port; char *host; int err; struct proxy_l *proxy; action_u_t *a; str s; DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no); if (param_no==1){ return 0; } else if (param_no==2) { a = fixup_get_param(param, param_no, 1); host= a->u.string; port=str2s(*param, strlen(*param), &err); if (err!=0) { LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n", (char*)(*param)); return E_UNSPEC; } s.s = host; s.len = strlen(host); proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */ if (proxy==0) { LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n", host ); return E_BAD_ADDRESS; } /* success -- fix the first parameter to proxy now ! */ a->u.data=proxy; return 0; } else { LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n"); return E_BUG; } }
char* parse_hostport(char* buf, str* host, short int* port) { char *tmp; int err; host->s=buf; for(tmp=buf;(*tmp)&&(*tmp!=':');tmp++); host->len=tmp-buf; if (*tmp==0) { *port=0; } else { *tmp=0; *port=str2s((unsigned char*)(tmp+1), strlen(tmp+1), &err); if (err ){ LOG(L_INFO, "ERROR: hostport: trailing chars in port number: %s\n", tmp+1); /* report error? */ } } return host->s; }
/* * returns 1 if msg contains an AVP with the given name and value, * returns -1 otherwise */ static int attr_equals(struct sip_msg* msg, char* p1, char* p2) { avp_ident_t avpid; int_str value, avp_value; avp_t* avp; struct search_state st; if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) { return -1; } if (p2 && get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) { ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig); return -1; } avp = search_avp(avpid, &avp_value, &st); if (avp == 0) return -1; if (!p2) return 1; while (avp != 0) { if (avp->flags & AVP_VAL_STR) { if ((avp_value.s.len == value.s.len) && !memcmp(avp_value.s.s, value.s.s, avp_value.s.len)) { return 1; } } else { if (avp_value.n == str2s(value.s.s, value.s.len, 0)) { return 1; } } avp = search_next_avp(&st, &avp_value); } return -1; }
/** Initializes seas module. It first parses the listen_sockets parameter * which has the form "ip_address[:port]", creates the pipe to * communicate with the dispatcher. */ static int seas_init(void) { char *p,*port; struct hostent *he; struct socket_info *si; int c_pipe[2],mierr,i; /** Populate seas_functions*/ if (load_tm_api(&seas_f.tmb)!=0) { LM_ERR( "can't load TM API\n"); return -1; } if(!(seas_f.t_check_orig_trans = find_export("t_check_trans", 0, 0))){ LM_ERR( "Seas requires transaction module (t_check_trans not found)\n"); return -1; } /** Populate seas_functions*/ c_pipe[0]=c_pipe[1]=-1; p=seas_listen_socket; port=(char *)0; seas_listen_port=5080; /*if the seas_listen_socket configuration string is empty, use default values*/ if(p==NULL || *p==0){ si=get_first_socket(); seas_listen_ip=&si->address; } else {/*if config string is not empty, then try to find host first, and maybe port..*/ while(*p){ if(*p == ':'){ *p=0; port=p+1; break; } p++; } if(!(he=resolvehost(seas_listen_socket,0))) goto error; if(!(seas_listen_ip=pkg_malloc(sizeof(struct ip_addr)))) goto error; hostent2ip_addr(seas_listen_ip, he, 0); if(port!=(char *)0 && (seas_listen_port=str2s(port,strlen(port),&mierr))==0){ LM_ERR("invalid port %s \n",port); goto error; } } memset(unc_as_t,0,2*MAX_UNC_AS_NR*sizeof(struct unc_as));//useless because unc_as_t is in bss? if (pipe(c_pipe)==-1) { LM_ERR("cannot create pipe!\n"); goto error; } read_pipe=c_pipe[0]; write_pipe=c_pipe[1]; seas_init_tags(); if(0>start_stats_server(seas_stats_socket)) goto error; if(0>prepare_ha()) goto error; if(0>parse_cluster_cfg()) goto error; return 0; error: for(i=0;i<2;i++) if(c_pipe[i]!=-1) close(c_pipe[i]); if(seas_listen_ip!=0) pkg_free(seas_listen_ip); if(use_stats) stop_stats_server(); return -1; }
/* * call it with a vb initialized to 0 * returns: pointer after the parsed parts and sets vb->error * WARNING: don't forget to cleanup on error with free_via_list(vb)! */ char* parse_via(char* buffer, char* end, struct via_body *vbody) { char* tmp; char* param_start; unsigned char state; unsigned char saved_state; int c_nest; int err; struct via_body* vb; struct via_param* param; vb=vbody; /* keep orignal vbody value, needed to set the error member in case of multiple via bodies in the same header */ parse_again: vb->error=PARSE_ERROR; /* parse start of via ( SIP/2.0/UDP )*/ state=F_SIP; saved_state=0; /*it should generate error if it's used without set*/ param_start=0; for(tmp=buffer;tmp<end;tmp++){ switch(*tmp){ case ' ': case'\t': switch(state){ case L_VER: /* eat space */ case L_PROTO: case F_SIP: case F_VER: case F_PROTO: break; case FIN_UDP: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_UDP; state=F_HOST; /* start looking for host*/ goto main_via; case FIN_TCP: /* finished proto parsing */ vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_TCP; state=F_HOST; /* start looking for host*/ goto main_via; case FIN_TLS: /* finished proto parsing */ vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_TLS; state=F_HOST; /* start looking for host*/ goto main_via; case FIN_SCTP: /* finished proto parsing */ vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_SCTP; state=F_HOST; /* start looking for host*/ goto main_via; case OTHER_PROTO: /* finished proto parsing */ vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_OTHER; state=F_HOST; /* start looking for host*/ goto main_via; case FIN_SIP: vb->name.len=tmp-vb->name.s; state=L_VER; break; case FIN_VER: vb->version.len=tmp-vb->version.s; state=L_PROTO; break; case F_LF: case F_CRLF: case F_CR: /* header continues on this line */ state=saved_state; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case '\n': switch(state){ case L_VER: case F_SIP: case F_VER: case F_PROTO: case L_PROTO: saved_state=state; state=F_LF; break; case FIN_UDP: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_UDP; state=F_LF; saved_state=F_HOST; /* start looking for host*/ goto main_via; case FIN_TCP: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_TCP; state=F_LF; saved_state=F_HOST; /* start looking for host*/ goto main_via; case FIN_TLS: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_TLS; state=F_LF; saved_state=F_HOST; /* start looking for host*/ goto main_via; case OTHER_PROTO: /* finished proto parsing */ vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_OTHER; state=F_LF; saved_state=F_HOST; /* start looking for host*/ goto main_via; case FIN_SIP: vb->name.len=tmp-vb->name.s; state=F_LF; saved_state=L_VER; break; case FIN_VER: vb->version.len=tmp-vb->version.s; state=F_LF; saved_state=L_PROTO; break; case F_CR: state=F_CRLF; break; case F_LF: case F_CRLF: state=saved_state; goto endofheader; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case '\r': switch(state){ case L_VER: case F_SIP: case F_VER: case F_PROTO: case L_PROTO: saved_state=state; state=F_CR; break; case FIN_UDP: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_UDP; state=F_CR; saved_state=F_HOST; goto main_via; case FIN_TCP: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_TCP; state=F_CR; saved_state=F_HOST; goto main_via; case FIN_TLS: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_TLS; state=F_CR; saved_state=F_HOST; goto main_via; case OTHER_PROTO: vb->transport.len=tmp-vb->transport.s; vb->proto=PROTO_OTHER; state=F_CR; saved_state=F_HOST; goto main_via; case FIN_SIP: vb->name.len=tmp-vb->name.s; state=F_CR; saved_state=L_VER; break; case FIN_VER: vb->version.len=tmp-vb->version.s; state=F_CR; saved_state=L_PROTO; break; case F_LF: /*end of line ?next header?*/ case F_CR: case F_CRLF: state=saved_state; goto endofheader; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case '/': switch(state){ case FIN_SIP: vb->name.len=tmp-vb->name.s; state=F_VER; break; case FIN_VER: vb->version.len=tmp-vb->version.s; state=F_PROTO; break; case L_VER: state=F_VER; break; case L_PROTO: state=F_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; /* match SIP*/ case 'S': case 's': switch(state){ case F_SIP: state=SIP1; vb->name.s=tmp; break; case TLS2: state=FIN_TLS; break; case F_PROTO: state=SCTP1; vb->transport.s=tmp; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'I': case 'i': switch(state){ case SIP1: state=SIP2; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'p': case 'P': switch(state){ case SIP2: state=FIN_SIP; break; /* allow p in PROTO */ case UDP2: state=FIN_UDP; break; case TCP2: state=FIN_TCP; break; case SCTP3: state=FIN_SCTP; break; case OTHER_PROTO: break; case UDP1: case FIN_UDP: case TCP_TLS1: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'U': case 'u': switch(state){ case F_PROTO: state=UDP1; vb->transport.s=tmp; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'D': case 'd': switch(state){ case UDP1: state=UDP2; break; case OTHER_PROTO: break; case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'T': case 't': switch(state){ case F_PROTO: state=TCP_TLS1; vb->transport.s=tmp; break; case SCTP2: state=SCTP3; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'C': case 'c': switch(state){ case TCP_TLS1: state=TCP2; break; case SCTP1: state=SCTP2; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case 'L': case 'l': switch(state){ case TCP_TLS1: state=TLS2; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; /*match 2.0*/ case '2': switch(state){ case F_VER: state=VER1; vb->version.s=tmp; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case '.': switch(state){ case VER1: state=VER2; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; case '0': switch(state){ case VER2: state=FIN_VER; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; default: switch(state){ case F_PROTO: state=OTHER_PROTO; vb->transport.s=tmp; break; case OTHER_PROTO: break; case UDP1: case UDP2: case FIN_UDP: case TCP_TLS1: case TCP2: case FIN_TCP: case TLS2: case FIN_TLS: case SCTP1: case SCTP2: case SCTP3: case FIN_SCTP: state=OTHER_PROTO; break; default: LM_ERR("bad char <%c> on state %d\n", *tmp, state); goto parse_error; } break; } } /* for tmp*/ /* we should not be here! if everything is ok > main_via*/ LM_ERR("bad via: end of packet on state=%d\n", state); goto parse_error; main_via: /* inc tmp to point to the next char*/ tmp++; c_nest=0; /*state should always be F_HOST here*/; for(;*tmp;tmp++){ switch(*tmp){ case ' ': case '\t': switch(state){ case F_HOST:/*eat the spaces*/ break; case P_HOST: /*mark end of host*/ vb->host.len=tmp-vb->host.s; state=L_PORT; break; case L_PORT: /*eat the spaces*/ case F_PORT: break; case P_PORT: /*end of port */ vb->port_str.len=tmp-vb->port_str.s; state=L_PARAM; break; case L_PARAM: /* eat the space */ case F_PARAM: break; case P_PARAM: /* *tmp=0;*/ /*!?end of param*/ state=L_PARAM; break; case L_VIA: case F_VIA: /* eat the space */ break; case F_COMMENT: case P_COMMENT: break; case F_IP6HOST: /*no spaces allowed*/ case P_IP6HOST: LM_ERR("bad ipv6 reference\n"); goto parse_error; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now =' '*/ state=saved_state; break; default: LM_CRIT("on <%c>, state=%d\n",*tmp, state); goto parse_error; } break; case '\n': switch(state){ case F_HOST:/*eat the spaces*/ case L_PORT: /*eat the spaces*/ case F_PORT: case L_PARAM: /* eat the space */ case F_PARAM: case F_VIA: /* eat the space */ case L_VIA: case F_COMMENT: case P_COMMENT: case F_IP6HOST: case P_IP6HOST: saved_state=state; state=F_LF; break; case P_HOST: /*mark end of host*/ vb->host.len=tmp-vb->host.s; saved_state=L_PORT; state=F_LF; break; case P_PORT: /*end of port */ vb->port_str.len=tmp-vb->port_str.s; saved_state=L_PARAM; state=F_LF; break; case P_PARAM: /* *tmp=0;*/ /*!?end of param*/ saved_state=L_PARAM; state=F_LF; break; case F_CR: state=F_CRLF; break; case F_CRLF: case F_LF: state=saved_state; goto endofheader; default: LM_CRIT("BUG on <%c>\n",*tmp); goto parse_error; } break; case '\r': switch(state){ case F_HOST:/*eat the spaces*/ case L_PORT: /*eat the spaces*/ case F_PORT: case L_PARAM: /* eat the space */ case F_PARAM: case F_VIA: /* eat the space */ case L_VIA: case F_COMMENT: case P_COMMENT: case F_IP6HOST: case P_IP6HOST: saved_state=state; state=F_CR; break; case P_HOST: /*mark end of host*/ vb->host.len=tmp-vb->host.s; saved_state=L_PORT; state=F_CR; break; case P_PORT: /*end of port */ vb->port_str.len=tmp-vb->port_str.s; saved_state=L_PARAM; state=F_CR; break; case P_PARAM: /* *tmp=0;*/ /*!?end of param*/ saved_state=L_PARAM; state=F_CR; break; case F_CRLF: case F_CR: case F_LF: state=saved_state; goto endofheader; default: LM_CRIT("on <%c>\n",*tmp); goto parse_error; } break; case ':': switch(state){ case F_HOST: case F_IP6HOST: state=P_IP6HOST; break; case P_IP6HOST: break; case P_HOST: /*mark end of host*/ vb->host.len=tmp-vb->host.s; state=F_PORT; break; case L_PORT: state=F_PORT; break; case P_PORT: LM_ERR("bad port\n"); goto parse_error; case L_PARAM: case F_PARAM: case P_PARAM: LM_ERR("bad char <%c> in state %d\n", *tmp,state); goto parse_error; case L_VIA: case F_VIA: LM_ERR("bad char in compact via\n"); goto parse_error; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; case F_COMMENT:/*everything is allowed in a comment*/ vb->comment.s=tmp; state=P_COMMENT; break; case P_COMMENT: /*everything is allowed in a comment*/ break; default: LM_CRIT("on <%c> state %d\n", *tmp, state); goto parse_error; } break; case ';': switch(state){ case F_HOST: case F_IP6HOST: LM_ERR(" no host found\n"); goto parse_error; case P_IP6HOST: LM_ERR(" bad ipv6 reference\n"); goto parse_error; case P_HOST: vb->host.len=tmp-vb->host.s; state=F_PARAM; param_start=tmp+1; break; case P_PORT: /*mark the end*/ vb->port_str.len=tmp-vb->port_str.s; case L_PORT: case L_PARAM: state=F_PARAM; param_start=tmp+1; break; case F_PORT: LM_ERR(" bad char <%c> in state %d\n", *tmp,state); goto parse_error; case F_PARAM: LM_ERR("null param?\n"); goto parse_error; case P_PARAM: /*hmm next, param?*/ state=F_PARAM; param_start=tmp+1; break; case L_VIA: case F_VIA: LM_ERR("bad char <%c> in next via\n", *tmp); goto parse_error; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; case F_COMMENT:/*everything is allowed in a comment*/ vb->comment.s=tmp; state=P_COMMENT; break; case P_COMMENT: /*everything is allowed in a comment*/ break; default: LM_CRIT("on <%c> state %d\n", *tmp, state); goto parse_error; } break; case ',': switch(state){ case F_HOST: case F_IP6HOST: LM_ERR("no host found\n"); goto parse_error; case P_IP6HOST: LM_ERR(" bad ipv6 reference\n"); goto parse_error; case P_HOST: /*mark the end*/ vb->host.len=tmp-vb->host.s; state=F_VIA; break; case P_PORT: /*mark the end*/ vb->port_str.len=tmp-vb->port_str.s; state=F_VIA; break; case L_PORT: case L_PARAM: case P_PARAM: case L_VIA: state=F_VIA; break; case F_PORT: case F_PARAM: LM_ERR("invalid char <%c> in state %d\n", *tmp,state); goto parse_error; case F_VIA: /* do nothing, eat ","*/ break; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; case F_COMMENT:/*everything is allowed in a comment*/ vb->comment.s=tmp; state=P_COMMENT; break; case P_COMMENT: /*everything is allowed in a comment*/ break; default: LM_CRIT("on <%c> state %d\n",*tmp, state); goto parse_error; } break; case '(': switch(state){ case F_HOST: case F_PORT: case F_PARAM: case F_VIA: case F_IP6HOST: case P_IP6HOST: /*must be terminated in ']'*/ LM_ERR(" on <%c> state %d\n", *tmp, state); goto parse_error; case P_HOST: /*mark the end*/ vb->host.len=tmp-vb->host.s; state=F_COMMENT; c_nest++; break; case P_PORT: /*mark the end*/ vb->port_str.len=tmp-vb->port_str.s; state=F_COMMENT; c_nest++; break; case P_PARAM: /*mark the end*/ vb->params.len=tmp-vb->params.s; state=F_COMMENT; c_nest++; break; case L_PORT: case L_PARAM: case L_VIA: state=F_COMMENT; vb->params.len=tmp-vb->params.s; c_nest++; break; case P_COMMENT: case F_COMMENT: c_nest++; break; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; default: LM_CRIT("on <%c> state %d\n", *tmp, state); goto parse_error; } break; case ')': switch(state){ case F_COMMENT: case P_COMMENT: if (c_nest){ c_nest--; if(c_nest==0){ state=L_VIA; vb->comment.len=tmp-vb->comment.s; break; } }else{ LM_ERR(" missing '(' - nesting= %d\n", c_nest); goto parse_error; } break; case F_HOST: case F_PORT: case F_PARAM: case F_VIA: case P_HOST: case P_PORT: case P_PARAM: case L_PORT: case L_PARAM: case L_VIA: case F_IP6HOST: case P_IP6HOST: LM_ERR(" on <%c> state %d\n",*tmp, state); goto parse_error; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; default: LM_CRIT("on <%c> state %d\n", *tmp, state); goto parse_error; } break; case '[': switch(state){ case F_HOST: vb->host.s=tmp; /* mark start here (include [])*/ state=F_IP6HOST; break; case F_COMMENT:/*everything is allowed in a comment*/ vb->comment.s=tmp; state=P_COMMENT; break; case P_COMMENT: break; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; default: LM_ERR("on <%c> state %d\n",*tmp, state); goto parse_error; } break; case ']': switch(state){ case P_IP6HOST: /*mark the end*/ vb->host.len=(tmp-vb->host.s)+1; /* include "]" */ state=L_PORT; break; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; case F_COMMENT:/*everything is allowed in a comment*/ vb->comment.s=tmp; state=P_COMMENT; break; case P_COMMENT: break; default: LM_ERR("on <%c> state %d\n",*tmp, state); goto parse_error; } break; default: switch(state){ case F_HOST: state=P_HOST; vb->host.s=tmp; //break; case P_HOST: /*check if host allowed char*/ if ( (*tmp<'a' || *tmp>'z') && (*tmp<'A' || *tmp>'Z') && (*tmp<'0' || *tmp>'9') && *tmp!='-' && *tmp!='.') goto parse_error; break; case F_PORT: state=P_PORT; vb->port_str.s=tmp; //break; case P_PORT: /*check if number*/ if ( *tmp<'0' || *tmp>'9' ) goto parse_error; break; case F_PARAM: /*state=P_PARAM*/; if(vb->params.s==0) vb->params.s=param_start; param=pkg_malloc(sizeof(struct via_param)); if (param==0){ LM_ERR("no pkg memory left\n"); goto error; } memset(param,0, sizeof(struct via_param)); param->start=param_start; tmp=parse_via_param(tmp, end, &state, &saved_state, param); switch(state){ case F_PARAM: param_start=tmp+1; case L_PARAM: case F_LF: case F_CR: vb->params.len=tmp - vb->params.s; break; case F_VIA: vb->params.len=param->start+param->size -vb->params.s; break; case END_OF_HEADER: vb->params.len=param->start+param->size -vb->params.s; break; case PARAM_ERROR: pkg_free(param); goto parse_error; default: pkg_free(param); LM_ERR(" after parse_via_param: invalid " "char <%c> on state %d\n",*tmp, state); goto parse_error; } /*add param to the list*/ if (vb->last_param) vb->last_param->next=param; else vb->param_lst=param; vb->last_param=param; /* update param. shortcuts */ switch(param->type){ case PARAM_BRANCH: vb->branch=param; break; case PARAM_RECEIVED: vb->received=param; break; case PARAM_RPORT: vb->rport=param; break; case PARAM_I: vb->i=param; break; case PARAM_ALIAS: vb->alias=param; break; case PARAM_MADDR: vb->maddr=param; break; } if (state==END_OF_HEADER){ state=saved_state; goto endofheader; } break; case P_PARAM: break; case F_VIA: /*vb->next=tmp;*/ /*???*/ goto nextvia; case L_PORT: case L_PARAM: case L_VIA: LM_ERR("on <%c> state %d (default)\n",*tmp, state); goto parse_error; case F_COMMENT: state=P_COMMENT; vb->comment.s=tmp; break; case P_COMMENT: break; case F_IP6HOST: state=P_IP6HOST; //break; case P_IP6HOST: /*check if host allowed char*/ if ( (*tmp<'a' || *tmp>'f') && (*tmp<'A' || *tmp>'F') && (*tmp<'0' || *tmp>'9') && *tmp!=':') goto parse_error; break; case F_CRLF: case F_LF: case F_CR: /*previous=crlf and now !=' '*/ goto endofheader; default: LM_CRIT("invalid char <%c> in state %d\n",*tmp, state); goto parse_error; } } } LM_DBG("end of packet reached, state=%d\n", state); goto endofpacket; /*end of packet, probably should be goto error*/ endofheader: state=saved_state; LM_DBG("end of header reached, state=%d\n", state); endofpacket: /* check if error*/ switch(state){ case P_HOST: case L_PORT: case P_PORT: case L_PARAM: case P_PARAM: case P_VALUE: case GEN_PARAM: case FIN_HIDDEN: case L_VIA: break; default: LM_ERR(" invalid via - end of header in state %d\n", state); goto parse_error; } /* if (proto) printf("<SIP/2.0/%s>\n", proto); if (host) printf("host= <%s>\n", host); if (port_str) printf("port= <%s>\n", port_str); if (param) printf("params= <%s>\n", param); if (comment) printf("comment= <%s>\n", comment); if(next_via) printf("next_via= <%s>\n", next_via); */ /*LM_DBG("rest=<%s>\n", tmp);*/ vb->error=PARSE_OK; vb->bsize=tmp-buffer; if (vb->port_str.s){ vb->port=str2s(vb->port_str.s, vb->port_str.len, &err); if (err){ LM_ERR(" invalid port number <%.*s>\n", vb->port_str.len, ZSW(vb->port_str.s)); goto parse_error; } } return tmp; nextvia: LM_DBG("next_via\n"); vb->error=PARSE_OK; vb->bsize=tmp-buffer; if (vb->port_str.s){ vb->port=str2s(vb->port_str.s, vb->port_str.len, &err); if (err){ LM_ERR(" invalid port number <%.*s>\n", vb->port_str.len, ZSW(vb->port_str.s)); goto parse_error; } } vb->next=pkg_malloc(sizeof(struct via_body)); if (vb->next==0){ LM_ERR(" out of pkg memory\n"); goto error; } vb=vb->next; memset(vb, 0, sizeof(struct via_body)); buffer=tmp; goto parse_again; parse_error: if (end>buffer){ LM_ERR(" <%.*s>\n", (int)(end-buffer), ZSW(buffer)); } if ((tmp>buffer)&&(tmp<end)){ LM_ERR("parsed so far:<%.*s>\n", (int)(tmp-buffer), ZSW(buffer) ); }else{ LM_ERR("via parse failed\n"); } error: vb->error=PARSE_ERROR; vbody->error=PARSE_ERROR; /* make sure the first via body is marked as bad also */ return tmp; }
int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto) { str dest = {0}; int ret = 0; struct sip_uri next_hop, *u; struct dest_info dst; char *p; if (pu) { if (fixup_get_svalue(msg, pu, &dest)) { LM_ERR("cannot get the destination parameter\n"); return -1; } } init_dest_info(&dst); if (dest.len <= 0) { /*get next hop uri uri*/ if (msg->dst_uri.len) { ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop); u = &next_hop; } else { ret = parse_sip_msg_uri(msg); u = &msg->parsed_uri; } if (ret<0) { LM_ERR("send() - bad_uri dropping packet\n"); ret=E_BUG; goto error; } } else { u = &next_hop; u->port_no = 5060; u->host = dest; /* detect ipv6 */ p = memchr(dest.s, ']', dest.len); if (p) { p++; p = memchr(p, ':', dest.s + dest.len - p); } else { p = memchr(dest.s, ':', dest.len); } if (p) { u->host.len = p - dest.s; p++; u->port_no = str2s(p, dest.len - (p - dest.s), NULL); } } ret = sip_hostport2su(&dst.to, &u->host, u->port_no, &dst.proto); if(ret!=0) { LM_ERR("failed to resolve [%.*s]\n", u->host.len, ZSW(u->host.s)); ret=E_BUG; goto error; } dst.proto = proto; if (proto == PROTO_UDP) { dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP); if (dst.send_sock!=0){ ret=udp_send(&dst, msg->buf, msg->len); }else{ ret=-1; } } #ifdef USE_TCP else{ /*tcp*/ dst.id=0; ret=tcp_send(&dst, 0, msg->buf, msg->len); } #endif if (ret>=0) ret=1; error: return ret; }
int corex_add_alias_subdomains(char* aliasval) { char *p = NULL; corex_alias_t ta; corex_alias_t *na; memset(&ta, 0, sizeof(corex_alias_t)); p = strchr(aliasval, ':'); if(p==NULL) { /* only hostname */ ta.alias.s = aliasval; ta.alias.len = strlen(aliasval); goto done; } if((p-aliasval)==3 || (p-aliasval)==4) { /* check if it is protocol */ if((p-aliasval)==3 && strncasecmp(aliasval, "udp", 3)==0) { ta.proto = PROTO_UDP; } else if((p-aliasval)==3 && strncasecmp(aliasval, "tcp", 3)==0) { ta.proto = PROTO_TCP; } else if((p-aliasval)==3 && strncasecmp(aliasval, "tls", 3)==0) { ta.proto = PROTO_TLS; } else if((p-aliasval)==4 && strncasecmp(aliasval, "sctp", 4)==0) { ta.proto = PROTO_SCTP; } else { /* use hostname */ ta.alias.s = aliasval; ta.alias.len = p - aliasval; } } if(ta.alias.len==0) { p++; if(p>=aliasval+strlen(aliasval)) goto error; ta.alias.s = p; p = strchr(ta.alias.s, ':'); if(p==NULL) { ta.alias.len = strlen(ta.alias.s); goto done; } } /* port */ p++; if(p>=aliasval+strlen(aliasval)) goto error; ta.port = str2s(p, strlen(p), NULL); done: if(ta.alias.len==0) goto error; na = (corex_alias_t*)pkg_malloc(sizeof(corex_alias_t)); if(na==NULL) { LM_ERR("no memory for adding alias subdomains: %s\n", aliasval); return -1; } memcpy(na, &ta, sizeof(corex_alias_t)); na->next = _corex_alias_list; _corex_alias_list = na; return 0; error: LM_ERR("error adding alias subdomains: %s\n", aliasval); return -1; }