int process_map_reply(uint8_t *packet) { lispd_pkt_map_reply_t *mrp; uint64_t nonce; //uint8_t rloc_probe; int record_count; int ctr; mrp = (lispd_pkt_map_reply_t *)packet; nonce = mrp->nonce; record_count = mrp->record_count; lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply: Nonce of the Map Reply is: %s", get_char_from_nonce(nonce)); packet = CO(packet, sizeof(lispd_pkt_map_reply_t)); for (ctr=0;ctr<record_count;ctr++){ if (mrp->rloc_probe == FALSE){ if ((process_map_reply_record(&packet,nonce))==BAD){ return (BAD); } if (is_loggable(LISP_LOG_DEBUG_3)){ dump_map_cache_db(LISP_LOG_DEBUG_3); } }else{ if ((process_map_reply_probe_record(&packet,nonce))==BAD){ return (BAD); } } } return (TRUE); }
/* * dump mapping */ void dump_mapping_entry( lispd_mapping_elt *mapping, int log_level) { lispd_locators_list *locator_iterator_array[2] = {NULL,NULL}; lispd_locators_list *locator_iterator = NULL; lispd_locator_elt *locator = NULL; int ctr = 0; if (is_loggable(log_level) == FALSE){ return; } lispd_log_msg(log_level,"IDENTIFIER (EID): %s/%d (IID = %d)\n ", get_char_from_lisp_addr_t(mapping->eid_prefix), mapping->eid_prefix_length, mapping->iid); lispd_log_msg(log_level, "| Locator (RLOC) | Status | Priority/Weight |"); if (mapping->locator_count > 0){ locator_iterator_array[0] = mapping->head_v4_locators_list; locator_iterator_array[1] = mapping->head_v6_locators_list; // Loop through the locators and print each for (ctr = 0 ; ctr < 2 ; ctr++){ locator_iterator = locator_iterator_array[ctr]; while (locator_iterator != NULL) { locator = locator_iterator->locator; dump_locator (locator,log_level); locator_iterator = locator_iterator->next; } } lispd_log_msg(log_level,"\n"); } }
void dump_map_servers(int log_level) { lispd_map_server_list_t *ms = NULL; char str[80]; if (map_servers == NULL || is_loggable(log_level) == FALSE){ return; } lispd_log_msg(log_level, "******************* Map-Servers list ********************************"); lispd_log_msg(log_level, "| Locator (RLOC) | Key Type |"); ms = map_servers; while (ms) { sprintf(str, "| %39s |",get_char_from_lisp_addr_t(*ms->address)); if (ms->key_type == NO_KEY){ sprintf(str + strlen(str)," NONE |"); }else if (ms->key_type == HMAC_SHA_1_96){ sprintf(str + strlen(str)," HMAC-SHA-1-96 |"); }else{ sprintf(str + strlen(str)," HMAC-SHA-256-128 |"); } ms = ms->next; lispd_log_msg(log_level,"%s",str); } }
void dump_locator ( lispd_locator_elt *locator, int log_level) { char locator_str [2000]; if (is_loggable(log_level)){ sprintf(locator_str, "| %39s |", get_char_from_lisp_addr_t(*(locator->locator_addr))); sprintf(locator_str + strlen(locator_str), " %5s ", locator->state ? "Up" : "Down"); sprintf(locator_str + strlen(locator_str), "| %3d/%-3d |", locator->priority, locator->weight); LISPD_LOG(log_level,"%s",locator_str); } }
void dump_iface_list(int log_level) { lispd_iface_list_elt *interface_list = head_interface_list; lispd_iface_mappings_list *mapping_list = NULL; char str[4000]; if (head_interface_list == NULL || is_loggable(log_level) == FALSE){ return; } sprintf(str,"*** LISP RLOC Interfaces List ***\n\n"); while (interface_list){ sprintf(str + strlen(str),"== %s (%s)==\n",interface_list->iface->iface_name, interface_list->iface->status ? "Up" : "Down"); if (interface_list->iface->ipv4_address){ sprintf(str + strlen(str)," IPv4 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv4_address))); sprintf(str + strlen(str)," -- LIST mappings -- \n"); mapping_list = interface_list->iface->head_mappings_list; while (mapping_list){ if (mapping_list->use_ipv4_address == TRUE){ sprintf(str + strlen(str)," %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix), mapping_list->mapping->eid_prefix_length); } mapping_list = mapping_list->next; } } if (interface_list->iface->ipv6_address){ sprintf(str + strlen(str)," IPv6 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv6_address))); sprintf(str + strlen(str)," -- LIST mappings -- \n"); mapping_list = interface_list->iface->head_mappings_list; while (mapping_list){ if (mapping_list->use_ipv6_address == TRUE){ sprintf(str + strlen(str)," %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix), mapping_list->mapping->eid_prefix_length); } mapping_list = mapping_list->next; } } interface_list = interface_list->next; } lispd_log_msg(log_level,"%s",str); }
/* * Print balancing locators vector information */ void dump_balancing_locators_vec( balancing_locators_vecs b_locators_vecs, lispd_mapping_elt *mapping, int log_level) { int ctr = 0; char str[3000]; if ( is_loggable(log_level)){ lispd_log_msg(log_level,"Balancing locator vector for %s/%d: ", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); sprintf(str," IPv4 locators vector (%d locators): ",b_locators_vecs.v4_locators_vec_length); for (ctr = 0; ctr< b_locators_vecs.v4_locators_vec_length; ctr++){ if (strlen(str) > 2850){ sprintf(str + strlen(str)," ..."); break; } sprintf(str + strlen(str)," %s ",get_char_from_lisp_addr_t(*b_locators_vecs.v4_balancing_locators_vec[ctr]->locator_addr)); } lispd_log_msg(log_level,"%s",str); sprintf(str," IPv6 locators vector (%d locators): ",b_locators_vecs.v6_locators_vec_length); for (ctr = 0; ctr< b_locators_vecs.v6_locators_vec_length; ctr++){ if (strlen(str) > 2900){ sprintf(str + strlen(str)," ..."); break; } sprintf(str + strlen(str)," %s ",get_char_from_lisp_addr_t(*b_locators_vecs.v6_balancing_locators_vec[ctr]->locator_addr)); } lispd_log_msg(log_level,"%s",str); sprintf(str," IPv4 & IPv6 locators vector (%d locators): ", b_locators_vecs.locators_vec_length); for (ctr = 0; ctr< b_locators_vecs.locators_vec_length; ctr++){ if (strlen(str) > 2950){ sprintf(str + strlen(str)," ..."); break; } sprintf(str + strlen(str)," %s ",get_char_from_lisp_addr_t(*b_locators_vecs.balancing_locators_vec[ctr]->locator_addr)); } lispd_log_msg(log_level,"%s",str); } }
void dump_proxy_etrs(int log_level) { lispd_locators_list *locator_lst_elt[2] = {NULL,NULL}; int ctr = 0; if (proxy_etrs == NULL || is_loggable(log_level) == FALSE){ return; } locator_lst_elt[0] = proxy_etrs->mapping->head_v4_locators_list; locator_lst_elt[1] = proxy_etrs->mapping->head_v6_locators_list; lispd_log_msg(log_level, "************************* Proxy ETRs List ****************************"); lispd_log_msg(log_level, "| Locator (RLOC) | Status | Priority/Weight |"); for (ctr = 0 ; ctr<2 ; ctr++){ while (locator_lst_elt[ctr]){ dump_locator (locator_lst_elt[ctr]->locator,log_level); locator_lst_elt[ctr] = locator_lst_elt[ctr]->next; } } }
int process_map_reply_record(uint8_t **cur_ptr, uint64_t nonce) { lispd_pkt_mapping_record_t *record = NULL; lispd_mapping_elt *mapping = NULL; lispd_map_cache_entry *cache_entry = NULL; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = 0; int ctr = 0; uint8_t is_new_mapping = FALSE; record = (lispd_pkt_mapping_record_t *)(*cur_ptr); mapping = new_map_cache_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid); if (mapping == NULL){ return (BAD); } *cur_ptr = (uint8_t *)&(record->eid_prefix_afi); if (!pkt_process_eid_afi(cur_ptr,mapping)){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Error processing the EID of the map reply record"); free_mapping_elt(mapping); return (BAD); } mapping->eid_prefix_length = record->eid_prefix_length; /* * Check if the map replay corresponds to a not active map cache */ cache_entry = lookup_nonce_in_no_active_map_caches(mapping->eid_prefix.afi, nonce); if (cache_entry != NULL){ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Instance ID of the map reply doesn't match with the inactive map cache entry"); free_mapping_elt(mapping); return (BAD); } /* * If the eid prefix of the received map reply doesn't match the inactive map cache entry (x.x.x.x/32 or x:x:x:x:x:x:x:x/128),then * we remove the inactie entry from the database and store it again with the correct eix prefix (for instance /24). */ if (cache_entry->mapping->eid_prefix_length != mapping->eid_prefix_length){ if (change_map_cache_prefix_in_db(mapping->eid_prefix, mapping->eid_prefix_length, cache_entry) != GOOD){ free_mapping_elt(mapping); return (BAD); } } cache_entry->active = 1; stop_timer(cache_entry->request_retry_timer); cache_entry->request_retry_timer = NULL; lispd_log_msg(LISP_LOG_DEBUG_2," Activating map cache entry %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); is_new_mapping = TRUE; } /* If the nonce is not found in the no active cache enties, then it should be an active cache entry */ else { /* Serch map cache entry exist*/ cache_entry = lookup_map_cache_exact(mapping->eid_prefix,mapping->eid_prefix_length); if (cache_entry == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: No map cache entry found for %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); return (BAD); } /* Check the found map cache entry contain the nonce of the map reply*/ if (check_nonce(cache_entry->nonces,nonce)==BAD){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: The nonce of the Map-Reply doesn't match the nonce of the generated Map-Request. Discarding message ..."); free_mapping_elt(mapping); return (BAD); }else { free(cache_entry->nonces); cache_entry->nonces = NULL; } /* Stop timer of Map Requests retransmits */ if (cache_entry->smr_inv_timer != NULL){ stop_timer(cache_entry->smr_inv_timer); cache_entry->smr_inv_timer = NULL; } /* Check instane id.*/ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Instance ID of the map reply doesn't match with the map cache entry"); free_mapping_elt(mapping); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_2," A map cache entry already exists for %s/%d, replacing locators list of this entry", get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length); free_locator_list(cache_entry->mapping->head_v4_locators_list); free_locator_list(cache_entry->mapping->head_v6_locators_list); cache_entry->mapping->head_v4_locators_list = NULL; cache_entry->mapping->head_v6_locators_list = NULL; free_mapping_elt(mapping); } cache_entry->actions = record->action; cache_entry->ttl = ntohl(record->ttl); cache_entry->active_witin_period = 1; cache_entry->timestamp = time(NULL); //locator_count updated when adding the processed locators /* Generate the locators */ for (ctr=0 ; ctr < record->locator_count ; ctr++){ if ((process_map_reply_locator (cur_ptr, cache_entry->mapping)) != GOOD){ return(BAD); } } if (is_loggable(LISP_LOG_DEBUG_2)){ dump_map_cache_entry(cache_entry, LISP_LOG_DEBUG_2); } /* [re]Calculate balancing locator vectors if it is not a negative map reply*/ if (cache_entry->mapping->locator_count != 0){ calculate_balancing_vectors ( cache_entry->mapping, &(((rmt_mapping_extended_info *)cache_entry->mapping->extended_info)->rmt_balancing_locators_vecs)); } /* * Reprogramming timers */ /* Expiration cache timer */ if (!cache_entry->expiry_cache_timer){ cache_entry->expiry_cache_timer = create_timer (EXPIRE_MAP_CACHE_TIMER); } start_timer(cache_entry->expiry_cache_timer, cache_entry->ttl*60, (timer_callback)map_cache_entry_expiration, (void *)cache_entry); lispd_log_msg(LISP_LOG_DEBUG_1,"The map cache entry %s/%d will expire in %d minutes.", get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length, cache_entry->ttl); /* RLOC probing timer */ if (is_new_mapping == TRUE && rloc_probe_interval != 0){ programming_rloc_probing(cache_entry); } return (TRUE); }
void dump_referral_cache_entry( lispd_referral_cache_entry *entry, int log_level) { int ctr = 0; char str[400]; lispd_locators_list *locator_iterator_array[2] = {NULL,NULL}; lispd_locators_list *locator_iterator = NULL; lispd_locator_elt *locator = NULL; if (is_loggable(log_level) == FALSE){ return; } sprintf(str,"IDENTIFIER (EID): %s/%d (IID = %d), TTL: %d", get_char_from_lisp_addr_t(entry->mapping->eid_prefix), entry->mapping->eid_prefix_length, entry->mapping->iid, entry->ttl); switch (entry->act_entry_type){ case NODE_REFERRAL: sprintf(str + strlen(str)," Type: Node Referral "); break; case MS_REFERRAL: sprintf(str + strlen(str)," Type: MS Referral "); break; case MS_ACK: sprintf(str + strlen(str)," Type: MS ACK "); break; case MS_NOT_REGISTERED: sprintf(str + strlen(str)," Type: Not Registered "); break; case DELEGATION_HOLE: sprintf(str + strlen(str)," Type: Delegation hole "); break; case NOT_AUTHORITATIVE: sprintf(str + strlen(str)," Type: Not authoritative "); break; default: sprintf(str + strlen(str)," Type: %d ", entry->act_entry_type); break; } if (entry->parent_node != NULL){ sprintf(str + strlen(str)," Parent (EID): %s/%d ", get_char_from_lisp_addr_t(entry->parent_node->mapping->eid_prefix), entry->parent_node->mapping->eid_prefix_length); } lispd_log_msg(log_level,"%s",str); if (entry->mapping->locator_count > 0){ locator_iterator_array[0] = entry->mapping->head_v4_locators_list; locator_iterator_array[1] = entry->mapping->head_v6_locators_list; lispd_log_msg(log_level, "| Locator (RLOC) | Status | Priority/Weight |"); // Loop through the locators and print each for (ctr = 0 ; ctr < 2 ; ctr++){ locator_iterator = locator_iterator_array[ctr]; while (locator_iterator != NULL) { locator = locator_iterator->locator; dump_locator(locator, log_level); locator_iterator = locator_iterator->next; } } lispd_log_msg(log_level,"\n"); } }
int process_info_reply_msg( uint8_t *packet, lisp_addr_t local_rloc) { uint8_t *ptr = packet; uint8_t lisp_type = 0; uint8_t reply = 0; uint64_t nonce = 0; uint16_t key_id = 0; uint16_t auth_data_len = 0; uint8_t *auth_data_pos = NULL; uint32_t ttl = 0; uint8_t eid_mask_len = 0; lisp_addr_t eid_prefix = {.afi=AF_UNSPEC}; uint16_t ms_udp_port = 0; uint16_t etr_udp_port = 0; uint32_t info_reply_hdr_len = 0; uint32_t lcaf_addr_len = 0; uint32_t pckt_len = 0; uint16_t *lcaf_afi = NULL; lisp_addr_t global_etr_rloc = {.afi=AF_UNSPEC}; lisp_addr_t ms_rloc = {.afi=AF_UNSPEC}; lisp_addr_t private_etr_rloc = {.afi=AF_UNSPEC}; lispd_rtr_locators_list *rtr_locators_list = NULL; lispd_mapping_elt *mapping = NULL; lispd_locator_elt *locator = NULL; lcl_locator_extended_info *lcl_locator_ext_inf = NULL; char rtrs_list_str[2000]; int rtrs_list_str_size = 0; lispd_rtr_locators_list *aux_rtr_locators_list = NULL; uint8_t is_behind_nat = FALSE; /* * Get source port and address. */ err = extract_info_nat_header(ptr, &lisp_type, &reply, &nonce, &key_id, &auth_data_len, &auth_data_pos, &ttl, &eid_mask_len, &eid_prefix, &info_reply_hdr_len); if (err != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Couldn't process Info Reply message"); return (BAD); } ptr = CO(ptr,info_reply_hdr_len); lcaf_afi = (uint16_t *)ptr; if ( ntohs(*lcaf_afi) != LISP_AFI_LCAF){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Malformed packet"); return (BAD); } ptr = CO(ptr,FIELD_AFI_LEN); /* Extract Info-Reply body fields */ err = extract_nat_lcaf_data(ptr, &ms_udp_port, &etr_udp_port, &global_etr_rloc, &ms_rloc, &private_etr_rloc, &rtr_locators_list, &lcaf_addr_len); if (err == BAD) { lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Error extracting packet data"); return (BAD); } /* Leave only RTR with same afi as the local rloc where we received the message */ remove_rtr_locators_with_afi_different_to(&rtr_locators_list, local_rloc.afi); lcaf_addr_len = lcaf_addr_len + FIELD_AFI_LEN; /* Print the extracted information of the message */ if (is_loggable(LISP_LOG_DEBUG_2)){ aux_rtr_locators_list = rtr_locators_list; rtrs_list_str[0] = '\0'; while (aux_rtr_locators_list != NULL){ sprintf(rtrs_list_str + rtrs_list_str_size, " %s ", get_char_from_lisp_addr_t(aux_rtr_locators_list->locator->address)); rtrs_list_str_size = rtrs_list_str_size + strlen(rtrs_list_str); aux_rtr_locators_list = aux_rtr_locators_list->next; } lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply message data->" "Nonce: %s , KeyID: %hu ,TTL: %u , EID-prefix: %s/%hhu , " "MS UDP Port Number: %hu , ETR UDP Port Number: %hu , Global ETR RLOC Address: %s , " "MS RLOC Address: %s , Private ETR RLOC Address: %s, RTR RLOC Compatible list: %s", get_char_from_nonce(nonce), key_id, ttl, get_char_from_lisp_addr_t(eid_prefix),eid_mask_len, ms_udp_port, etr_udp_port, get_char_from_lisp_addr_t(global_etr_rloc), get_char_from_lisp_addr_t(ms_rloc),get_char_from_lisp_addr_t(private_etr_rloc),rtrs_list_str); } /* Checking the nonce */ if (check_nonce(nat_ir_nonce,nonce) == GOOD ){ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct nonce field checking "); free(nat_ir_nonce); nat_ir_nonce = NULL; }else{ lispd_log_msg(LISP_LOG_DEBUG_1, "Info-Reply: Error checking nonce field. No Info Request generated with nonce: %s", get_char_from_nonce (nonce)); return (BAD); } /* Check authentication data */ pckt_len = info_reply_hdr_len + lcaf_addr_len; if(BAD == check_auth_field(key_id, map_servers->key, (void *) packet, pckt_len, auth_data_pos)){ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Error checking auth data field"); return(BAD); }else{ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct auth data field checking"); } // TODO Select the best RTR from the list retrieved from the Info-Reply /* Check if behind NAT */ switch (compare_lisp_addr_t(&global_etr_rloc, &local_rloc)) { case 0: is_behind_nat = FALSE; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is not behind NAT"); break; case 1: case 2: is_behind_nat = TRUE; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is behind NAT"); break; case -1: is_behind_nat = UNKNOWN; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: Unknown state"); break; } if (is_behind_nat == TRUE){ if (rtr_locators_list == NULL){ lispd_log_msg(LISP_LOG_WARNING, "process_info_reply_msg: The interface with IP address %s is behind NAT" " but there is no RTR compatible with local AFI", get_char_from_lisp_addr_t(local_rloc)); } mapping = lookup_eid_exact_in_db(eid_prefix, eid_mask_len); if (mapping == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply is not for any local EID"); return (BAD); } locator = get_locator_from_mapping(mapping,local_rloc); if (locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply received in the wrong locator"); return (BAD); } lcl_locator_ext_inf = (lcl_locator_extended_info *)locator->extended_info; if (lcl_locator_ext_inf->rtr_locators_list != NULL){ free_rtr_list(lcl_locator_ext_inf->rtr_locators_list); } lcl_locator_ext_inf->rtr_locators_list = rtr_locators_list; if (nat_status == NO_NAT || nat_status == PARTIAL_NAT){ nat_status = PARTIAL_NAT; }else{ nat_status = FULL_NAT; } }else{ if (nat_status == FULL_NAT || nat_status == PARTIAL_NAT){ nat_status = PARTIAL_NAT; }else{ nat_status = NO_NAT; } } /* If we are behind NAT, the program timer to send Info Request after TTL minutes */ if (is_behind_nat == TRUE){ if (info_reply_ttl_timer == NULL) { info_reply_ttl_timer = create_timer(INFO_REPLY_TTL_TIMER); } start_timer(info_reply_ttl_timer, ttl*60, info_request, (void *)mapping); lispd_log_msg(LISP_LOG_DEBUG_1, "Reprogrammed info request in %d minutes",ttl); }else{ stop_timer(info_reply_ttl_timer); info_reply_ttl_timer = NULL; } /* Once we know the NAT state we send a Map-Register */ map_register(NULL,NULL); return (GOOD); }