/* * Creates the routes to send the traffic to the tun interface to be encapsulated */ int configure_routing_to_tun() { lispd_mapping_list *list = NULL; lispd_mapping_list *list_elt = NULL; lisp_addr_t *tun_v4_addr = NULL; lisp_addr_t *tun_v6_addr = NULL; lispd_mapping_elt *mapping = NULL; uint32_t iface_index = 0; if (tun_bring_up_iface(TUN_IFACE_NAME) != GOOD){ return (BAD); } if (router_mode == FALSE) { /* * For mobile node mode, we create two /1 routes covering the full IP addresses space to route all traffic * generated by the node to the lispTun0 interface * IPv4: 0.0.0.0/1 and 128.0.0.0/1 * IPv6: ::/1 and 8000::/1 */ tun_v4_addr = get_main_eid(AF_INET); tun_v6_addr = get_main_eid(AF_INET6); if (tun_v4_addr != NULL){ if (tun_add_eid_to_iface(*tun_v4_addr,TUN_IFACE_NAME) != GOOD){ return (BAD); } if (set_tun_default_route_v4() != GOOD){ return (BAD); } } if (tun_v6_addr != NULL){ if (tun_add_eid_to_iface(*tun_v6_addr,TUN_IFACE_NAME) != GOOD){ return (BAD); } if (set_tun_default_route_v6() != GOOD){ return (BAD); } } }else{ /* * For router mode, add a new routing table with default route to tun interface. Using source routing, * We send all traffic generated by EIDs to this table */ list = get_all_mappings(AF_UNSPEC); list_elt = list; /* Create rules to the new table */ while (list_elt != NULL){ mapping = list_elt->mapping; if (add_rule(mapping->eid_prefix.afi, 0, LISP_TABLE, RULE_TO_LISP_TABLE_PRIORITY, RTN_UNICAST, &(mapping->eid_prefix), mapping->eid_prefix_length, NULL,0,0)!=GOOD){ free_mapping_list(list, FALSE); return (BAD); } list_elt = list_elt->next; if (add_rule(mapping->eid_prefix.afi, 0, RT_TABLE_MAIN, RULE_AVOID_LISP_TABLE_PRIORITY, RTN_UNICAST, NULL,0, &(mapping->eid_prefix), mapping->eid_prefix_length, 0)!=GOOD){ free_mapping_list(list, FALSE); return (BAD); } } /* Add default route into the new table */ iface_index = if_nametoindex(TUN_IFACE_NAME); tun_v4_addr = get_main_eid(AF_INET); tun_v6_addr = get_main_eid(AF_INET6); if (tun_v4_addr != NULL){ add_route(AF_INET,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE); } if (tun_v6_addr != NULL){ add_route(AF_INET6,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE); } free_mapping_list(list, FALSE); } return (GOOD); }
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); }
int main(int argc, char **argv) { lisp_addr_t *tun_v4_addr = NULL; lisp_addr_t *tun_v6_addr = NULL; char *tun_dev_name = TUN_IFACE_NAME; uint32_t iseed = 0; /* initial random number generator */ pid_t pid = 0; /* child pid */ pid_t sid = 0; #ifdef OPENWRT lispd_log_msg(LISP_LOG_INFO,"LISPmob %s compiled for openWRT\n", LISPD_VERSION); #else #ifdef ANDROID open_log_file(); lispd_log_msg(LISP_LOG_INFO,"LISPmob %s compiled for Android\n", LISPD_VERSION); #else lispd_log_msg(LISP_LOG_INFO,"LISPmob %s compiled for Linux\n", LISPD_VERSION); #endif #endif init_globales(); #ifndef ANDROID /* * Check for required capabilities and drop unnecssary privileges */ if(check_capabilities() != GOOD) { exit_cleanup(); } #else /* * Check for superuser privileges */ if (geteuid() != 0) { lispd_log_msg(LISP_LOG_INFO,"Running %s requires superuser privileges! Exiting...\n", LISPD); exit_cleanup(); } #endif /* * Initialize the random number generator */ iseed = (unsigned int) time (NULL); srandom(iseed); /* * Set up signal handlers */ signal(SIGHUP, signal_handler); signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); /* * set up databases */ db_init(); map_cache_init(); init_referral_cache(); /* * Parse command line options */ handle_lispd_command_line(argc, argv); /* * see if we need to daemonize, and if so, do it */ if (daemonize) { lispd_log_msg(LISP_LOG_DEBUG_1, "Starting the daemonizing process1"); if ((pid = fork()) < 0) { exit_cleanup(); } umask(0); if (pid > 0){ exit(EXIT_SUCCESS); } if ((sid = setsid()) < 0){ exit_cleanup(); } if ((chdir("/")) < 0){ exit_cleanup(); } } /* * create timers */ if (build_timers_event_socket(&timers_fd) == 0) { lispd_log_msg(LISP_LOG_CRIT, " Error programing the timer signal. Exiting..."); exit_cleanup(); } init_timers(); /* * Parse config file. Format of the file depends on the node: Linux Box or OpenWRT router */ #ifdef OPENWRT if (config_file == NULL){ config_file = "/etc/config/lispd"; } err = handle_uci_lispd_config_file(config_file); #else if (config_file == NULL){ config_file = "/etc/lispd.conf"; } err = handle_lispd_config_file(config_file); #endif if (err != GOOD){ lispd_log_msg(LISP_LOG_CRIT,"Wrong configuration."); exit_cleanup(); } if (ddt_client == FALSE){ drop_referral_cache(); } /* * Select the default rlocs for output data packets and output control packets */ set_default_output_ifaces(); set_default_ctrl_ifaces(); /* * Create tun interface */ create_tun(tun_dev_name, TUN_RECEIVE_SIZE, TUN_MTU, &tun_receive_fd, &tun_ifindex, &tun_receive_buf); /* * Assign address to the tun interface * Assign route to 0.0.0.0/1 and 128.0.0.0/1 via tun interface * ::/1 and 8000::/1 */ if (router_mode == TRUE){ tun_v4_addr = get_main_eid(AF_INET); if (tun_v4_addr != NULL){ tun_v4_addr = (lisp_addr_t *)malloc(sizeof(lisp_addr_t)); get_lisp_addr_from_char(TUN_LOCAL_V4_ADDR,tun_v4_addr); } tun_v6_addr = get_main_eid(AF_INET6); if (tun_v6_addr != NULL){ tun_v6_addr = (lisp_addr_t *)malloc(sizeof(lisp_addr_t)); get_lisp_addr_from_char(TUN_LOCAL_V6_ADDR,tun_v6_addr); } }else{ tun_v4_addr = get_main_eid(AF_INET); tun_v6_addr = get_main_eid(AF_INET6); } tun_bring_up_iface(tun_dev_name); if (tun_v4_addr != NULL){ tun_add_eid_to_iface(*tun_v4_addr,tun_dev_name); set_tun_default_route_v4(); } if (tun_v6_addr != NULL){ tun_add_eid_to_iface(*tun_v6_addr,tun_dev_name); set_tun_default_route_v6(); } if (router_mode == TRUE){ if (tun_v4_addr != NULL){ free(tun_v4_addr); } if (tun_v6_addr != NULL){ free(tun_v6_addr); } } /* * Generate receive sockets for control (4342) and data port (4341) */ if (default_rloc_afi == AF_UNSPEC || default_rloc_afi == AF_INET){ ipv4_control_input_fd = open_control_input_socket(AF_INET); ipv4_data_input_fd = open_data_input_socket(AF_INET); } if (default_rloc_afi == AF_UNSPEC || default_rloc_afi == AF_INET6){ ipv6_control_input_fd = open_control_input_socket(AF_INET6); ipv6_data_input_fd = open_data_input_socket(AF_INET6); } /* * Create net_link socket to receive notifications of changes of RLOC status. */ netlink_fd = opent_netlink_socket(); lispd_log_msg(LISP_LOG_INFO,"LISPmob (%s): 'lispd' started...", LISPD_VERSION); if (router_mode == TRUE){ lispd_log_msg(LISP_LOG_INFO,"Running as an xTR router"); }else{ lispd_log_msg(LISP_LOG_INFO,"Running as a LISP mobile node"); } /* * Request to dump the routing tables to obtain the gatways when processing the netlink messages */ request_route_table(RT_TABLE_MAIN, AF_INET); process_netlink_msg(netlink_fd); request_route_table(RT_TABLE_MAIN, AF_INET6); process_netlink_msg(netlink_fd); /* * Register to the Map-Server(s) */ map_register (NULL,NULL); /* * SMR proxy-ITRs list to be updated with new mappings */ init_smr(NULL,NULL); /* * RLOC Probing proxy ETRs */ programming_petr_rloc_probing(); event_loop(); lispd_log_msg(LISP_LOG_INFO, "Exiting..."); /* event_loop returned bad */ closelog(); return(0); }
int main(int argc, char **argv) { lisp_addr_t *tun_v4_addr; lisp_addr_t *tun_v6_addr; char *tun_dev_name = TUN_IFACE_NAME; #ifdef ROUTER #ifdef OPENWRT lispd_log_msg(LISP_LOG_INFO,"LISPmob compiled for openWRT xTR\n"); #else lispd_log_msg(LISP_LOG_INFO,"LISPmob compiled for linux xTR\n"); #endif #else lispd_log_msg(LISP_LOG_INFO,"LISPmob compiled for mobile node\n"); #endif /* * Check for superuser privileges */ if (geteuid()) { lispd_log_msg(LISP_LOG_INFO,"Running %s requires superuser privileges! Exiting...\n", LISPD); exit_cleanup(); } /* * Initialize the random number generator */ iseed = (unsigned int) time (NULL); srandom(iseed); /* * Set up signal handlers */ signal(SIGHUP, signal_handler); signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); /* * set up databases */ db_init(); map_cache_init(); /* * Parse command line options */ handle_lispd_command_line(argc, argv); /* * see if we need to daemonize, and if so, do it */ if (daemonize) { lispd_log_msg(LISP_LOG_DEBUG_1, "Starting the daemonizing process"); if ((pid = fork()) < 0) { exit_cleanup(); } umask(0); if (pid > 0) exit_cleanup(); if ((sid = setsid()) < 0) exit_cleanup(); if ((chdir("/")) < 0) exit_cleanup(); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } /* * create timers */ if (build_timers_event_socket(&timers_fd) == 0) { lispd_log_msg(LISP_LOG_CRIT, " Error programing the timer signal. Exiting..."); exit_cleanup(); } init_timers(); /* * Parse config file. Format of the file depends on the node: Linux Box or OpenWRT router */ #ifdef OPENWRT if (config_file == NULL){ config_file = "/etc/config/lispd"; } handle_uci_lispd_config_file(config_file); #else if (config_file == NULL){ config_file = "/etc/lispd.conf"; } handle_lispd_config_file(config_file); #endif if (map_servers == NULL){ lispd_log_msg(LISP_LOG_CRIT, "No Map Server configured. Exiting..."); exit_cleanup(); } if (map_resolvers == NULL){ lispd_log_msg(LISP_LOG_CRIT, "No Map Resolver configured. Exiting..."); exit_cleanup(); } if (proxy_etrs == NULL){ lispd_log_msg(LISP_LOG_WARNING, "No Proxy-ETR defined. Packets to non-LISP destinations will be " "forwarded natively (no LISP encapsulation). This may prevent mobility in some scenarios."); sleep(3); }else{ calculate_balancing_vectors ( proxy_etrs->mapping, &(((rmt_mapping_extended_info *)(proxy_etrs->mapping->extended_info))->rmt_balancing_locators_vecs)); } /* * Select the default rlocs for output data packets and output control packets */ set_default_output_ifaces(); set_default_ctrl_ifaces(); /* * Create tun interface */ create_tun(tun_dev_name, TUN_RECEIVE_SIZE, TUN_MTU, &tun_receive_fd, &tun_ifindex, &tun_receive_buf); /* * Assign address to the tun interface * Assign route to 0.0.0.0/1 and 128.0.0.0/1 via tun interface * ::/1 and 8000::/1 */ #ifdef ROUTER tun_v4_addr = get_main_eid(AF_INET); if (tun_v4_addr != NULL){ tun_v4_addr = (lisp_addr_t *)malloc(sizeof(lisp_addr_t)); get_lisp_addr_from_char(TUN_LOCAL_V4_ADDR,tun_v4_addr); } tun_v6_addr = get_main_eid(AF_INET6); if (tun_v6_addr != NULL){ tun_v6_addr = (lisp_addr_t *)malloc(sizeof(lisp_addr_t)); get_lisp_addr_from_char(TUN_LOCAL_V6_ADDR,tun_v6_addr); } #else tun_v4_addr = get_main_eid(AF_INET); tun_v6_addr = get_main_eid(AF_INET6); #endif tun_bring_up_iface(tun_dev_name); if (tun_v4_addr != NULL){ tun_add_eid_to_iface(*tun_v4_addr,tun_dev_name); set_tun_default_route_v4(); } if (tun_v6_addr != NULL){ tun_add_eid_to_iface(*tun_v6_addr,tun_dev_name); set_tun_default_route_v6(); } #ifdef ROUTER if (tun_v4_addr != NULL){ free(tun_v4_addr); } if (tun_v6_addr != NULL){ free(tun_v6_addr); } #endif /* * Generate receive sockets for control (4342) and data port (4341) */ if (default_rloc_afi == -1 || default_rloc_afi == AF_INET){ ipv4_control_input_fd = open_control_input_socket(AF_INET); ipv4_data_input_fd = open_data_input_socket(AF_INET); } if (default_rloc_afi == -1 || default_rloc_afi == AF_INET6){ ipv6_control_input_fd = open_control_input_socket(AF_INET6); ipv6_data_input_fd = open_data_input_socket(AF_INET6); } /* * Create net_link socket to receive notifications of changes of RLOC status. */ netlink_fd = opent_netlink_socket(); lispd_log_msg(LISP_LOG_INFO,"LISPmob (0.3.3): 'lispd' started..."); /* * Request to dump the routing tables to obtain the gatways when processing the netlink messages */ request_route_table(RT_TABLE_MAIN, AF_INET); process_netlink_msg(netlink_fd); request_route_table(RT_TABLE_MAIN, AF_INET6); process_netlink_msg(netlink_fd); /* * Register to the Map-Server(s) */ map_register (NULL,NULL); /* * SMR proxy-ITRs list to be updated with new mappings */ init_smr(NULL,NULL); /* * RLOC Probing proxy ETRs */ programming_petr_rloc_probing(); event_loop(); lispd_log_msg(LISP_LOG_INFO, "Exiting..."); /* event_loop returned bad */ closelog(); return(0); }