Example #1
0
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;
}
Example #2
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;
}
Example #3
0
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;
}
Example #4
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;
}
Example #5
0
/* 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;
}
Example #6
0
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;
}
Example #7
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";
    }
}
Example #8
0
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;
}
Example #9
0
File: avp.c Project: 2pac/kamailio
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;
}
Example #10
0
/* 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;
}
Example #11
0
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;
		}
	}
}
Example #12
0
/** 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) */
}
Example #13
0
/* 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;
}
Example #14
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;
}
Example #15
0
/* 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;
}
Example #16
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;
	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;
}
Example #17
0
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;
}
Example #18
0
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;
}
Example #19
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;
}
Example #20
0
File: sl.c Project: OPSF/uClinux
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;
}
Example #21
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;
}
Example #22
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;
	}
}
Example #23
0
/* 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;
}
Example #24
0
/* (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;
}
Example #26
0
File: avp.c Project: 2pac/kamailio
/*
 *  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;
}
Example #27
0
/** 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;
}
Example #28
0
/*
 * 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;
}
Example #29
0
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;
}
Example #30
0
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;
}