int forward_native( char *packet_buf, int pckt_length ) { int ret = 0; int output_socket = 0; int packet_afi = 0; packet_afi = get_afi_from_packet((uint8_t *)packet_buf); output_socket = get_default_output_socket(packet_afi); if (output_socket == -1){ lispd_log_msg(LISP_LOG_DEBUG_2, "fordward_native: No output interface for afi %d",packet_afi); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_3, "Fordwarding native for destination %s", get_char_from_lisp_addr_t(extract_dst_addr_from_packet(packet_buf))); ret = send_packet(output_socket,packet_buf,pckt_length); return (ret); }
int fordward_to_petr( char *original_packet, int original_packet_length, lispd_mapping_elt *src_mapping, packet_tuple tuple) { lispd_locator_elt *outer_src_locator = NULL; lispd_locator_elt *outer_dst_locator = NULL; char *encap_packet = NULL; int encap_packet_size = 0; int output_socket = 0; if (proxy_etrs == NULL){ lispd_log_msg(LISP_LOG_DEBUG_3, "fordward_to_petr: Proxy-etr not found"); return (BAD); } if ((select_src_rmt_locators_from_balancing_locators_vec ( src_mapping, proxy_etrs->mapping, tuple, &outer_src_locator, &outer_dst_locator)) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_3, "fordward_to_petr: No Proxy-etr compatible with local locators afi"); return (BAD); } if (encapsulate_packet(original_packet, original_packet_length, outer_src_locator->locator_addr, outer_dst_locator->locator_addr, LISP_DATA_PORT, LISP_DATA_PORT, 0, &encap_packet, &encap_packet_size) != GOOD){ return (BAD); } output_socket = ((lcl_locator_extended_info *)(outer_src_locator->extended_info))->out_socket; if (send_packet (output_socket,encap_packet,encap_packet_size ) != GOOD){ free (encap_packet ); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_3, "Fordwarded eid %s to petr",get_char_from_lisp_addr_t(extract_dst_addr_from_packet(original_packet))); free (encap_packet ); return (GOOD); }
void process_input_packet(int fd, int afi, int tun_receive_fd) { uint8_t *packet = NULL; int length = 0; uint8_t ttl = 0; uint8_t tos = 0; struct lisphdr *lisp_hdr = NULL; struct iphdr *iph = NULL; struct ip6_hdr *ip6h = NULL; struct udphdr *udph = NULL; if ((packet = (uint8_t *) malloc(MAX_IP_PACKET))==NULL){ lispd_log_msg(LISP_LOG_ERR,"process_input_packet: Couldn't allocate space for packet: %s", strerror(errno)); return; } memset(packet,0,MAX_IP_PACKET); if (get_data_packet (fd, afi, packet, &length, &ttl, &tos) == BAD){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_input_packet: get_data_packet error: %s", strerror(errno)); free(packet); return; } if(afi == AF_INET){ /* With input RAW UDP sockets in IPv4, we get the whole external IPv4 packet */ udph = (struct udphdr *) CO(packet,sizeof(struct iphdr)); }else{ /* With input RAW UDP sockets in IPv6, we get the whole external UDP packet */ udph = (struct udphdr *) packet; } /* With input RAW UDP sockets, we receive all UDP packets, we only want lisp data ones */ if(ntohs(udph->dest) != LISP_DATA_PORT){ free(packet); //lispd_log_msg(LISP_LOG_DEBUG_3,"INPUT (No LISP data): UDP dest: %d ",ntohs(udph->dest)); return; } lisp_hdr = (struct lisphdr *) CO(udph,sizeof(struct udphdr)); length = length - sizeof(struct udphdr) - sizeof(struct lisphdr); iph = (struct iphdr *) CO(lisp_hdr,sizeof(struct lisphdr)); lispd_log_msg(LISP_LOG_DEBUG_3,"INPUT (4341): Inner src: %s | Inner dst: %s ", get_char_from_lisp_addr_t(extract_src_addr_from_packet((char *)iph)), get_char_from_lisp_addr_t(extract_dst_addr_from_packet((char *)iph))); if (iph->version == 4) { if(ttl!=0){ /*XXX It seems that there is a bug in uClibc that causes ttl=0 in OpenWRT. This is a quick workaround */ iph->ttl = ttl; } iph->tos = tos; /* We need to recompute the checksum since we have changed the TTL and TOS header fields */ iph->check = 0; /* New checksum must be computed with the checksum header field with 0s */ iph->check = ip_checksum((uint16_t*) iph, sizeof(struct iphdr)); }else{ ip6h = ( struct ip6_hdr *) iph; if(ttl!=0){ /*XXX It seems that there is a bug in uClibc that causes ttl=0 in OpenWRT. This is a quick workaround */ ip6h->ip6_hops = ttl; /* ttl = Hops limit in IPv6 */ } IPV6_SET_TC(ip6h,tos); /* tos = Traffic class field in IPv6 */ } if ((write(tun_receive_fd, iph, length)) < 0){ lispd_log_msg(LISP_LOG_DEBUG_2,"lisp_input: write error: %s\n ", strerror(errno)); } free(packet); }