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); }
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); }
int process_map_referral(uint8_t *packet) { uint8_t *cur_ptr = NULL; lispd_pkt_map_referral_t *map_referral_pkt = NULL; uint64_t nonce; int record_count; int ctr; map_referral_pkt = (lispd_pkt_map_referral_t *)packet; nonce = map_referral_pkt->nonce; record_count = map_referral_pkt->record_count; lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_referral: Nonce of the Map Referral is: %s", get_char_from_nonce(nonce)); cur_ptr = CO(packet, sizeof(lispd_pkt_map_referral_t)); for (ctr=0;ctr<record_count;ctr++){ if ((process_map_referral_record(&cur_ptr,nonce))==BAD){ return (BAD); } } return (TRUE); }
int build_and_send_map_request_msg( lispd_mapping_elt *requested_mapping, lisp_addr_t *src_eid, lisp_addr_t *dst_rloc_addr, uint8_t encap, uint8_t probe, uint8_t solicit_map_request, uint8_t smr_invoked, uint64_t *nonce) { uint8_t *packet = NULL; uint8_t *map_req_pkt = NULL; lisp_addr_t *src_addr = NULL; int out_socket = 0; int packet_len = 0; int mrp_len = 0; /* return the length here */ int result = 0; map_req_pkt = build_map_request_pkt( requested_mapping, src_eid, encap, probe, solicit_map_request, smr_invoked, &mrp_len, nonce); if (map_req_pkt == NULL) { lispd_log_msg(LISP_LOG_DEBUG_1, "build_and_send_map_request_msg: Could not build map-request packet for %s/%d:" " Encap: %c, Probe: %c, SMR: %c, SMR-inv: %c ", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length, (encap == TRUE ? 'Y' : 'N'), (probe == TRUE ? 'Y' : 'N'), (solicit_map_request == TRUE ? 'Y' : 'N'), (smr_invoked == TRUE ? 'Y' : 'N')); return (BAD); } /* Get src interface information */ src_addr = get_default_ctrl_address(dst_rloc_addr->afi); out_socket = get_default_ctrl_socket(dst_rloc_addr->afi); if (src_addr == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1, "build_and_send_map_request_msg: Couden't send Map Request. No output interface with afi %d.", dst_rloc_addr->afi); free (map_req_pkt); return (BAD); } /* Add UDP and IP header to the Map Request message */ packet = build_ip_udp_pcket(map_req_pkt, mrp_len, src_addr, dst_rloc_addr, LISP_CONTROL_PORT, LISP_CONTROL_PORT, &packet_len); free (map_req_pkt); if (packet == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"build_and_send_map_request_msg: Couldn't send Map Request. Error adding IP and UDP header to the message"); return (BAD); } /* Send the packet */ if ((err = send_packet(out_socket,packet,packet_len)) == GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Request packet for %s/%d to %s: Encap: %c, Probe: %c, SMR: %c, SMR-inv: %c . Nonce: %s", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length, get_char_from_lisp_addr_t(*dst_rloc_addr), (encap == TRUE ? 'Y' : 'N'), (probe == TRUE ? 'Y' : 'N'), (solicit_map_request == TRUE ? 'Y' : 'N'), (smr_invoked == TRUE ? 'Y' : 'N'), get_char_from_nonce(*nonce)); result = GOOD; }else{ lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't sent Map-Request packet for %s/%d: Encap: %c, Probe: %c, SMR: %c, SMR-inv: %c ", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length, (encap == TRUE ? 'Y' : 'N'), (probe == TRUE ? 'Y' : 'N'), (solicit_map_request == TRUE ? 'Y' : 'N'), (smr_invoked == TRUE ? 'Y' : 'N')); result = BAD; } free (packet); return (result); }