Пример #1
0
void *pkt_fill_mapping_record(
    lispd_pkt_mapping_record_t              *rec,
    lispd_mapping_elt                       *mapping,
    lisp_addr_t                             *probed_rloc)
{
    int                                     cpy_len             = 0;
    lispd_pkt_mapping_record_locator_t      *loc_ptr            = NULL;
    lispd_locators_list                     *locators_list[2]   = {NULL,NULL};
    lispd_locator_elt                       *locator            = NULL;
    int                                     ctr                 = 0;

    if ((rec == NULL) || (mapping == NULL))
        return NULL;

    rec->ttl                    = htonl(DEFAULT_MAP_REGISTER_TIMEOUT);
    rec->locator_count          = mapping->locator_count;
    rec->eid_prefix_length      = mapping->eid_prefix_length;
    rec->action                 = 0;
    rec->authoritative          = 1;
    rec->version_hi             = 0;
    rec->version_low            = 0;

    loc_ptr = (lispd_pkt_mapping_record_locator_t *)pkt_fill_eid(&(rec->eid_prefix_afi), mapping);

    if (loc_ptr == NULL){
        return NULL;
    }

    locators_list[0] = mapping->head_v4_locators_list;
    locators_list[1] = mapping->head_v6_locators_list;
    for (ctr = 0 ; ctr < 2 ; ctr++){
        while (locators_list[ctr]) {
            locator              = locators_list[ctr]->locator;
            loc_ptr->priority    = locator->priority;
            loc_ptr->weight      = locator->weight;
            loc_ptr->mpriority   = locator->mpriority;
            loc_ptr->mweight     = locator->mweight;
            loc_ptr->local       = 1;
            if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){
                loc_ptr->probed  = 1;
            }
            loc_ptr->reachable   = *(locator->state);
            loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL));

            if ((cpy_len = copy_addr((void *) CO(loc_ptr,
                    sizeof(lispd_pkt_mapping_record_locator_t)), locator->locator_addr, 0)) == 0) {
                LISPD_LOG(LISP_LOG_DEBUG_3, "copy_addr failed for locator %s",
                        get_char_from_lisp_addr_t(*(locator->locator_addr)));
                return(NULL);
            }

            loc_ptr = (lispd_pkt_mapping_record_locator_t *)
                            CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len));
            locators_list[ctr] = locators_list[ctr]->next;
        }
    }
    return (void *)loc_ptr;
}
Пример #2
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);
}
Пример #3
0
/*
 * build_map_reply()
 *
 * Create the response packet given a locator chain and
 * destination address.
 */
lispd_pkt_map_reply_t *build_map_reply(uint32_t probe_source, int probe,
                                       lispd_locator_chain_t *loc_chain,
                                       char *nonce,
                                       int *len)
{
    lispd_pkt_map_reply_t     *reply_pkt;
    lispd_pkt_map_reply_eid_prefix_record_t *eid_rec;
    lispd_pkt_map_reply_locator_record_t *loc_rec;
    lisp_addr_t               loc_addr;
    lispd_locator_chain_elt_t *locator_chain_elt;
    lispd_if_t                *intf;
    uint32_t                   total_loc_length   = 0;
    uint32_t                   eid_afi           = 0;
    uint32_t                   pkt_length        = 0;
    uint32_t                   addr_len          = 0;
    uint32_t                   afi_len           = 0;
    uint32_t                   loc_count         = 0;
    uint32_t                   loc_afi           = 0;

    /*
     * Like in map registers, assume one record with
     * several locators.
     */
    locator_chain_elt = loc_chain->head;
    total_loc_length = get_locator_length_and_count(locator_chain_elt, &loc_count);

    eid_afi = get_lisp_afi(loc_chain->eid_prefix.afi, &afi_len);

    pkt_length = sizeof(lispd_pkt_map_reply_t) +
                 sizeof(lispd_pkt_map_reply_eid_prefix_record_t) +  // XXX Just one for now
                 afi_len +
                 (loc_count *
                  sizeof(lispd_pkt_map_reply_locator_record_t)) +
                 total_loc_length;

    if ((reply_pkt = (lispd_pkt_map_reply_t *)malloc(pkt_length)) == NULL) {
        log_msg(INFO, "malloc (map-reply packet): %s", strerror(errno));
        return NULL;
    }

    memset(reply_pkt, 0, pkt_length);

    reply_pkt->type = LISP_MAP_REPLY;
    reply_pkt->probe = probe;
    reply_pkt->echononce = 0;
    reply_pkt->count = 1;

    memcpy(&reply_pkt->nonce, nonce, sizeof(uint64_t));

    eid_rec = (lispd_pkt_map_reply_eid_prefix_record_t *)CO(reply_pkt,
                                                            sizeof(lispd_pkt_map_reply_t));

    eid_rec->act = 0;
    eid_rec->authoritative = 1;
    eid_rec->loc_count = loc_count;
    eid_rec->eid_afi = htons(eid_afi);
    eid_rec->eid_masklen = loc_chain->eid_prefix_length;
    eid_rec->ttl = htonl(DEFAULT_MAP_REGISTER_TIMEOUT); // Should be different for Map-replies?
    eid_rec->version = 0;

    /*
     * Advance to the prefix
     */
    if ((addr_len = copy_addr((void *)CO(eid_rec, sizeof(lispd_pkt_map_reply_eid_prefix_record_t)),
                              &(loc_chain->eid_prefix),
                              loc_chain->eid_prefix.afi,
                              0)) == 0) {
        log_msg(INFO, "eid prefix (%s) has an unknown afi (%d)",
               loc_chain->eid_name,
               loc_chain->eid_prefix.afi);
        return NULL;
    }

    /*
     * skip over the fixed part and eid prefix, and build
     * the locators
     */
    loc_rec = (lispd_pkt_map_reply_locator_record_t *)
        CO(eid_rec,(sizeof(lispd_pkt_mapping_record_t) + addr_len));

    while (locator_chain_elt) {

        intf = locator_chain_elt->interface;

        /*
         * Check interface status and get the address
         */
        if (intf && (intf->flags & IFF_UP)) {
            if (intf->nat_type != NATOff) {
                if (is_nat_complete(intf)) { // Skip untranslated NAT interfaces
                    memcpy(&loc_addr, &intf->nat_address.address.ip.s_addr, sizeof(lisp_addr_t));
                } else {
                    locator_chain_elt = locator_chain_elt->next;
                    continue;
                }
            } else if (intf->address.address.ip.s_addr != 0) {  // IPV4 only and local interface only XXX
                memcpy(&loc_addr, &intf->address, sizeof(lisp_addr_t));
            } else {
                locator_chain_elt = locator_chain_elt->next;
                continue; // No address? Not included.
            }
        } else {
            locator_chain_elt = locator_chain_elt->next;
            continue;
        } // Need to handle non-local locators XXX

        loc_rec->priority    = locator_chain_elt->priority;
        loc_rec->weight      = locator_chain_elt->weight;
        loc_rec->mpriority   = locator_chain_elt->mpriority;
        loc_rec->mweight     = locator_chain_elt->mweight;
        loc_rec->reachable   = 1;
        loc_rec->probe       = probe;
        loc_rec->local       = 1;
        if (intf) {
            loc_afi = intf->address.afi;
        } else {
            loc_afi = locator_chain_elt->locator_afi;
        }
        loc_rec->loc_afi = htons(get_lisp_afi(loc_afi, NULL));

        /*
         * skip over the mapping record locator, and copy the locator
         * to that address...
         */
        if ((addr_len = copy_addr((void *)
                             CO(loc_rec,
                                sizeof(lispd_pkt_map_reply_locator_record_t)),
                             &(loc_addr),
                             loc_afi,
                             0)) == 0) {
            log_msg(INFO, "locator (%s) has an unknown afi (%d)",
                   locator_chain_elt->locator_name,
                   locator_chain_elt->locator_afi);
            return NULL;
        }

        /*
         * get the next locator in the chain and wind
         * loc_rec to the right place
         */
        loc_rec = (lispd_pkt_map_reply_locator_record_t *)
            CO(loc_rec, (sizeof(lispd_pkt_map_reply_locator_record_t) + addr_len));

        locator_chain_elt = locator_chain_elt->next;
    }
    *len = pkt_length;
    return reply_pkt;
}
Пример #4
0
uint8_t *build_map_request_pkt(
        lispd_mapping_elt       *requested_mapping,
        lisp_addr_t             *src_eid,
        uint8_t                 encap,
        uint8_t                 probe,
        uint8_t                 solicit_map_request,/* boolean really */
        uint8_t                 smr_invoked,
        int                     *len,               /* return length here */
        uint64_t                *nonce)             /* return nonce here */
{

    uint8_t                                     *packet                 = NULL;
    uint8_t                                     *mr_packet              = NULL;
    lispd_pkt_map_request_t                     *mrp                    = NULL;
    lispd_pkt_mapping_record_t                  *rec                    = NULL;
    lispd_pkt_map_request_itr_rloc_t            *itr_rloc               = NULL;
    lispd_pkt_map_request_eid_prefix_record_t   *request_eid_record     = NULL;
    uint8_t                                     *cur_ptr                = NULL;

    int                     map_request_msg_len = 0;
    int                     ctr                 = 0;
    int                     cpy_len             = 0;
    int                     locators_ctr        = 0;

    lispd_mapping_elt       *src_mapping        = NULL;
    lispd_locators_list     *locators_list[2]   = {NULL,NULL};
    lispd_locator_elt       *locator            = NULL;
    lisp_addr_t             *ih_src_ip          = NULL;

    /*
     * Lookup the local EID prefix from where we generate the message.
     * src_eid is null for RLOC probing and refreshing map_cache -> Source-EID AFI = 0
     */
    if (src_eid != NULL){
        src_mapping = lookup_eid_in_db(*src_eid);
        if (!src_mapping){
            lispd_log_msg(LISP_LOG_DEBUG_2,"build_map_request_pkt: Source EID address not found in local data base - %s -",
                    get_char_from_lisp_addr_t(*src_eid));
            return (NULL);
        }

    }

    /* Calculate the packet size and reserve memory */
    map_request_msg_len = get_map_request_length(requested_mapping,src_mapping);
    *len = map_request_msg_len;

    if ((packet = malloc(map_request_msg_len)) == NULL){
        lispd_log_msg(LISP_LOG_WARNING,"build_map_request_pkt: Unable to allocate memory for Map Request (packet_len): %s", strerror(errno));
        return (NULL);
    }
    memset(packet, 0, map_request_msg_len);


    cur_ptr = packet;

    mrp = (lispd_pkt_map_request_t *)cur_ptr;

    mrp->type                      = LISP_MAP_REQUEST;
    mrp->authoritative             = 0;
    if (src_eid != NULL)
        mrp->map_data_present      = 1;
    else
        mrp->map_data_present      = 0;

    if (probe)
        mrp->rloc_probe            = 1;
    else
        mrp->rloc_probe            = 0;

    if (solicit_map_request)
        mrp->solicit_map_request   = 1;
    else
        mrp->solicit_map_request   = 0;

    if (smr_invoked)
        mrp->smr_invoked           = 1;
    else
        mrp->smr_invoked           = 0;

    mrp->additional_itr_rloc_count = 0;     /* To be filled later  */
    mrp->record_count              = 1;     /* XXX: assume 1 record */
    mrp->nonce = build_nonce((unsigned int) time(NULL));
    *nonce                         = mrp->nonce;

    if (src_eid != NULL){
        cur_ptr = pkt_fill_eid(&(mrp->source_eid_afi),src_mapping);

        /* Add itr-rlocs */
        locators_list[0] = src_mapping->head_v4_locators_list;
        locators_list[1] = src_mapping->head_v6_locators_list;

        for (ctr=0 ; ctr < 2 ; ctr++){
            while (locators_list[ctr]){
                locator = locators_list[ctr]->locator;
                if (*(locator->state)==DOWN){
                    locators_list[ctr] = locators_list[ctr]->next;
                    continue;
                }
                /* Remove ITR locators behind NAT: No control message (4342) can be received in these interfaces */
                if (((lcl_locator_extended_info *)locator->extended_info)->rtr_locators_list != NULL){
                    locators_list[ctr] = locators_list[ctr]->next;
                    continue;
                }

                itr_rloc = (lispd_pkt_map_request_itr_rloc_t *)cur_ptr;
                itr_rloc->afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL));
                /* Add rloc address */
                cur_ptr = CO(itr_rloc,sizeof(lispd_pkt_map_request_itr_rloc_t));
                cpy_len = copy_addr((void *) cur_ptr ,locator->locator_addr, 0);
                cur_ptr = CO(cur_ptr, cpy_len);
                locators_ctr ++;
                locators_list[ctr] = locators_list[ctr]->next;
            }
        }
    }else {
        // XXX If no source EID is used, then we only use one ITR-RLOC for IPv4 and one for IPv6-> Default control RLOC
        mrp->source_eid_afi = 0;
        cur_ptr = CO(mrp, sizeof(lispd_pkt_map_request_t));
        if (default_ctrl_iface_v4 != NULL){
            itr_rloc = (lispd_pkt_map_request_itr_rloc_t *)cur_ptr;
            itr_rloc->afi = htons((uint16_t)LISP_AFI_IP);
            cur_ptr = CO(itr_rloc,sizeof(lispd_pkt_map_request_itr_rloc_t));
            cpy_len = copy_addr((void *) cur_ptr ,default_ctrl_iface_v4->ipv4_address, 0);
            cur_ptr = CO(cur_ptr, cpy_len);
            locators_ctr ++;
        }
        if (default_ctrl_iface_v6 != NULL){
            itr_rloc = (lispd_pkt_map_request_itr_rloc_t *)cur_ptr;
            itr_rloc->afi = htons(get_lisp_afi(AF_INET6,NULL));
            cur_ptr = CO(itr_rloc,sizeof(lispd_pkt_map_request_itr_rloc_t));
            cpy_len = copy_addr((void *) cur_ptr ,default_ctrl_iface_v6->ipv6_address, 0);
            cur_ptr = CO(cur_ptr, cpy_len);
            locators_ctr ++;
        }
    }
    mrp->additional_itr_rloc_count = locators_ctr - 1; /* IRC = 0 --> 1 ITR-RLOC */
    if (locators_ctr == 0){
        lispd_log_msg(LISP_LOG_DEBUG_2,"build_map_request_pkt: No ITR RLOCs.");
        free(packet);
        return (NULL);
    }


    /* Requested EID record */
    request_eid_record = (lispd_pkt_map_request_eid_prefix_record_t *)cur_ptr;
    request_eid_record->eid_prefix_length = requested_mapping->eid_prefix_length;

    cur_ptr = pkt_fill_eid(&(request_eid_record->eid_prefix_afi),requested_mapping);

    if (mrp->map_data_present == 1){
        /* Map-Reply Record */
        rec = (lispd_pkt_mapping_record_t *)cur_ptr;
        if ((pkt_fill_mapping_record(rec, src_mapping, NULL))== NULL) {
            lispd_log_msg(LISP_LOG_DEBUG_2,"build_map_request_pkt: Couldn't buil map reply record for map request. "
                    "Map Request will not be send");
            free(packet);
            return(NULL);
        }
    }

    /* Add Encapsulated (Inner) control header*/
    if (encap){

        /*
         * If no source EID is included (Source-EID-AFI = 0), The default RLOC address is used for
         * the source address in the inner IP header
         */
        if (src_eid != NULL){
            ih_src_ip = &(src_mapping->eid_prefix);;
        }else{
            if (requested_mapping->eid_prefix.afi == AF_INET){
                ih_src_ip = get_main_eid (AF_INET);
            }else{
                ih_src_ip = get_main_eid (AF_INET6);
            }
        }

        mr_packet = packet;
        packet = build_control_encap_pkt(mr_packet, map_request_msg_len, ih_src_ip, &(requested_mapping->eid_prefix), LISP_CONTROL_PORT, LISP_CONTROL_PORT, len);

        if (packet == NULL){
            lispd_log_msg(LISP_LOG_DEBUG_1,"build_map_request_pkt: Couldn't encapsulate the map request");
            free (mr_packet);
            return (NULL);
        }
    }

    return (packet);
}
Пример #5
0
uint8_t *pkt_fill_mapping_record(
    lispd_pkt_mapping_record_t              *rec,
    lispd_mapping_elt                       *mapping,
    lisp_addr_t                             *probed_rloc)
{
    uint8_t                                 *cur_ptr             = NULL;
    int                                     cpy_len             = 0;
    lispd_pkt_mapping_record_locator_t      *loc_ptr            = NULL;
    lispd_locators_list                     *locators_list[2]   = {NULL,NULL};
    lispd_locator_elt                       *locator            = NULL;
    lcl_locator_extended_info               *lct_extended_info  = NULL;
    lisp_addr_t                             *itr_address    = NULL;
    int                                     ctr                 = 0;


    if ((rec == NULL) || (mapping == NULL)){
        return NULL;
    }

    rec->ttl                    = htonl(DEFAULT_MAP_REGISTER_TIMEOUT);
    rec->locator_count          = mapping->locator_count;
    rec->eid_prefix_length      = mapping->eid_prefix_length;
    rec->action                 = 0;
    rec->authoritative          = 1;
    rec->version_hi             = 0;
    rec->version_low            = 0;

    cur_ptr = (uint8_t *)&(rec->eid_prefix_afi);
    cur_ptr = pkt_fill_eid(cur_ptr, mapping);
    loc_ptr = (lispd_pkt_mapping_record_locator_t *)cur_ptr;

    if (loc_ptr == NULL){
        return NULL;
    }

    locators_list[0] = mapping->head_v4_locators_list;
    locators_list[1] = mapping->head_v6_locators_list;
    for (ctr = 0 ; ctr < 2 ; ctr++){
        while (locators_list[ctr]) {
            locator              = locators_list[ctr]->locator;

            if (*(locator->state) == UP){
                loc_ptr->priority    = locator->priority;
            }else{
                /* If the locator is DOWN, set the priority to 255 -> Locator should not be used */
                loc_ptr->priority    = UNUSED_RLOC_PRIORITY;
            }
            loc_ptr->weight      = locator->weight;
            loc_ptr->mpriority   = locator->mpriority;
            loc_ptr->mweight     = locator->mweight;
            loc_ptr->local       = 1;
            if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){
                loc_ptr->probed  = 1;
            }

            loc_ptr->reachable   = *(locator->state);
            loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL));

            lct_extended_info = (lcl_locator_extended_info *)(locator->extended_info);
            if (lct_extended_info->rtr_locators_list != NULL){
                itr_address = &(lct_extended_info->rtr_locators_list->locator->address);
            }else{
                itr_address = locator->locator_addr;
            }

            if ((cpy_len = copy_addr((void *) CO(loc_ptr,
                    sizeof(lispd_pkt_mapping_record_locator_t)), itr_address, 0)) == 0) {
                lispd_log_msg(LISP_LOG_DEBUG_3, "pkt_fill_mapping_record: copy_addr failed for locator %s",
                        get_char_from_lisp_addr_t(*(locator->locator_addr)));
                return(NULL);
            }

            loc_ptr = (lispd_pkt_mapping_record_locator_t *)
                            CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len));
            locators_list[ctr] = locators_list[ctr]->next;
        }
    }
    return ((void *)loc_ptr);
}