Esempio n. 1
0
File: avp.c Progetto: 2pac/kamailio
static int set_destination(struct sip_msg* msg, str* dest)
{
    name_addr_t nameaddr;
    
    if (!parse_nameaddr(dest, &nameaddr)) {
	return set_dst_uri(msg, &nameaddr.uri);
    } else {
	     /* it is just URI, pass it through */
	return set_dst_uri(msg, dest);
    }
}
Esempio n. 2
0
int parse_first_nameaddr(sip_nameaddr* na, const char* c, int len)
{
  const char* tmp_c = c;
  const char* end = c + len;
  const char* na_end = NULL;
  const char* na_begin = c;

  int err = skip_2_next_nameaddr(tmp_c,na_end,end);
  if(err < 0){
    ERROR("While parsing first nameaddr ('%.*s')\n",len,c);
    return -1;
  }

  tmp_c = c;
  return parse_nameaddr(na,&tmp_c,na_end-tmp_c);
}
Esempio n. 3
0
int parse_nameaddr_uri(sip_nameaddr* na, const char** c, int len)
{
    if(parse_nameaddr(na, c, len) < 0) {
      
      DBG("Parsing name-addr failed\n");
      return -1;
    }
    
    if(parse_uri(&na->uri,na->addr.s,na->addr.len) < 0) {
	
	DBG("Parsing uri failed\n");
	return -1;
    }

    return 0;
}
Esempio n. 4
0
/*
 * Check if URI in RPID AVP contains an E164 user part
 */
int is_rpid_user_e164(struct sip_msg* _m, char* _s1, char* _s2)
{
	struct usr_avp *avp;
	name_addr_t parsed;
	str tmp, rpid;
	struct sip_uri uri;
	int_str val;

	if (rpid_avp_name==-1) {
		LM_ERR("rpid avp not defined\n");
		return -1;
	}

	if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
		LM_DBG("no rpid AVP\n");
		goto err;
	}

	if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
		LM_DBG("empty or non-string rpid, nothing to append\n");
		return -1;
	}

	rpid = val.s;

	if (find_not_quoted(&rpid, '<')) {
		if (parse_nameaddr(&rpid, &parsed) < 0) {
			LM_ERR("failed to parse RPID\n");
			goto err;
		}
		tmp = parsed.uri;
	} else {
		tmp = rpid;
	}

	if (parse_uri(tmp.s, tmp.len, &uri) < 0) {
	    LM_ERR("failed to parse RPID URI\n");
	    goto err;
	}

	return is_e164(&uri.user);

err:
	return -1;
}
Esempio n. 5
0
/*! \brief
 * Parse Route or Record-Route body
 */
static inline int do_parse_rr_body(char *buf, int len, rr_t **head)
{
	rr_t* r, *last;
	str s;
	param_hooks_t hooks;

	/* Make a temporary copy of the string pointer */
	if(buf==0 || len<=0)
	{
		DBG("parse_rr_body(): No body for record-route\n");
		*head = 0;
		return -2;
	}
	s.s = buf;
	s.len = len;
	trim_leading(&s);

	last = 0;

	while(1) {
		     /* Allocate and clear rr structure */
		r = (rr_t*)pkg_malloc(sizeof(rr_t));
		if (!r) {
			LOG(L_ERR, "parse_rr(): No memory left\n");
			goto error;
		}
		memset(r, 0, sizeof(rr_t));
		
		     /* Parse name-addr part of the header */
		if (parse_nameaddr(&s, &r->nameaddr) < 0) {
			LOG(L_ERR, "parse_rr(): Error while parsing name-addr (%.*s)\n",
					s.len, ZSW(s.s));
			goto error;
		}
		r->len = r->nameaddr.len;

		     /* Shift just behind the closing > */
		s.s = r->nameaddr.name.s + r->nameaddr.len;  /* Point just behind > */
		s.len -= r->nameaddr.len;

		trim_leading(&s); /* Skip any white-chars */

		if (s.len == 0) goto ok; /* Nothing left, finish */
		
		if (s.s[0] == ';') {         /* Route parameter found */
			s.s++;
			s.len--;
			trim_leading(&s);
			
			if (s.len == 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}

			     /* Parse all parameters */
			if (parse_params(&s, CLASS_ANY, &hooks, &r->params) < 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}
			r->len = r->params->name.s + r->params->len - r->nameaddr.name.s;

			     /* Copy hooks */
			     /*r->r2 = hooks.rr.r2; */

			trim_leading(&s);
			if (s.len == 0) goto ok;
		}

		if (s.s[0] != ',') {
			LOG(L_ERR, "parse_rr(): Invalid character '%c', comma expected\n", s.s[0]);
			goto error;
		}
		
		     /* Next character is comma or end of header*/
		s.s++;
		s.len--;
		trim_leading(&s);

		if (s.len == 0) {
			LOG(L_ERR, "parse_rr(): Text after comma missing\n");
			goto error;
		}

		     /* Append the structure as last parameter of the linked list */
		if (!*head) *head = r;
		if (last) last->next = r;
		last = r;
	}

 error:
	if (r) free_rr(&r);
	free_rr(head); /* Free any contacts created so far */
	return -1;

 ok:
	if (!*head) *head = r;
	if (last) last->next = r;
	return 0;
}
Esempio n. 6
0
/*
 * Parse Route and Record-Route header fields
 */
int parse_rr(struct hdr_field* _h)
{
	rr_t* r, *last;
	str s;
	param_hooks_t hooks;

	if (!_h) {
		LOG(L_ERR, "parse_rr(): Invalid parameter value\n");
		return -1;
	}

	if (_h->parsed) {
		     /* Already parsed, return */
		return 0;
	}

	     /* Make a temporary copy of the string pointer */
	s.s = _h->body.s;
	s.len = _h->body.len;
	trim_leading(&s);

	last = 0;

	while(1) {
		     /* Allocate and clear rr stucture */
		r = (rr_t*)pkg_malloc(sizeof(rr_t));
		if (!r) {
			LOG(L_ERR, "parse_rr(): No memory left\n");
			goto error;
		}
		memset(r, 0, sizeof(rr_t));
		
		     /* Parse name-addr part of the header */
		if (parse_nameaddr(&s, &r->nameaddr) < 0) {
			LOG(L_ERR, "parse_rr(): Error while parsing name-addr\n");
			goto error;
		}
		r->len = r->nameaddr.len;

		     /* Shift just behind the closing > */
		s.s = r->nameaddr.name.s + r->nameaddr.len;  /* Point just behind > */
		s.len -= r->nameaddr.len;

		trim_leading(&s); /* Skip any whitechars */
		
		     /* Nothing left, finish */
		if (s.len == 0) goto ok;
		
		if (s.s[0] == ';') {         /* Contact parameter found */
			s.s++;
			s.len--;
			trim_leading(&s);
			
			if (s.len == 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}

			     /* Parse all parameters */
			if (parse_params(&s, CLASS_ANY, &hooks, &r->params) < 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}
			r->len = r->params->name.s + r->params->len - r->nameaddr.name.s;

			     /* Copy hooks */
			     /*r->r2 = hooks.rr.r2; */
			trim_leading(&s);
			if (s.len == 0) goto ok;
		}

		if (s.s[0] != ',') {
			LOG(L_ERR, "parse_rr(): Invalid character '%c', comma expected\n", s.s[0]);
			goto error;
		}

		     /* Next character is comma or end of header*/
		s.s++;
		s.len--;
		trim_leading(&s);

		if (s.len == 0) {
			LOG(L_ERR, "parse_rr(): Text after comma missing\n");
			goto error;
		}

		     /* Append the structure as last parameter of the linked list */
		if (!_h->parsed) _h->parsed = (void*)r;
		if (last) last->next = r;
		last = r;
	}

 error:
	if (r) pkg_free(r);
	free_rr((rr_t**)&_h->parsed); /* Free any contacts created so far */
	return -1;

 ok:
	if (!_h->parsed) _h->parsed = (void*)r;
	if (last) last->next = r;
	return 0;
}
Esempio n. 7
0
static int assemble_msg(struct sip_msg* msg, struct tw_info *twi)
{
	static char     id_buf[IDBUF_LEN];
	static char     route_buffer[ROUTE_BUFFER_MAX];
	static char     append_buf[APPEND_BUFFER_MAX];
	static char     cmd_buf[CMD_BUFFER_MAX];
	static str      empty_param = {".",1};
	unsigned int      hash_index, label;
	contact_body_t*   cb=0;
	contact_t*        c=0;
	name_addr_t       na;
	rr_t*             record_route;
	struct hdr_field* p_hdr;
	param_hooks_t     hooks;
	int               l;
	char*             s, fproxy_lr;
	str               route, next_hop, append, tmp_s, body, str_uri;

	if(msg->first_line.type != SIP_REQUEST){
		LM_ERR("called for something else then a SIP request\n");
		goto error;
	}

	/* parse all -- we will need every header field for a UAS */
	if ( parse_headers(msg, HDR_EOH_F, 0)==-1) {
		LM_ERR("parse_headers failed\n");
		goto error;
	}

	/* find index and hash; (the transaction can be safely used due 
	 * to refcounting till script completes) */
	if( t_get_trans_ident(msg,&hash_index,&label) == -1 ) {
		LM_ERR("t_get_trans_ident failed\n");
		goto error;
	}

	 /* parse from header */
	if (msg->from->parsed==0 && parse_from_header(msg)<0 ) {
		LM_ERR("failed to parse <From:> header\n");
		goto error;
	}

	/* parse the RURI (doesn't make any malloc) */
	msg->parsed_uri_ok = 0; /* force parsing */
	if (parse_sip_msg_uri(msg)<0) {
		LM_ERR("uri has not been parsed\n");
		goto error;
	}

	/* parse contact header */
	str_uri.s = 0;
	str_uri.len = 0;
	if(msg->contact) {
		if (msg->contact->parsed==0 && parse_contact(msg->contact)<0) {
			LM_ERR("failed to parse <Contact:> header\n");
			goto error;
		}
		cb = (contact_body_t*)msg->contact->parsed;
		if(cb && (c=cb->contacts)) {
			str_uri = c->uri;
			if (find_not_quoted(&str_uri,'<')) {
				parse_nameaddr(&str_uri,&na);
				str_uri = na.uri;
			}
		}
	}

	/* str_uri is taken from caller's contact or from header
	 * for backwards compatibility with pre-3261 (from is already parsed)*/
	if(!str_uri.len || !str_uri.s)
		str_uri = get_from(msg)->uri;

	/* parse Record-Route headers */
	route.s = s = route_buffer; route.len = 0;
	fproxy_lr = 0;
	next_hop = empty_param;

	p_hdr = msg->record_route;
	if(p_hdr) {
		if (p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ) {
			LM_ERR("failed to parse 'Record-Route:' header\n");
			goto error;
		}
		record_route = (rr_t*)p_hdr->parsed;
	} else {
		record_route = 0;
	}

	if( record_route ) {
		if ( (tmp_s.s=find_not_quoted(&record_route->nameaddr.uri,';'))!=0 &&
		tmp_s.s+1!=record_route->nameaddr.uri.s+
		record_route->nameaddr.uri.len) {
			/* Parse all parameters */
			tmp_s.len = record_route->nameaddr.uri.len - (tmp_s.s-
				record_route->nameaddr.uri.s);
			if (parse_params( &tmp_s, CLASS_URI, &hooks, 
			&record_route->params) < 0) {
				LM_ERR("failed to parse record route uri params\n");
				goto error;
			}
			fproxy_lr = (hooks.uri.lr != 0);
			LM_DBG("record_route->nameaddr.uri: %.*s\n",
				record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);
			if(fproxy_lr){
				LM_DBG("first proxy has loose routing\n");
				copy_route(s,route.len,record_route->nameaddr.uri.s,
					record_route->nameaddr.uri.len);
			}
		}
		for(p_hdr = p_hdr->next;p_hdr;p_hdr = p_hdr->next) {
			/* filter out non-RR hdr and empty hdrs */
			if( (p_hdr->type!=HDR_RECORDROUTE_T) || p_hdr->body.len==0)
				continue;

			if(p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ){
				LM_ERR("failed to parse <Record-route:> header\n");
				goto error;
			}
			for(record_route=p_hdr->parsed; record_route;
				record_route=record_route->next){
				LM_DBG("record_route->nameaddr.uri: <%.*s>\n",
					record_route->nameaddr.uri.len,
					record_route->nameaddr.uri.s);
				copy_route(s,route.len,record_route->nameaddr.uri.s,
					record_route->nameaddr.uri.len);
			}
		}

		if(!fproxy_lr){
			copy_route(s,route.len,str_uri.s,str_uri.len);
			str_uri = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
		} else {
			next_hop = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
		}
	}

	LM_DBG("calculated route: %.*s\n",route.len,route.len ? route.s : "");
	LM_DBG("next r-uri: %.*s\n",str_uri.len,str_uri.len ? str_uri.s : "");

	if ( REQ_LINE(msg).method_value==METHOD_INVITE || 
	(twi->append && twi->append->add_body) ) {
		/* get body */
		if( (body.s = get_body(msg)) == 0 ){
			LM_ERR("get_body failed\n");
			goto error;
		}
		body.len = msg->len - (body.s - msg->buf);
	} else {
		body = empty_param;
	}

	/* flags & additional headers */
	append.s = s = append_buf;
	if (sizeof(flag_t)*2+12+1 >= APPEND_BUFFER_MAX) {
		LM_ERR("buffer overflow while copying flags\n");
		goto error;
	}
	append_str(s,"P-MsgFlags: ",12);
	l = APPEND_BUFFER_MAX - (12+1); /* include trailing `\n'*/

	if (int2reverse_hex(&s, &l, (int)msg->msg_flags) == -1) {
		LM_ERR("buffer overflow while copying optional header\n");
		goto error;
	}
	append_chr(s,'\n');

	if ( twi->append && ((s=append2buf( s, APPEND_BUFFER_MAX-(s-append.s), msg,
	twi->append->elems))==0) )
		goto error;

	/* body separator */
	append_chr(s,'.');
	append.len = s-append.s;

	eol_line(1).s = s = cmd_buf;
	if(twi->action.len+12 >= CMD_BUFFER_MAX){
		LM_ERR("buffer overflow while copying command name\n");
		goto error;
	}
	append_str(s,"sip_request.",12);
	append_str(s,twi->action.s,twi->action.len);
	eol_line(1).len = s-eol_line(1).s;

	eol_line(2)=REQ_LINE(msg).method;     /* method type */
	eol_line(3)=msg->parsed_uri.user;     /* user from r-uri */
	eol_line(4)=msg->parsed_uri.host;     /* domain */

	eol_line(5)=msg->rcv.bind_address->address_str; /* dst ip */

	eol_line(6)=msg->rcv.dst_port==SIP_PORT ?
			empty_param : msg->rcv.bind_address->port_no_str; /* port */

	/* r_uri ('Contact:' for next requests) */
	eol_line(7)=*GET_RURI(msg);

	/* r_uri for subsequent requests */
	eol_line(8)=str_uri.len?str_uri:empty_param;

	eol_line(9)=get_from(msg)->body;		/* from */
	eol_line(10)=msg->to->body;			/* to */
	eol_line(11)=msg->callid->body;		/* callid */
	eol_line(12)=get_from(msg)->tag_value;	/* from tag */
	eol_line(13)=get_to(msg)->tag_value;	/* to tag */
	eol_line(14)=get_cseq(msg)->number;	/* cseq number */

	eol_line(15).s=id_buf;       /* hash:label */
	s = int2str(hash_index, &l);
	if (l+1>=IDBUF_LEN) {
		LM_ERR("too big hash\n");
		goto error;
	}
	memcpy(id_buf, s, l);
	id_buf[l]=':';
	eol_line(15).len=l+1;
	s = int2str(label, &l);
	if (l+1+eol_line(15).len>=IDBUF_LEN) {
		LM_ERR("too big label\n");
		goto error;
	}
	memcpy(id_buf+eol_line(15).len, s, l);
	eol_line(15).len+=l;

	eol_line(16) = route.len ? route : empty_param;
	eol_line(17) = next_hop;
	eol_line(18) = append;
	eol_line(19) = body;

	/* success */
	return 1;
error:
	/* 0 would lead to immediate script exit -- -1 returns
	 * with 'false' to script processing */
	return -1;
}
Esempio n. 8
0
//
// Ref. RFC 3261 "12.2.1.1 Generating the Request"
//
int trans_layer::set_next_hop(list<sip_header*>& route_hdrs, 
			      cstring& r_uri, 
			      sockaddr_storage* remote_ip)
{
    string         next_hop;
    unsigned short next_port=0; 

    //assert(msg->type == SIP_REQUEST);

    int err=0;

    if(!route_hdrs.empty()){
	
	sip_header* fr = route_hdrs.front();
	
	sip_nameaddr na;
	const char* c = fr->value.s;
	if(parse_nameaddr(&na, &c, fr->value.len)<0) {
	    
	    DBG("Parsing name-addr failed\n");
	    return -1;
	}
	
	if(parse_uri(&na.uri,na.addr.s,na.addr.len) < 0) {
	    
	    DBG("Parsing route uri failed\n");
	    return -1;
	}

	bool is_lr = false;
	if(!na.uri.params.empty()){
	    
	    list<sip_avp*>::iterator it = na.uri.params.begin();
	    for(;it != na.uri.params.end(); it++){
		
		if( ((*it)->name.len == 2) && 
		    (!memcmp((*it)->name.s,"lr",2)) ) {

		    is_lr = true;
		    break;
		}
	    }

	}

	if (SipCtrlInterfaceFactory::outbound_host.empty()) {
	    next_hop  = c2stlstr(na.uri.host);
	    next_port = na.uri.port;
	} else {
	    next_hop = SipCtrlInterfaceFactory::outbound_host;
	    next_port = SipCtrlInterfaceFactory::outbound_port;
	}	    

	if(!is_lr){
	    
	    // detect beginning of next route

	    enum {
		RR_PARAMS=0,
		RR_QUOTED,
		RR_SEP_SWS,  // space(s) after ','
		RR_NXT_ROUTE
	    };

	    int st = RR_PARAMS;
	    const char* end = fr->value.s + fr->value.len;
	    for(;c<end;c++){
		
		switch(st){
		case RR_PARAMS:
		    switch(*c){
		    case SP:
		    case HTAB:
		    case CR:
		    case LF:
			break;
		    case COMMA:
			st = RR_SEP_SWS;
			break;
		    case DQUOTE:
			st = RR_QUOTED;
			break;
		    }
		    break;
		case RR_QUOTED:
		    switch(*c){
		    case BACKSLASH:
			c++;
			break;
		    case DQUOTE:
			st = RR_PARAMS;
			break;
		    }
		    break;
		case RR_SEP_SWS:
		    switch(*c){
		    case SP:
		    case HTAB:
		    case CR:
		    case LF:
			break;
		    default:
			st = RR_NXT_ROUTE;
			goto nxt_route;
		    }
		    break;
		}
	    }

	nxt_route:
	    
	    switch(st){
	    case RR_QUOTED:
	    case RR_SEP_SWS:
		DBG("Malformed first route header\n");
	    case RR_PARAMS:
		// remove current route header from message
		DBG("delete (fr=0x%p)\n",fr);
		delete fr; // route_hdrs.front();
		route_hdrs.pop_front();
		DBG("route_hdrs.length() = %i\n",(int)route_hdrs.size());
		break;
		
	    case RR_NXT_ROUTE:
		// remove current route from this header
		fr->value.s   = c;
		fr->value.len = end-c;
		break;
	    }

	    
	    // copy r_uri at the end of 
	    // the route set.
	    route_hdrs.push_back(new sip_header(0,"Route",r_uri));

	    r_uri = na.addr;
	}
	
    }
    else {

	if (SipCtrlInterfaceFactory::outbound_host.empty()) {
	    sip_uri parsed_r_uri;
	    err = parse_uri(&parsed_r_uri,r_uri.s,r_uri.len);
	    if(err < 0){
		ERROR("Invalid Request URI\n");
		return -1;
	    }
	    next_hop  = c2stlstr(parsed_r_uri.host);
	    next_port = parsed_r_uri.port;
	} else {
	    next_hop = SipCtrlInterfaceFactory::outbound_host;
	    next_port = SipCtrlInterfaceFactory::outbound_port;
	}
    }

    DBG("next_hop:next_port is <%s:%u>\n", next_hop.c_str(), next_port);
    
    err = resolver::instance()->resolve_name(next_hop.c_str(),
					     remote_ip,IPv4,UDP);
    if(err < 0){
	ERROR("Unresolvable Request URI\n");
	return -1;
    }

    ((sockaddr_in*)remote_ip)->sin_port = htons(next_port);
    
    return 0;
}
Esempio n. 9
0
void trans_layer::send_200_ack(sip_msg* reply, sip_trans* t)
{
    // Set request URI
    // TODO: use correct R-URI instead of just 'Contact'
    if(!get_contact(reply)) {
	DBG("Sorry, reply has no Contact header: could not send ACK\n");
	return;
    }
    
    sip_nameaddr na;
    const char* c = get_contact(reply)->value.s;
    if(parse_nameaddr(&na,&c,get_contact(reply)->value.len) < 0){
	DBG("Sorry, reply's Contact parsing failed: could not send ACK\n");
	return;
    }
    
    cstring r_uri = na.addr;
    list<sip_header*> route_hdrs;

    if(t && !t->msg->route.empty()){
	for(list<sip_header*>::iterator it = t->msg->route.begin();
	    it != t->msg->route.end(); ++it) {
	    
	    route_hdrs.push_back(new sip_header(0,"Route",(*it)->value));
	}
    }
    else {
	for(list<sip_header*>::reverse_iterator it = reply->record_route.rbegin();
	    it != reply->record_route.rend(); ++it) {
	    
	    route_hdrs.push_back(new sip_header(0,"Route",(*it)->value));
	}
    }

    sockaddr_storage remote_ip;
    set_next_hop(route_hdrs,r_uri,&remote_ip);

    int request_len = request_line_len(cstring("ACK",3),r_uri);
   
    char branch_buf[BRANCH_BUF_LEN];
    compute_branch(branch_buf,reply->callid->value,reply->cseq->value);
    cstring branch(branch_buf,BRANCH_BUF_LEN);

    sip_header* max_forward = new sip_header(0,cstring("Max-Forwards"),cstring("10"));

    cstring via((char*)transport->get_local_ip()); 

    request_len += via_len(via,branch);

    request_len += copy_hdrs_len(route_hdrs);

    request_len += copy_hdr_len(reply->to);
    request_len += copy_hdr_len(reply->from);
    request_len += copy_hdr_len(reply->callid);
    request_len += copy_hdr_len(max_forward);
    request_len += cseq_len(get_cseq(reply)->num_str,cstring("ACK",3));
    request_len += 2/* CRLF end-of-headers*/;

    // Allocate new message
    char* ack_buf = new char[request_len];

    // generate it
    char* msg = ack_buf;

    request_line_wr(&msg,cstring("ACK",3),r_uri);
    via_wr(&msg,via,branch);

    copy_hdrs_wr(&msg,route_hdrs);
    // clear route headers list
    for (list<sip_header*>::iterator it=route_hdrs.begin(); 
	 it!= route_hdrs.end(); it++)
	delete *it;
    
    copy_hdr_wr(&msg,reply->from);
    copy_hdr_wr(&msg,reply->to);
    copy_hdr_wr(&msg,reply->callid);
    copy_hdr_wr(&msg,max_forward);
    delete max_forward;
    cseq_wr(&msg,get_cseq(reply)->num_str,cstring("ACK",3));

    *msg++ = CR;
    *msg++ = LF;

    DBG("About to send 200 ACK\n");
    //    DBG("About to send 200 ACK: \n<%.*s>\n",request_len,ack_buf);

    assert(transport);
    int send_err = transport->send(&remote_ip,ack_buf,request_len);
    if(send_err < 0){
	ERROR("Error from transport layer\n");
	delete [] ack_buf;
    }
    else if(t){
	delete [] t->retr_buf;
	t->retr_buf = ack_buf;
	t->retr_len = request_len;
	memcpy(&t->retr_addr,&remote_ip,sizeof(sockaddr_storage));
    }
}
Esempio n. 10
0
int parse_from_to(sip_from_to* ft, const char* beg, int len)
{
    enum {
	FTP_BEG,

	FTP_TAG1,
	FTP_TAG2,
	FTP_TAG3,

	FTP_OTHER
    };

    const char* c = beg;
    const char* end = c+len;

    int ret = parse_nameaddr(&ft->nameaddr,&c,len);
    if(ret) return ret;

    ret = parse_gen_params(&ft->params,&c, end-c, 0);
    
    if(!ft->params.empty()){

	list<sip_avp*>::iterator it = ft->params.begin();
	for(;it!=ft->params.end();++it){

	    const char* c = (*it)->name.s;
	    const char* end = c + (*it)->name.len;
	    int st = FTP_BEG;
	    
	    for(;c!=end;c++){

#define case_FT_PARAM(st1,ch1,ch2,st2)\
	    case st1:\
		switch(*c){\
		case ch1:\
		case ch2:\
		    st = st2;\
		    break;\
		default:\
		    st = FTP_OTHER;\
		}\
		break

		switch(st){
		    case_FT_PARAM(FTP_BEG, 't','T',FTP_TAG1);
		    case_FT_PARAM(FTP_TAG1,'a','A',FTP_TAG2);
		    case_FT_PARAM(FTP_TAG2,'g','G',FTP_TAG3);

		case FTP_OTHER:
		    goto next_param;
		}
	    }

	    switch(st){
	    case FTP_TAG3:
		ft->tag = (*it)->value;
		break;
	    }

	next_param:
	    continue;
	}
    }
    
    return ret;
}