/** * 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; }
/** * 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); } }
/** * 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; }
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; }
/** * 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; } }