Пример #1
0
/* Process encapsulated map request header:  lisp header and the interal IP and
 * UDP header */
int
lisp_msg_ecm_decap(lbuf_t *pkt, uint16_t *src_port)
{
    uint16_t ipsum = 0;
    uint16_t udpsum = 0;
    int udp_len = 0;
    struct udphdr *udph;
    struct ip *iph;

    /* this is the new start of the packet */
    lisp_msg_pull_ecm_hdr(pkt);
    /* Set and extract inner layer 3 packet */
    lbuf_reset_l3(pkt);
    iph = pkt_pull_ip(pkt);
    /* Set and extract inner layer 4 packet */
    lbuf_reset_l4(pkt);
    udph = pkt_pull_udp(pkt);

    /* Set the beginning of the LISP msg*/
    lbuf_reset_lisp(pkt);

    /* This should overwrite the external port (dst_port in map-reply =
     * inner src_port in encap map-request) */
    *src_port = ntohs(udph->source);

 #ifdef BSD
    udp_len = ntohs(udph->uh_ulen);
 #else
    udp_len = ntohs(udph->len);
 #endif

    /* Verify the checksums. */
    if (iph->ip_v == IPVERSION) {
        ipsum = ip_checksum((uint16_t *) iph, sizeof(struct ip));
        if (ipsum != 0) {
            OOR_LOG(LDBG_2, "IP checksum failed.");
        }

    }

    /* Verify UDP checksum only if different from 0.
     * This means we ACCEPT UDP checksum 0! */
    if (udph->check != 0) {
        udpsum = udp_checksum(udph, udp_len, iph,
                ip_version_to_sock_afi(iph->ip_v));
        if (udpsum != 0) {
            OOR_LOG(LDBG_2, "UDP checksum failed.");
            return (BAD);
        }
    }

    OOR_LOG(LDBG_2, "%s, inner IP: %s -> %s, inner UDP: %d -> %d",
            lisp_msg_hdr_to_char(pkt),
            ip_to_char(&iph->ip_src, ip_version_to_sock_afi(iph->ip_v)),
            ip_to_char(&iph->ip_dst, ip_version_to_sock_afi(iph->ip_v)),
            ntohs(udph->source), ntohs(udph->dest));

    return (GOOD);
}
Пример #2
0
int
tun_read_and_decap_pkt(int sock, lbuf_t *b, uint32_t *iid)
{
    uint8_t ttl = 0, tos = 0;
    int afi;
    struct udphdr *udph;
    lisp_data_hdr_t *lisph;
    vxlan_gpe_hdr_t *vxlanh;
    int port;

    if (sock_data_recv(sock, b, &afi, &ttl, &tos) != GOOD) {
        return(BAD);
    }

    if (afi == AF_INET){
        /* With input RAW UDP sockets in IPv4, we get the whole external
         * IPv4 packet */
        lbuf_reset_ip(b);
        pkt_pull_ip(b);
        lbuf_reset_udp(b);
    }else{
        /* With input RAW UDP sockets in IPv6, we get the whole external
         * UDP packet */
        lbuf_reset_udp(b);
    }

    udph = pkt_pull_udp(b);

    /* FILTER UDP: with input RAW UDP sockets, we receive all UDP packets,
     * we only want LISP data ones */
    switch (ntohs(udph->dest)){
    case LISP_DATA_PORT:
        lisph = lisp_data_pull_hdr(b);
        if (LDHDR_LSB_BIT(lisph)){
            *iid = lisp_data_hdr_get_iid(lisph);
        }else{
            *iid = 0;
        }

        port = LISP_DATA_PORT;
        break;
    case VXLAN_GPE_DATA_PORT:

        vxlanh = vxlan_gpe_data_pull_hdr(b);
        if (VXLAN_HDR_VNI_BIT(vxlanh)){
            *iid = vxlan_gpe_hdr_get_vni(vxlanh);
        }
        port = VXLAN_GPE_DATA_PORT;
        break;
    default:
        return (ERR_NOT_ENCAP);
    }

    /* RESET L3: prepare for output */
    lbuf_reset_l3(b);

    /* UPDATE IP TOS and TTL. Checksum is also updated for IPv4
     * NOTE: we always assume an IP payload*/
    ip_hdr_set_ttl_and_tos(lbuf_data(b), ttl, tos);

    OOR_LOG(LDBG_3, "INPUT (%d): %s",port, ip_src_and_dst_to_char(lbuf_l3(b),
            "Inner IP: %s -> %s"));

    return(GOOD);
}