Example #1
0
int hepv2_received(char *buf, unsigned int len, struct receive_info *ri){

	int hl;
        struct hep_hdr *heph;
        struct ip_addr dst_ip, src_ip;
        char *hep_payload, *end, *hep_ip;
        struct hep_iphdr *hepiph = NULL;

	struct hep_timehdr* heptime_tmp = NULL;
        memset(heptime, 0, sizeof(struct hep_timehdr));

        struct hep_ip6hdr *hepip6h = NULL;
            	        
	correlation_id = NULL;
	authkey = NULL;

	hep_offset = 0; 
	
	hl = hep_offset = sizeof(struct hep_hdr);
        end = buf + len;
        if (unlikely(len<hep_offset)) {
        	LOG(L_ERR, "ERROR: sipcapture:hep_msg_received len less than offset [%i] vs [%i]\n", len, hep_offset);
                return -1;
        }

	/* hep_hdr */
        heph = (struct hep_hdr*) buf;

        switch(heph->hp_f){
        	case AF_INET:
                	hl += sizeof(struct hep_iphdr);
                        break;
		case AF_INET6:
                	hl += sizeof(struct hep_ip6hdr);
                        break;
		default:
                        LOG(L_ERR, "ERROR: sipcapture:hep_msg_received:  unsupported family [%d]\n", heph->hp_f);
                        return -1;
	}

        /* PROTO */
        if(heph->hp_p == IPPROTO_UDP) ri->proto=PROTO_UDP;
        else if(heph->hp_p == IPPROTO_TCP) ri->proto=PROTO_TCP;
        else if(heph->hp_p == IPPROTO_IDP) ri->proto=PROTO_TLS; /* fake protocol */
#ifdef USE_SCTP
        else if(heph->hp_p == IPPROTO_SCTP) ri->proto=PROTO_SCTP;
#endif
        else {
        	LOG(L_ERR, "ERROR: sipcapture:hep_msg_received: unknown protocol [%d]\n",heph->hp_p);
                ri->proto = PROTO_NONE;
	}

        hep_ip = buf + sizeof(struct hep_hdr);

        if (unlikely(hep_ip>end)){
                LOG(L_ERR,"hep_ip is over buf+len\n");
                return -1;
        }

	switch(heph->hp_f){
		case AF_INET:
                	hep_offset+=sizeof(struct hep_iphdr);
                        hepiph = (struct hep_iphdr*) hep_ip;
                        break;

		case AF_INET6:
                	hep_offset+=sizeof(struct hep_ip6hdr);
                        hepip6h = (struct hep_ip6hdr*) hep_ip;
                        break;

	}

	/* VOIP payload */
        hep_payload = buf + hep_offset;

        if (unlikely(hep_payload>end)){
        	LOG(L_ERR,"hep_payload is over buf+len\n");
                return -1;
	}

	/* timming */
        if(heph->hp_v == 2) {
                hep_offset+=sizeof(struct hep_timehdr);
                heptime_tmp = (struct hep_timehdr*) hep_payload;

                heptime->tv_sec = to_le(heptime_tmp->tv_sec);
                heptime->tv_usec = to_le(heptime_tmp->tv_usec);
                heptime->captid = heptime_tmp->captid;
        }


	/* fill ip from the packet to dst_ip && to */
        switch(heph->hp_f){

		case AF_INET:
                	dst_ip.af = src_ip.af = AF_INET;
                        dst_ip.len = src_ip.len = 4 ;
                        memcpy(&dst_ip.u.addr, &hepiph->hp_dst, 4);
                        memcpy(&src_ip.u.addr, &hepiph->hp_src, 4);
                        break;

		case AF_INET6:
                	dst_ip.af = src_ip.af = AF_INET6;
                        dst_ip.len = src_ip.len = 16 ;
                        memcpy(&dst_ip.u.addr, &hepip6h->hp6_dst, 16);
                        memcpy(&src_ip.u.addr, &hepip6h->hp6_src, 16);
                        break;

	}

        ri->src_ip = src_ip;
        ri->src_port = ntohs(heph->hp_sport);

        ri->dst_ip = dst_ip;
        ri->dst_port = ntohs(heph->hp_dport);

	/* cut off the offset */
	/* 
	 *  len -= offset;
         *  p = buf + offset;
	 *  memmove(buf, p, BUF_SIZE+1); 
	*/

        hep_payload = buf + hep_offset;

        receive_msg(hep_payload,(unsigned int)(len - hep_offset), ri);
	
	return -1;
}
Example #2
0
static int trace_send_hep_duplicate(str *body, str *from, str *to, struct dest_info * dst2)
{
	struct dest_info dst;
	struct socket_info *si;
	struct dest_info* dst_fin = NULL;
	struct proxy_l * p=NULL /* make gcc happy */;
	void* buffer = NULL;
	union sockaddr_union from_su;
	union sockaddr_union to_su;
	unsigned int len, buflen, proto;
	struct hep_hdr hdr;
	struct hep_iphdr hep_ipheader;
	struct hep_timehdr hep_time;
	struct timeval tvb;
	struct timezone tz;

	struct hep_ip6hdr hep_ip6header;

	if(body->s==NULL || body->len <= 0)
		return -1;

	if(dup_uri_str.s==0 || dup_uri==NULL)
		return 0;


	gettimeofday( &tvb, &tz );


	/* message length */
	len = body->len 
		+ sizeof(struct hep_ip6hdr)
		+ sizeof(struct hep_hdr) + sizeof(struct hep_timehdr);;


	/* The packet is too big for us */
	if (unlikely(len>BUF_SIZE)){
		goto error;
	}

	/* Convert proto:ip:port to sockaddress union SRC IP */
	if (pipport2su(from->s, &from_su, &proto)==-1 || (pipport2su(to->s, &to_su, &proto)==-1))
		goto error;

	/* check if from and to are in the same family*/
	if(from_su.s.sa_family != to_su.s.sa_family) {
		LM_ERR("interworking detected ?\n");
		goto error;
	}

	if (!dst2){
		init_dest_info(&dst);
		/* create a temporary proxy*/
		dst.proto = PROTO_UDP;
		p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
				dst.proto);
		if (p==0)
		{
			LM_ERR("bad host name in uri\n");
			goto error;
		}

		hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
		LM_DBG("setting up the socket_info\n");
		dst_fin = &dst;
	} else {
		dst_fin = dst2;
	}

	if (force_send_sock_str.s) {
		LM_DBG("force_send_sock activated, grep for the sock_info\n");
		si = grep_sock_info(&force_send_sock_uri->host,
				(force_send_sock_uri->port_no)?force_send_sock_uri->port_no:SIP_PORT,
				PROTO_UDP);
		if (!si) {
			LM_WARN("cannot grep socket info\n");
		} else {
			LM_DBG("found socket while grep: [%.*s] [%.*s]\n", si->name.len, si->name.s, si->address_str.len, si->address_str.s);
			dst_fin->send_sock = si;
		}
	}

	if (dst_fin->send_sock == 0) {
		dst_fin->send_sock=get_send_socket(0, &dst_fin->to, dst_fin->proto);
		if (dst_fin->send_sock == 0) {
			LM_ERR("can't forward to af %d, proto %d no corresponding"
					" listening socket\n", dst_fin->to.s.sa_family, dst_fin->proto);
			goto error;
		}
	}

	/* Version && proto && length */
	hdr.hp_l = sizeof(struct hep_hdr);
	hdr.hp_v = hep_version;
	hdr.hp_p = proto;

	/* AND the last */
	if (from_su.s.sa_family==AF_INET){
		/* prepare the hep headers */

		hdr.hp_f = AF_INET;
		hdr.hp_sport = htons(from_su.sin.sin_port);
		hdr.hp_dport = htons(to_su.sin.sin_port);

		hep_ipheader.hp_src = from_su.sin.sin_addr;
		hep_ipheader.hp_dst = to_su.sin.sin_addr;

		len = sizeof(struct hep_iphdr);
	}
	else if (from_su.s.sa_family==AF_INET6){
		/* prepare the hep6 headers */

		hdr.hp_f = AF_INET6;

		hdr.hp_sport = htons(from_su.sin6.sin6_port);
		hdr.hp_dport = htons(to_su.sin6.sin6_port);

		hep_ip6header.hp6_src = from_su.sin6.sin6_addr;
		hep_ip6header.hp6_dst = to_su.sin6.sin6_addr;

		len = sizeof(struct hep_ip6hdr);
	}
	else {
		LM_ERR("Unsupported protocol family\n");
		goto error;;
	}

	hdr.hp_l +=len;
	if (hep_version == 2){
		len += sizeof(struct hep_timehdr);
	}
	len += sizeof(struct hep_hdr) + body->len;
	buffer = (void *)pkg_malloc(len+1);
	if (buffer==0){
		LM_ERR("out of memory\n");
		goto error;
	}

	/* Copy job */
	memset(buffer, '\0', len+1);

	/* copy hep_hdr */
	memcpy((void*)buffer, &hdr, sizeof(struct hep_hdr));
	buflen = sizeof(struct hep_hdr);

	/* hep_ip_hdr */
	if(from_su.s.sa_family==AF_INET) {
		memcpy((void*)buffer + buflen, &hep_ipheader, sizeof(struct hep_iphdr));
		buflen += sizeof(struct hep_iphdr);
	}
	else {
		memcpy((void*)buffer+buflen, &hep_ip6header, sizeof(struct hep_ip6hdr));
		buflen += sizeof(struct hep_ip6hdr);
	}

	if(hep_version == 2) {

		hep_time.tv_sec = to_le(tvb.tv_sec);
		hep_time.tv_usec = to_le(tvb.tv_usec);
		hep_time.captid = hep_capture_id;

		memcpy((void*)buffer+buflen, &hep_time, sizeof(struct hep_timehdr));
		buflen += sizeof(struct hep_timehdr);
	}

	/* PAYLOAD */
	memcpy((void*)(buffer + buflen) , (void*)body->s, body->len);
	buflen +=body->len;

	if (msg_send_buffer(dst_fin, buffer, buflen, 1)<0)
	{
		LM_ERR("cannot send hep duplicate message\n");
		goto error;
	}

	if (p) {
		free_proxy(p); /* frees only p content, not p itself */
		pkg_free(p);
	}
	pkg_free(buffer);
	return 0;
error:
	if(p)
	{
		free_proxy(p); /* frees only p content, not p itself */
		pkg_free(p);
	}
	if(buffer) pkg_free(buffer);
	return -1;
}