Example #1
0
/** 
 * resolve_dht_gateway_info - Resolves the gateway address
 * @param gateway_name	FQDN of the gateway
 * @param gateway	Addrinfo struct where the result will be stored
 * @param af		address family
 * 
 * @return Returns 0 on success otherwise -1
 */
int resolve_dht_gateway_info(char *gateway_name, 
			     struct addrinfo ** gateway,
			     in_port_t gateway_port,
			     int af) {
    struct addrinfo hints;
    struct sockaddr_in  *sa_v4 = NULL;
    struct sockaddr_in6 *sa_v6 = NULL;
    int error;
    char opendht_serving_gateway_port_str[7];

    if ((af != AF_INET) && (af != AF_INET6)) {
	error = -1;
	HIP_DEBUG("Wrong address family!\n");
	return error;
    }

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = af;
    hints.ai_socktype = SOCK_STREAM;
    /* For some reason this does not work anymore -samu */
    //hints.ai_flags = AI_NODHT;
    error = 0;
    
    sprintf(opendht_serving_gateway_port_str, "%d", gateway_port);
    error = getaddrinfo(gateway_name, opendht_serving_gateway_port_str, &hints, gateway);
    if (error != 0) {
        HIP_DEBUG("OpenDHT gateway resolving failed %s\n", gateway_name);
	HIP_DEBUG("%s\n",gai_strerror(error));
    } else {
	if (af == AF_INET) {
	    sa_v4 = (struct sockaddr_in *) (*gateway)->ai_addr;
	    HIP_DEBUG_INADDR("OpenDHT gateway IPv4", &(sa_v4->sin_addr));
	} else if (af == AF_INET6) {
	    sa_v6 = (struct sockaddr_in6 *) (*gateway)->ai_addr;
	    HIP_DEBUG_IN6ADDR("OpenDHT gateway IPv6", &(sa_v6->sin6_addr));
	}
    }

    return error;
}
Example #2
0
/**
 *  connect_dht_gateway - Connects to given v6 gateway
 *  @param sockfd
 *  @param addrinfo Address to connect to 
 *  @param blocking 1 for blocking connect 0 for nonblocking
 *
 *  @return Returns 0 on success -1 otherwise, if nonblocking can return EINPRGORESS
 */
int connect_dht_gateway(int sockfd,
			   struct addrinfo * gateway,
			   int blocking){
    int flags = 0, error = 0;
    struct sockaddr_in *sa_v4;
    struct sockaddr_in6 *sa_v6;

    struct sigaction act, oact;
    act.sa_handler = connect_alarm;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    
    if(gateway == NULL){
            HIP_ERROR("No OpenDHT Serving Gateway Address.\n");
            return(-1);
    }
    
    if(blocking == 0)
        goto unblock;

    // blocking connect
    if(sigaction(SIGALRM, &act, &oact) < 0){
            HIP_DEBUG("Signal error before OpenDHT connect, "
                      "connecting without alarm\n");
            error = connect(sockfd, gateway->ai_addr, gateway->ai_addrlen);
    }else {
            HIP_DEBUG("Connecting to OpenDHT with alarm\n");
            if (alarm(DHT_CONNECT_TIMEOUT) != 0)
                HIP_DEBUG("Alarm was already set, connecting without\n");
            error = connect(sockfd, gateway->ai_addr, gateway->ai_addrlen);
            alarm(0);
            if (sigaction(SIGALRM, &oact, &act) <0 ) 
                HIP_DEBUG("Signal error after OpenDHT connect\n");
    }
    
    if(error < 0){
            HIP_PERROR("OpenDHT connect:");
            if (errno == EINTR)
                HIP_DEBUG("Connect to OpenDHT timedout\n");
            return(-1);
    }else{
	if(gateway->ai_family == AF_INET){
	    sa_v4 = (struct sockaddr_in *)gateway->ai_addr;
	    HIP_DEBUG_INADDR("Connected to OpenDHT v4 gateway", &(sa_v4->sin_addr));
	}
	else if(gateway->ai_family == AF_INET6){
            sa_v6 = (struct sockaddr_in6 *)gateway->ai_addr;
            HIP_DEBUG_IN6ADDR("Connected to OpenDHT v6 gateway", &(sa_v6->sin6_addr));
	}
	else{
	    HIP_DEBUG("Wrong address family for OPENDHT gateway %d\n", gateway->ai_family);
	}
	return(0);
    }
        
 unblock:
    // unblocking connect
    flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); 
    
    if(gateway->ai_family == AF_INET){
	    sa_v4 = (struct sockaddr_in *)gateway->ai_addr;
	    HIP_DEBUG_INADDR("Connecting to OpenDHT v4 gateway", &(sa_v4->sin_addr));
    }
    else if(gateway->ai_family == AF_INET6){
            sa_v6 = (struct sockaddr_in6 *)gateway->ai_addr;
            HIP_DEBUG_IN6ADDR("Connecting to OpenDHT v6 gateway", &(sa_v6->sin6_addr));
    }
    else{
	    HIP_DEBUG("Wrong address family for OPENDHT gateway %d\n", gateway->ai_family);
    }

    if(connect(sockfd, gateway->ai_addr, gateway->ai_addrlen) < 0){
            if (errno == EINPROGRESS)
                return(EINPROGRESS);
            else{
                    HIP_PERROR("OpenDHT connect:");
                    return(-1);
            }
    }else{
            // connect ok
            return(0);
    }
}
Example #3
0
File: opptcp.c Project: surki/hipl
/**
 * Analyzes incoming TCP packets
 * 
 * @param *handle	the handle that has grabbed the packet, needed when allowing or dropping the packet.
 * @param hdr		pointer to the ip packet being examined.
 * @param ip_version	ipv4 or ipv6 type of traffic.
 * @return		nothing
 */
int hip_fw_examine_incoming_tcp_packet(void *hdr,
				       int ip_version,
				       int header_size) {
	int i, optLen, optionsLen, err = 0, state_ha;
	char 	       *hdrBytes = NULL;
	struct tcphdr  *tcphdr;
	struct ip      *iphdr;
	struct ip6_hdr *ip6_hdr;
	//fields for temporary values
	u_int16_t       portTemp;
	struct in_addr  addrTemp;
	struct in6_addr addr6Temp;
	/* the following vars are needed for
	 * sending the i1 - initiating the exchange
	 * in case we see that the peer supports hip*/
	struct in6_addr peer_ip, own_ip;
	struct in6_addr peer_hit;
	in_port_t        src_tcp_port;
	in_port_t        dst_tcp_port;
	/*this is needed for puting in default values
	  for the hits and lsi in the firewall entry*/
	struct in6_addr all_zero_default;
	firewall_hl_t *entry_peer = NULL;
	struct in6_addr src_lsi, dst_lsi;
	struct in6_addr src_hit, dst_hit;

	HIP_DEBUG("\n");

	if(ip_version == 4){
		iphdr = (struct ip *)hdr;
		//get the tcp header
		tcphdr = ((struct tcphdr *) (((char *) iphdr) + header_size));
		hdrBytes = ((char *) iphdr) + header_size;
		HIP_DEBUG_INADDR("the destination", &iphdr->ip_src);
		//peer and local ip needed for sending the i1 through hipd
		IPV4_TO_IPV6_MAP(&iphdr->ip_src, &peer_ip);
		IPV4_TO_IPV6_MAP(&iphdr->ip_dst, &own_ip);
	}
	else if(ip_version == 6){
		ip6_hdr = (struct ip6_hdr *)hdr;
		//get the tcp header
		tcphdr = ((struct tcphdr *) (((char *) ip6_hdr) + header_size));
		hdrBytes = ((char *) ip6_hdr) + header_size;
		//peer and local ip needed for sending the i1 through hipd
		ipv6_addr_copy(&peer_ip, &ip6_hdr->ip6_src);
		ipv6_addr_copy(&own_ip, &ip6_hdr->ip6_dst);
	}

	/* this condition was originally only for SYN 0
	 * but below we added a condition for RST 1 and ACK 1
	 * So, in order for the RST ACK condition to be reachable,
	 * we added the condition for RST 0 here.
	 * The purpose is to process the packets as soon as possible.
	 * Many packets have SYN 0 and RST 0, so they get accepted quickly. 
	 */
	if((tcphdr->syn == 0) && (tcphdr->rst == 0) && (tcphdr->fin == 0)){
		return 1;
	}
	
	/* this shortcut check was removed
	 * because we need to analyze incoming
	 * TCP SYN_ACK, RST_ACK and FIN_ACK packets
	 * even when there are no options
	 * for updating the firewall entry
	 */
	/*//check that there are no options
	if(tcphdr->doff == 5){
		return 1;
	}*/

	if((tcphdr->syn == 1) && (tcphdr->ack == 0)){	//incoming, syn=1 and ack=0
		
		/* We need to create state in the firewall db
		 * if there is no entry for the peer yet. */
		entry_peer = (firewall_hl_t *)firewall_ip_db_match(&peer_ip);
		//if there is no entry in fw, add a default one
		if(!entry_peer){
			firewall_add_default_entry(&peer_ip);
			entry_peer = (firewall_hl_t *)firewall_ip_db_match(&peer_ip);
		}


		if(tcp_packet_has_i1_option(hdrBytes, 4*tcphdr->doff)){
			/*//swap the ports
			portTemp = tcphdr->source;
			tcphdr->source = tcphdr->dest;
			tcphdr->dest = portTemp;
			//swap the ip addresses
			if(ip_version == 4){
				addrTemp = iphdr->ip_src;
				iphdr->ip_src = iphdr->ip_dst;
				iphdr->ip_dst = addrTemp;
			}
			else if(ip_version == 6){
				addr6Temp = ip6_hdr->ip6_src;
				ip6_hdr->ip6_src = ip6_hdr->ip6_dst;
				ip6_hdr->ip6_dst = addr6Temp;
			}
			//set ack field
			tcphdr->ack_seq = tcphdr->seq + 1;
			//set seq field
			tcphdr->seq = htonl(0);
			//set flags
			tcphdr->syn = 1;
			tcphdr->ack = 1;

			// send packet out after adding HIT
			// the option is already there but
			// it has to be added again since
			// if only the HIT is added, it will
			// overwrite the i1 option that is
			// in the options of TCP
			hip_request_send_tcp_packet(hdr, hdr_size + 4*tcphdr->doff, ip_version, 1, 1);
			*/
			//drop original packet
			return 0;
		}
		else{
			/* A SYN packet without option indicates lack of peer
			 * HIP support. Updating the fw db to NOT_SUPPORTED. */
			state_ha = hip_get_bex_state_from_IPs(&own_ip, &peer_ip, &src_hit,
					     &dst_hit, &src_lsi, &dst_lsi);

			if(state_ha != HIP_STATE_ESTABLISHED)
				firewall_update_entry(NULL, NULL, NULL, &peer_ip,
					       FIREWALL_STATE_BEX_NOT_SUPPORTED);

			//allow packet
			return 1;
		}
	}
	else if( ((tcphdr->syn == 1) && (tcphdr->ack == 1)) ||	 //SYN_ACK
		 ((tcphdr->rst == 1) && (tcphdr->ack == 1)) ||   //RST_ACK
		 ((tcphdr->fin == 1) && (tcphdr->ack == 1))   ){ //FIN_ACK
		//with the new implementation, the i1 is sent out directly
		/*if(tcp_packet_has_i1_option(hdrBytes, 4*tcphdr->doff)){
			// tcp header pointer + 20(minimum header length)
			// + 4(i1 option length in the TCP options)
			memcpy(peer_hit, &hdrBytes[20 + 4], 16);
			hip_request_send_i1_to_hip_peer_from_hipd(
					peer_hit,
					peer_ip);
			//the packet is no more needed
			drop_packet(handle, packetId);
			return;
		}
		else{*/

			/* Signal for normal TCP not
			 * to be blocked with this peer.
			 * Blacklist peer in the hipd db*/
			hip_fw_unblock_and_blacklist(&peer_ip);


			/* updating the fw db if necessary*/
			entry_peer = (firewall_hl_t *)firewall_ip_db_match(&peer_ip);
			//if there is no entry in fw, add a default one
			if(!entry_peer){
				firewall_add_default_entry(&peer_ip);
				entry_peer = (firewall_hl_t *)firewall_ip_db_match(&peer_ip);
			}
			if(entry_peer->bex_state != FIREWALL_STATE_BEX_ESTABLISHED){
				//update the firewall db entry
				HIP_DEBUG("updating fw entry state to NOT_SUPPORTED\n");
				firewall_update_entry(NULL, NULL, NULL, &peer_ip,
					      FIREWALL_STATE_BEX_NOT_SUPPORTED);
			}


			//normal traffic connections should be allowed to be created
			return 1;
		/*}*/
	}

out_err:
	/* Allow rest */
	return 1;
}
static int send_raw_from_one_src(const struct in6_addr *local_addr,
                                 const struct in6_addr *peer_addr,
                                 const in_port_t src_port,
                                 const in_port_t dst_port,
                                 struct hip_common *msg)
{
    int                     err = 0, sa_size, sent, len = 0, dupl, try_again, udp = 0;
    struct sockaddr_storage src, dst;
    int                     src_is_ipv4 = 0, dst_is_ipv4 = 0, memmoved = 0;
    struct sockaddr_in6    *src6        = NULL, *dst6 = NULL;
    struct sockaddr_in     *src4        = NULL, *dst4 = NULL;
    struct in6_addr         my_addr;
    /* Points either to v4 or v6 raw sock */
    int hipfw_raw_sock_output = 0;

    /* Verify the existence of obligatory parameters. */
    HIP_ASSERT(peer_addr != NULL && msg != NULL);

    HIP_DEBUG("Sending %s packet\n",
              hip_message_type_name(hip_get_msg_type(msg)));
    HIP_DEBUG_IN6ADDR("hip_send_raw(): local_addr", local_addr);
    HIP_DEBUG_IN6ADDR("hip_send_raw(): peer_addr", peer_addr);
    HIP_DEBUG("Source port=%d, destination port=%d\n", src_port, dst_port);
    HIP_DUMP_MSG(msg);

    //check msg length
    if (!hip_check_network_msg_len(msg)) {
        err = -EMSGSIZE;
        HIP_ERROR("bad msg len %d\n", hip_get_msg_total_len(msg));
        goto out_err;
    }

    dst_is_ipv4 = IN6_IS_ADDR_V4MAPPED(peer_addr);
    len         = hip_get_msg_total_len(msg);

    /* Some convinient short-hands to avoid too much casting (could be
     * an union as well) */
    src6 = (struct sockaddr_in6 *) &src;
    dst6 = (struct sockaddr_in6 *) &dst;
    src4 = (struct sockaddr_in *) &src;
    dst4 = (struct sockaddr_in *) &dst;

    memset(&src, 0, sizeof(src));
    memset(&dst, 0, sizeof(dst));

    if (dst_port && dst_is_ipv4) {
        HIP_DEBUG("Using IPv4 UDP socket\n");
        hipfw_raw_sock_output = hipfw_nat_sock_output_udp;
        sa_size               = sizeof(struct sockaddr_in);
        udp                   = 1;
    } else if (dst_is_ipv4) {
        HIP_DEBUG("Using IPv4 raw socket\n");
        //hipfw_raw_sock_output = hipfw_raw_sock_output_v4;
        //sa_size             = sizeof(struct sockaddr_in);
    } else {
        HIP_DEBUG("Using IPv6 raw socket\n");
        //hipfw_raw_sock_output = hipfw_raw_sock_output_v6;
        //sa_size             = sizeof(struct sockaddr_in6);
    }

    if (local_addr) {
        HIP_DEBUG("local address given\n");

        memcpy(&my_addr, local_addr, sizeof(struct in6_addr));
    } else {
        HIP_DEBUG("no local address, selecting one\n");
        HIP_IFEL(select_source_address(&my_addr, peer_addr), -1,
                 "Cannot find source address\n");
    }

    src_is_ipv4 = IN6_IS_ADDR_V4MAPPED(&my_addr);

    if (src_is_ipv4) {
        IPV6_TO_IPV4_MAP(&my_addr, &src4->sin_addr);
        src4->sin_family = AF_INET;
        HIP_DEBUG_INADDR("src4", &src4->sin_addr);
    } else {
        memcpy(&src6->sin6_addr, &my_addr,
               sizeof(struct in6_addr));
        src6->sin6_family = AF_INET6;
        HIP_DEBUG_IN6ADDR("src6", &src6->sin6_addr);
    }

    if (dst_is_ipv4) {
        IPV6_TO_IPV4_MAP(peer_addr, &dst4->sin_addr);
        dst4->sin_family = AF_INET;

        HIP_DEBUG_INADDR("dst4", &dst4->sin_addr);
    } else {
        memcpy(&dst6->sin6_addr, peer_addr, sizeof(struct in6_addr));
        dst6->sin6_family = AF_INET6;
        HIP_DEBUG_IN6ADDR("dst6", &dst6->sin6_addr);
    }

    if (src6->sin6_family != dst6->sin6_family) {
        /* @todo: Check if this may cause any trouble.
         * It happens every time we send update packet that contains few locators in msg, one is
         * the IPv4 address of the source, another is IPv6 address of the source. But even if one of
         * them is ok to send raw IPvX to IPvX raw packet, another one cause the trouble, and all
         * updates are dropped.  by Andrey "laser".
         *
         */
        err = -1;
        HIP_ERROR("Source and destination address families differ\n");
        goto out_err;
    }

    hip_zero_msg_checksum(msg);
    if (!udp) {
        msg->checksum = hip_checksum_packet((char *) msg,
                                            (struct sockaddr *) &src,
                                            (struct sockaddr *) &dst);
    }


    /* Handover may cause e.g. on-link duplicate address detection
     * which may cause bind to fail. */

    HIP_IFEL(bind(hipfw_raw_sock_output, (struct sockaddr *) &src, sa_size),
             -1, "Binding to raw sock failed\n");

    /* For some reason, neither sendmsg or send (with bind+connect)
     * do not seem to work properly. Thus, we use just sendto() */

    len = hip_get_msg_total_len(msg);

    if (udp) {
        struct udphdr *uh = (struct udphdr *) msg;

        /* Insert 32 bits of zero bytes between UDP and HIP */
        memmove(((char *) msg) + HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr), msg, len);
        memset(((char *) msg), 0, HIP_UDP_ZERO_BYTES_LEN  + sizeof(struct udphdr));
        len += HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr);

        uh->source = htons(src_port);
        uh->dest   = htons(dst_port);
        uh->len    = htons(len);
        uh->check  = 0;
        memmoved   = 1;
    }

    for (dupl = 0; dupl < 1; dupl++) {
        for (try_again = 0; try_again < 2; try_again++) {
            sent = sendto(hipfw_raw_sock_output, msg, len, 0,
                          (struct sockaddr *) &dst, sa_size);
            if (sent != len) {
                HIP_ERROR("Could not send the all requested" \
                          " data (%d/%d)\n", sent, len);
                HIP_DEBUG("strerror %s\n", strerror(errno));
                sleep(2);
            } else {
                HIP_DEBUG("sent=%d/%d ipv4=%d\n",
                          sent, len, dst_is_ipv4);
                HIP_DEBUG("Packet sent ok\n");
                break;
            }
        }
    }
out_err:

    /* Reset the interface to wildcard or otherwise receiving
     * broadcast messages fails from the raw sockets. A better
     * solution would be to have separate sockets for sending
     * and receiving because we cannot receive a broadcast while
     * sending */
    if (dst_is_ipv4) {
        src4->sin_addr.s_addr = INADDR_ANY;
        src4->sin_family      = AF_INET;
        sa_size               = sizeof(struct sockaddr_in);
    } else {
        struct in6_addr any = IN6ADDR_ANY_INIT;
        src6->sin6_family = AF_INET6;
        ipv6_addr_copy(&src6->sin6_addr, &any);
        sa_size = sizeof(struct sockaddr_in6);
    }
    bind(hipfw_raw_sock_output, (struct sockaddr *) &src, sa_size);

    if (udp && memmoved) {
        /* Remove 32 bits of zero bytes between UDP and HIP */
        len -= HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr);
        memmove((char *) msg, ((char *) msg) + HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr),
                len);
        memset(((char *) msg) + len, 0,
               HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr));
    }

    if (err) {
        HIP_ERROR("strerror: %s\n", strerror(errno));
    }

    return err;
}
Example #5
0
int main_server_udp(int ipv4_sock, int ipv6_sock, in_port_t local_port) {
	/* Use recvmsg/sendmsg instead of recvfrom/sendto because
	   the latter combination may choose a different source
	   HIT for the server */
	int err = 0, on = 1, recvnum, sendnum, is_ipv4 = 0;
	int cmsg_level, cmsg_type, highest_descriptor = -1;
        fd_set read_fdset;
	union {
		struct sockaddr_in in4;
		struct sockaddr_in6 in6;
	} peer_addr, local_addr;
	uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct inet6_pktinfo))];
	uint8_t mylovemostdata[IP_MAXPACKET];
	struct iovec iov;
        struct cmsghdr *cmsg = (struct cmsghdr *) cmsgbuf;
	union {
		struct in_pktinfo *in4;
		struct inet6_pktinfo *in6;
	} pktinfo;
	struct msghdr msg;

	FD_ZERO(&read_fdset);
	FD_SET(ipv4_sock, &read_fdset);
	FD_SET(ipv6_sock, &read_fdset);
	highest_descriptor = maxof(2, ipv4_sock, ipv6_sock);

	printf("=== Server listening INADDR_ANY/IN6ADDR_ANY ===\n");
	
	while(select((highest_descriptor + 1), &read_fdset,
		     NULL, NULL, NULL)) {

		/* XX FIXME: receiving two packets at the same time */

		if (FD_ISSET(ipv4_sock, &read_fdset)) {
			is_ipv4 = 1;
			//FD_CLR(ipv4_sock, &read_fdset);
		} else if (FD_ISSET(ipv6_sock, &read_fdset)) {
			is_ipv4 = 0;
			//FD_CLR(ipv6_sock, &read_fdset);
		} else {
			printf("Unhandled select event\n");
			goto reset;
		}

		msg.msg_name = &peer_addr.in6;
		msg.msg_namelen = sizeof(struct sockaddr_in6);
		msg.msg_iov = &iov;
		msg.msg_iovlen = 1;
		msg.msg_control = cmsgbuf;
		msg.msg_controllen = sizeof(cmsgbuf);
		msg.msg_flags = 0;
		
		iov.iov_base = mylovemostdata;
		iov.iov_len = sizeof(mylovemostdata);
		
		memset(mylovemostdata, 0, sizeof(mylovemostdata));
		memset(&peer_addr, 0, sizeof(peer_addr));
		memset(cmsgbuf, 0, sizeof(cmsgbuf));

		recvnum = recvmsg((is_ipv4 ? ipv4_sock : ipv6_sock), &msg, 0);
		if (recvnum < 0) {
			perror("recvmsg\n");
			goto reset;
		}
		printf("Received %d bytes\n", recvnum);

		//is_ipv4 = IN6_IS_ADDR_V4MAPPED(&peer_addr.in6.sin6_addr);
	
		cmsg_level = (is_ipv4) ? IPPROTO_IP : IPPROTO_IPV6;
		cmsg_type = (is_ipv4) ? IP_PKTINFO : IPV6_2292PKTINFO;
	
		/* Local address comes from ancillary data passed
		 * with msg due to IPV6_PKTINFO socket option */
		for (cmsg=CMSG_FIRSTHDR(&msg); cmsg;
		     cmsg=CMSG_NXTHDR(&msg,cmsg)){
			if ((cmsg->cmsg_level == cmsg_level) &&
			    (cmsg->cmsg_type == cmsg_type)) {
				/* The structure is a union, so this fills
				   also the pktinfo_in6 pointer */
				pktinfo.in4 =
					(struct in_pktinfo *)CMSG_DATA(cmsg);
				break;
			}
		}
	
		if (is_ipv4) {
			local_addr.in4.sin_family = AF_INET;
			local_addr.in4.sin_port = htons(local_port);
			//local_addr.in4.sin_port = peer_addr.in6.sin6_port;
			local_addr.in4.sin_addr.s_addr =
				pktinfo.in4->ipi_addr.s_addr;
			HIP_DEBUG_INADDR("local addr",
					 &local_addr.in4.sin_addr);
			HIP_DEBUG("local port %d\n",
				  ntohs(local_addr.in4.sin_port));
			HIP_DEBUG_INADDR("peer addr",
					 &peer_addr.in4.sin_addr);
			HIP_DEBUG("peer port %d\n",
				  ntohs(peer_addr.in4.sin_port));
			
		} else {
			local_addr.in6.sin6_family = AF_INET6;
			memcpy(&local_addr.in6.sin6_addr,
			       &pktinfo.in6->ipi6_addr,
			       sizeof(struct in6_addr));
			local_addr.in6.sin6_port = htons(local_port);
			HIP_DEBUG_IN6ADDR("local addr",
					  &local_addr.in6.sin6_addr);
			HIP_DEBUG("local port %d\n",
				  ntohs(local_addr.in6.sin6_port));
			HIP_DEBUG_IN6ADDR("peer addr",
					  &peer_addr.in6.sin6_addr);
			HIP_DEBUG("peer port %d\n",
				  ntohs(peer_addr.in6.sin6_port));
		}

		err = udp_send_msg((is_ipv4 ? ipv4_sock : ipv6_sock),
				   mylovemostdata, recvnum,
				   (struct sockaddr *) &local_addr,
				   (struct sockaddr *) &peer_addr);
		if (err) {
			printf("Failed to echo data back\n");
		}

	reset:

		FD_ZERO(&read_fdset);
		FD_SET(ipv4_sock, &read_fdset);
		FD_SET(ipv6_sock, &read_fdset);
	}

out_err:
	return err;
}
Example #6
0
File: cache.c Project: surki/hipl
/**
 * firewall_cache_db_match:
 * Search in the cache database the given peers of hits, lsis or ips
 */
int firewall_cache_db_match(    struct in6_addr *hit_our,
				struct in6_addr *hit_peer,
				hip_lsi_t       *lsi_our,
				hip_lsi_t       *lsi_peer,
				struct in6_addr *ip_our,
				struct in6_addr *ip_peer,
				int *state){
	int i, err = 0, entry_in_cache = 0;
	firewall_cache_hl_t *this;
	hip_list_t *item, *tmp;
	struct in6_addr all_zero_v6 = {0};
	struct in_addr  all_zero_v4 = {0};
	struct hip_common *msg = NULL;
	firewall_cache_hl_t *ha_curr = NULL;
	firewall_cache_hl_t *ha_match = NULL;
	struct hip_tlv_common *current_param = NULL;

	HIP_ASSERT( (hit_our && hit_peer) ||
		    (lsi_our && lsi_peer)    );

	if(hit_peer){
		ha_match = (firewall_cache_hl_t *)hip_ht_find(
						firewall_cache_db,
						(void *)hit_peer);
		if(ha_match){
			HIP_DEBUG("Matched using hash\n");
			entry_in_cache = 1;
			goto out_err;
		}
	}

	HIP_DEBUG("Check firewall cache db\n");

	HIP_LOCK_HT(&firewall_cache_db);

	list_for_each_safe(item, tmp, firewall_cache_db, i){
		this = list_entry(item);

		if( lsi_our && lsi_peer) {
		  HIP_DEBUG_INADDR("this->our", &this->lsi_our.s_addr);
		  HIP_DEBUG_INADDR("this->peer", &this->lsi_peer.s_addr);
		  HIP_DEBUG_INADDR("our", lsi_our);
		  HIP_DEBUG_INADDR("peer", lsi_peer);
		}

		if( hit_our && hit_peer &&
		    (ipv6_addr_cmp(hit_peer, &this->hit_peer) == 0 ) &&
		    (ipv6_addr_cmp(hit_our,  &this->hit_our)  == 0 )    ){
			ha_match = this;
			break;
		}
		if( lsi_our && lsi_peer &&
		    lsi_peer->s_addr == this->lsi_peer.s_addr &&
		    lsi_our->s_addr  == this->lsi_our.s_addr     ){
			ha_match = this;
			break;
		}
		if( ip_our && ip_peer &&
		    ip_peer->s6_addr == this->ip_peer.s6_addr &&
		    ip_our->s6_addr  == this->ip_our.s6_addr     ) {
			ha_match = this;
			break;
		}
	}