Example #1
0
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);

}
Example #2
0
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);
}
Example #3
0
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);
}