Beispiel #1
0
void *pkt_fill_eid(
        void                    *offset,
        lispd_mapping_elt       *mapping)
{
    uint16_t                *afi_ptr;
    lispd_pkt_lcaf_t        *lcaf_ptr;
    lispd_pkt_lcaf_iid_t    *iid_ptr;
    void                    *eid_ptr;
    int                     eid_addr_len;

    afi_ptr = (uint16_t *)offset;
    eid_addr_len = get_addr_len(mapping->eid_prefix.afi);

    /* For negative IID values, we skip LCAF/IID field */
    if (mapping->iid < 0) {
        *afi_ptr = htons(get_lisp_afi(mapping->eid_prefix.afi, NULL));
        eid_ptr  = CO(offset, sizeof(uint16_t));
    } else {
        *afi_ptr = htons(LISP_AFI_LCAF);
        lcaf_ptr = (lispd_pkt_lcaf_t *) CO(offset, sizeof(uint16_t));
        iid_ptr  = (lispd_pkt_lcaf_iid_t *) CO(lcaf_ptr, sizeof(lispd_pkt_lcaf_t));
        eid_ptr  = (void *) CO(iid_ptr, sizeof(lispd_pkt_lcaf_iid_t));

        lcaf_ptr->rsvd1 = 0;
        lcaf_ptr->flags = 0;
        lcaf_ptr->type  = 2;
        lcaf_ptr->rsvd2 = 0;    /* This can be IID mask-len, not yet supported */
        lcaf_ptr->len   = htons(sizeof(lispd_pkt_lcaf_iid_t) + eid_addr_len);

        iid_ptr->iid = htonl(mapping->iid);
        iid_ptr->afi = htons(mapping->eid_prefix.afi);
    }

    if ((copy_addr(eid_ptr,&(mapping->eid_prefix), 0)) == 0) {
        LISPD_LOG(LISP_LOG_DEBUG_3, "copy_addr failed");
        return NULL;
    }

    return CO(eid_ptr, eid_addr_len);
}
Beispiel #2
0
int get_prefix_len(int afi)
{
    return(get_addr_len(afi) * 8);
}
 int process_map_request_msg(
         uint8_t        *packet,
         lisp_addr_t    *local_rloc,
         uint16_t       dst_port) {

     lispd_mapping_elt          *source_mapping          = NULL;
     lispd_map_cache_entry      *map_cache_entry        = NULL;
     lisp_addr_t                itr_rloc[32];
     lisp_addr_t                *remote_rloc            = NULL;
     int                        itr_rloc_count          = 0;
     int                        itr_rloc_afi            = 0;
     uint8_t                    *cur_ptr                = NULL;
     int                        len                     = 0;
     lispd_pkt_map_request_t    *msg                    = NULL;
     lisp_addr_t                aux_eid_prefix;
     int                        aux_eid_prefix_length   = 0;
     int                        aux_iid                 = -1;
     int                        i                       = 0;

     /* If the packet is an Encapsulated Map Request, verify checksum and remove the inner IP header */

     if (((lisp_encap_control_hdr_t *) packet)->type == LISP_ENCAP_CONTROL_TYPE) {
         if ((err = process_encapsulated_map_request_headers(packet,&len,&dst_port)) != GOOD){
             return (BAD);
         }
         msg = (lispd_pkt_map_request_t *) CO(packet, len);
     } else if (((lispd_pkt_map_request_t *) packet)->type == LISP_MAP_REQUEST) {
         msg = (lispd_pkt_map_request_t *) packet;
     } else
         return(BAD); //we should never reach this return()

     /*
      * Source EID is optional in general, but required for SMRs
      */

     /* Auxiliar lispd_mapping_elt created to be filled with pkt_process_eid_afi */
     source_mapping = new_local_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid);
     if (source_mapping == NULL){
         return (BAD);
     }
     cur_ptr = (uint8_t *)&(msg->source_eid_afi);
     if (pkt_process_eid_afi(&cur_ptr, source_mapping) != GOOD){
         free_mapping_elt(source_mapping, FALSE);
         return (BAD);
     }
     /* If packet is a Solicit Map Request, process it */

     if (source_mapping->eid_prefix.afi != 0 && msg->solicit_map_request) {
         /*
          * Lookup the map cache entry that match with the source EID prefix of the message
          */
         map_cache_entry = lookup_map_cache(source_mapping->eid_prefix);
         if (map_cache_entry == NULL){
             free_mapping_elt(source_mapping, FALSE);
             return (BAD);
         }

         /*
          * Check IID of the received Solicit Map Request match the IID of the map cache
          */
         if (map_cache_entry->mapping->iid != source_mapping->iid){
             lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_request_msg: The IID of the received Solicit Map Request doesn't match the IID of "
                     "the entry in the map cache");
             free_mapping_elt(source_mapping, FALSE);
             return (BAD);
         }
         /* Free source_mapping once we have a valid map cache entry */
         free_mapping_elt(source_mapping, FALSE);

         /*
          * Only accept a solicit map request for an EID prefix ->If node which generates the message
          * has more than one locator, it probably will generate a solicit map request for each one.
          * Only the first one is considered.
          * If map_cache_entry->nonces is different of null, we have already received a solicit map request
          */
         if (map_cache_entry->nonces == NULL){
             solicit_map_request_reply(NULL,(void *)map_cache_entry);
         }
         /* Return here only if RLOC probe bit is not set */
         if (!msg->rloc_probe){
             return(GOOD);
         }
     }

     /* Get the array of ITR-RLOCs */
     itr_rloc_count = msg->additional_itr_rloc_count + 1;
     for (i = 0; i < itr_rloc_count; i++) {
         itr_rloc_afi = lisp2inetafi(ntohs(*(uint16_t *)cur_ptr));
         cur_ptr = CO(cur_ptr, sizeof(uint16_t));
         memcpy(&(itr_rloc[i].address), cur_ptr, get_addr_len(itr_rloc_afi));
         itr_rloc[i].afi = itr_rloc_afi;
         cur_ptr = CO(cur_ptr, get_addr_len(itr_rloc_afi));
         // Select the first accessible rloc from the ITR-RLOC list
         if (remote_rloc == NULL){
             if (local_rloc != NULL && itr_rloc[i].afi ==  local_rloc->afi){
                 remote_rloc = &itr_rloc[i];
             }
         }
     }
     if (remote_rloc == NULL){
         lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_request_msg: Couldn't generate map replay - "
                 "No supported afi in the list of ITR-RLOCS");
         return (BAD);
     }

     /* Process record and send Map Reply for each one */
     for (i = 0; i < msg->record_count; i++) {
         process_map_request_record(&cur_ptr, local_rloc, remote_rloc, dst_port, msg->rloc_probe, msg->nonce);
     }
     return(GOOD);
 }
Beispiel #4
0
int
extract_nat_lcaf_data(uint8_t *offset, uint16_t *ms_udp_port,
        uint16_t *etr_udp_port, lisp_addr_t *global_etr_rloc,
        lisp_addr_t *ms_rloc, lisp_addr_t *private_etr_rloc,
        rtr_locators_list_t **rtr_list, uint32_t *length)
{
    lcaf_hdr_t *pkt_lcaf;
    lispd_pkt_nat_lcaf_t *pkt_nat_lcaf;
    rtr_locators_list_t *rtr_locator_list = NULL;
    rtr_locator_t *rtr_locator;
    lisp_addr_t rtr_address = {.afi=LM_AFI_NO_ADDR};
    uint8_t *ptr = offset;
    uint32_t lcaf_length;
    uint32_t cumulative_add_length;


    pkt_lcaf = (lcaf_hdr_t *)ptr;

    if (pkt_lcaf->type != LCAF_NATT){
        LMLOG(LDBG_2, "extract_nat_lcaf_data: Packet doesn't have NAT LCAF address");
        return (BAD);
    }

    lcaf_length = ntohs(pkt_lcaf->len);

    ptr = CO(ptr,sizeof(lcaf_hdr_t));
    pkt_nat_lcaf = (lispd_pkt_nat_lcaf_t *)ptr;

    *ms_udp_port = ntohs(pkt_nat_lcaf->ms_udp_port);
    *etr_udp_port = ntohs(pkt_nat_lcaf->etr_udp_port);

    cumulative_add_length = FIELD_PORT_LEN * 2; /* 2 UDP ports */

    ptr = CO(ptr,sizeof(lispd_pkt_nat_lcaf_t));

    /* Extract the Global ETR RLOC */


    if ((extract_lisp_address(ptr, global_etr_rloc)) != GOOD){
        LMLOG(LDBG_2, "extract_nat_lcaf_data: Couldn't process Global ETR RLOC");
        return (BAD);
    }

    cumulative_add_length += get_addr_len(global_etr_rloc->afi) + FIELD_AFI_LEN;

    ptr = CO(ptr, get_addr_len(global_etr_rloc->afi) + FIELD_AFI_LEN);

    /* Extract the MS RLOC */

    if ((extract_lisp_address(ptr, ms_rloc)) != GOOD){
        LMLOG(LDBG_2, "extract_nat_lcaf_data: Couldn't process MS RLOC");
        return (BAD);
    }

    cumulative_add_length += get_addr_len(ms_rloc->afi) + FIELD_AFI_LEN;

    ptr = CO(ptr, get_addr_len(ms_rloc->afi) + FIELD_AFI_LEN);

    /* Extract the Private ETR RLOC */

    if (extract_lisp_address(ptr, private_etr_rloc) != GOOD){
        LMLOG(LDBG_2, "extract_nat_lcaf_data: Couldn't process private ETR RLOC");
        return (BAD);
    }

    cumulative_add_length += get_addr_len(private_etr_rloc->afi) + FIELD_AFI_LEN;

    ptr = CO(ptr, get_addr_len(private_etr_rloc->afi) + FIELD_AFI_LEN);


    /* Extract the list of RTR RLOCs */


    while (cumulative_add_length < lcaf_length) {
        if ((extract_lisp_address(ptr, &rtr_address))!= GOOD){
            LMLOG(LDBG_2, "extract_nat_lcaf_data: Coudln't process rtr address");
            return (BAD);
        }
        rtr_locator = rtr_locator_new (rtr_address);
        if (rtr_locator == NULL){
            LMLOG(LDBG_2, "extract_nat_lcaf_data: Error malloc lispd_rtr_locator");
            return (BAD);
        }
        if ((rtr_list_add(&rtr_locator_list,rtr_locator))!=GOOD){
            LMLOG(LDBG_2, "extract_nat_lcaf_data: Error adding rtr_locator");
            return (BAD);
        }
        // Return the first element of the list
        if (*rtr_list == NULL){
            *rtr_list = rtr_locator_list;
        }

        LMLOG(LDBG_3, "Added RTR with RLOC %s to the list of RTRs",
                get_char_from_lisp_addr_t(rtr_locator->address));

        cumulative_add_length += get_addr_len(rtr_locator->address.afi) + FIELD_AFI_LEN;

        ptr = CO(ptr, get_addr_len(rtr_locator->address.afi) + FIELD_AFI_LEN);

    }

    *length = sizeof(lcaf_hdr_t) + lcaf_length;

    return (GOOD);
}