#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <assert.h>
#include "debug.h"
#include "dyn_ip.h"
#include "proxyarp.h"
#include "agentapi.h"
#include "util.h"
#include "mn_handler.h"
#include "mn.h"
#include "mn_tunnel.h"
#include "device_info.h"
Include dependency graph for mn_util.c:
Go to the source code of this file.
Functions | |
fa_spi_entry * | get_fa_spi (int spi, struct in_addr addr) |
int | add_fa_spi (struct fa_spi_entry *spi, int replace_any_spi) |
void | remove_fa_spi (struct fa_spi_entry *spi) |
void | send_gratuitous_arp (struct in_addr route_addr, struct in_addr gratuitous_addr) |
send_gratuitous_arp: : : | |
int | update_fa_decaps_routes (const char *ifname, int ifindex, struct in_addr fa_addr, struct in_addr home_net_addr, int home_net_addr_plen) |
update_fa_decsps_routes: : interface name : interface index : foreign agent addres : home network addres : home network prefix length, -1 if no home network | |
int | check_interfaces (struct interface_data *iface, int iface_num) |
check_interfaces: : array of interfaces : number of interfaces in | |
int | create_registration_socket (void) |
create_registration_socket: | |
int | mn_parse_command_line (int argc, char *argv[]) |
int | mn_init (void) |
void | clean_up (int sig) |
void | add_fa_host_route (char *dev, struct hashtable *adv_hash, int ifindex, struct in_addr addr) |
void | remove_fa_host_routes (int all) |
int | is_coloc_addr_foreign (void) |
int | device_up (int ifindex) |
char * | event_type_str (int event_type) |
int | mn_remove_dynamic_home_addr (void) |
mn_remove_dynamic_home_addr: | |
int | monitor_check_policy (int bit) |
int | copy_str (char *buffer, int len, int *curr, char *str, char *attr) |
Variables | |
mn_data | mn |
mn_config | config |
timeval | timers [TIMER_COUNT] |
char * | program_name |
char * | opt_config |
int | opt_foreground |
int | real_tunnel_up |
void add_fa_host_route | ( | char * | dev, | |
struct hashtable * | adv_hash, | |||
int | ifindex, | |||
struct in_addr | addr | |||
) |
Definition at line 998 of file mn_util.c.
References agentadv_data::adv, adv_fetch(), DEBUG(), and DEBUG_INFO.
Referenced by request_tunnel(), and send_registration().
01000 { 01001 struct agentadv_data *adv; 01002 adv = adv_fetch(adv_hash, &addr, ifindex); 01003 01004 if (dyn_ip_route_replace(addr, dev) != 0) { 01005 if (adv != NULL && adv->routeentry) 01006 DEBUG(DEBUG_INFO, "Route entry already added for the " 01007 "FA (%s=>%s)\n", inet_ntoa(addr), dev); 01008 else 01009 DEBUG(DEBUG_INFO, "Could not add a route to the FA " 01010 "(%s=>%s), but trying to register anyway\n", 01011 inet_ntoa(addr), dev); 01012 } else { 01013 if (adv != NULL) 01014 adv->routeentry = 1; 01015 else 01016 DEBUG(DEBUG_INFO, "No agentadv for FA %s\n", 01017 inet_ntoa(addr)); 01018 } 01019 }
Here is the call graph for this function:
int add_fa_spi | ( | struct fa_spi_entry * | spi, | |
int | replace_any_spi | |||
) |
Definition at line 122 of file mn_util.c.
References fa_spi_entry::created, DEBUG(), DEBUG_INFO, mn_config::fa_spi_list, get_fa_spi(), remove_fa_spi(), and fa_spi_entry::spi.
00123 { 00124 struct fa_spi_entry *old; 00125 00126 old = get_fa_spi(replace_any_spi ? 0 : spi->spi, spi->addr); 00127 if (old != NULL) { 00128 if (old->created == 0) { 00129 DEBUG(DEBUG_INFO, "add_fa_spi: trying to replace " 00130 "static security association - aborting " 00131 "operation\n"); 00132 return -1; 00133 } 00134 00135 DEBUG(DEBUG_INFO, "add_fa_spi: overwriting previous dynamic " 00136 "security association\n"); 00137 remove_fa_spi(old); 00138 free(old); 00139 old = NULL; 00140 } 00141 00142 DEBUG(DEBUG_INFO, "add_fa_spi: adding dynamic security association " 00143 "(SPI=%i, addr=%s)\n", spi->spi, inet_ntoa(spi->addr)); 00144 list_init_node(&spi->node); 00145 list_add_tail(&config.fa_spi_list, &spi->node); 00146 return 0; 00147 }
Here is the call graph for this function:
int check_interfaces | ( | struct interface_data * | iface, | |
int | iface_num | |||
) |
check_interfaces: : array of interfaces : number of interfaces in
Check whether new interfaces can be detected or if an interface has been removed
Returns: 0 if successfully executed, 1 on error
Definition at line 411 of file mn_util.c.
References DEBUG(), DEBUG_INFO, and interface_data::index.
Referenced by handle_api(), handle_icmp(), main_vanha(), and mn_init().
00412 { 00413 int i; 00414 struct idxmap *idxmap, *idx; 00415 00416 idxmap = dyn_ip_get_interface_map(); 00417 if (idxmap == NULL) { 00418 DEBUG(DEBUG_INFO, "check_interfaces: interface map could " 00419 "not be created\n"); 00420 return 1; 00421 } 00422 00423 /* remove the ignored interfaces */ 00424 /* FIX: add list of interfaces to be ignored to dynmnd.conf and try to 00425 * eliminate 'virtual' interfaces like tunnels etc. */ 00426 idx = idxmap; 00427 while (idx != NULL) { 00428 if (check_ignore_iface(idx->name) || 00429 (dyn_ip_get_ifflags(idx->name) & IFF_UP) == 0) 00430 idx->index = -1; 00431 idx = idx->next; 00432 } 00433 00434 /* check removed interfaces */ 00435 for (i = 0; i < iface_num; i++) { 00436 idx = idxmap; 00437 while (idx != NULL) { 00438 if (iface[i].index == idx->index) 00439 break; 00440 idx = idx->next; 00441 } 00442 00443 if (iface[i].s > -1) { 00444 if (idx != NULL) { 00445 /* mark the interface used */ 00446 idx->index = -1; 00447 } else { 00448 DEBUG(DEBUG_INFO, "check_interfaces: " 00449 "removed interface\n"); 00450 /* this interface has been removed */ 00451 modify_removed_interface(&iface[i]); 00452 } 00453 } 00454 } 00455 00456 /* check new interfaces */ 00457 idx = idxmap; 00458 while (idx != NULL) { 00459 if (idx->index == -1) { 00460 idx = idx->next; 00461 continue; 00462 } 00463 00464 /* find a free slot */ 00465 i = 0; 00466 while (i < iface_num && iface[i].s > -1) i++; 00467 if (i >= iface_num) { 00468 DEBUG(DEBUG_INFO, "Not enough space for all " 00469 "the interfaces\n"); 00470 break; 00471 } 00472 00473 /* call handlers for INTERFACE_INIT event */ 00474 DEBUG(DEBUG_INFO, "check_interfaces: new interface\n"); 00475 modify_new_interface(&iface[i], idx); 00476 idx = idx->next; 00477 } 00478 00479 dyn_ip_free_interface_map(idxmap); 00480 00481 return 0; 00482 }
Here is the call graph for this function:
void clean_up | ( | int | sig | ) |
Definition at line 896 of file mn_util.c.
References mn_data::agentadv, mn_data::api_ro_socket, mn_data::api_rw_socket, clean_agentadv(), clean_up(), close_tunneling(), DEBUG(), DEBUG_HANDLERS, DEBUG_INFO, DEBUG_MESSAGES, event_type_str(), FA_ADV_EXPIRE, FA_ADV_RECEIVE, FA_GET, handler_unregister_all(), mn_data::iface, INTERFACE_DOWN, INTERFACE_INIT, mn_data::last_req_FA_NAI, MAX_INTERFACES, mn, mn_config::mn_api_admin_socket_path, mn_config::mn_api_read_socket_path, MN_CONNECTED, MN_PID_FILE, mn_remove_dynamic_home_addr(), MONITOR_unregister_module(), mn_data::pcap_capturer, REG_DISC, mn_data::registration_socket, reply_waiting_api(), mn_data::rtnetlink_socket, interface_data::s, interface_data::s_adv, send_registration(), mn_data::session_key, sock, and mn_data::state.
00897 { 00898 int i; 00899 00900 DEBUG(DEBUG_INFO, "cleaning up..\n"); 00901 00902 /* try to disconnect if connected */ 00903 if (mn.state == MN_CONNECTED) { 00904 send_registration(REG_DISC); 00905 DEBUG(DEBUG_MESSAGES, "Deregistration message sent\n"); 00906 } 00907 00908 if (mn.pcap_capturer > -1) { 00909 DEBUG(DEBUG_INFO, "Terminating pcap capturer\n"); 00910 kill(mn.pcap_capturer, SIGTERM); 00911 usleep(100000); 00912 kill(mn.pcap_capturer, SIGKILL); 00913 } 00914 00915 if (mn.agentadv != NULL) { 00916 hashtable_iterator(mn.agentadv, clean_agentadv, NULL); 00917 hashtable_destroy(mn.agentadv); 00918 } 00919 00920 /* close sockets */ 00921 close(mn.registration_socket); 00922 for (i = 0; i < MAX_INTERFACES; i++) { 00923 if (mn.iface[i].s > -1) 00924 close(mn.iface[i].s); 00925 if (mn.iface[i].s_adv > -1) 00926 close(mn.iface[i].s_adv); 00927 } 00928 if (mn.api_ro_socket > -1) 00929 close(mn.api_ro_socket); 00930 if (mn.api_rw_socket > -1) 00931 close(mn.api_rw_socket); 00932 #ifdef INCLUDE_IPAY 00933 close(mn.ipay_sock); 00934 ipay_cleanup(); 00935 #endif 00936 if (mn.rtnetlink_socket > -1) 00937 close(mn.rtnetlink_socket); 00938 00939 #ifdef WITH_WIRELESS 00940 /* Remove iwspy entries */ 00941 MONITOR_unregister_module(); 00942 #endif 00943 00944 /* stop to any waiting api call */ 00945 reply_waiting_api(API_FAILED, NULL, 0); 00946 /* close tunneling device */ 00947 close_tunneling(); 00948 mn_remove_dynamic_home_addr(); 00949 00950 /* free session key */ 00951 if (mn.session_key != NULL) 00952 free(mn.session_key); 00953 00954 if (mn.last_req_FA_NAI != NULL) 00955 free(mn.last_req_FA_NAI); 00956 00957 /* unlink api domain sockets */ 00958 unlink(config.mn_api_read_socket_path); 00959 unlink(config.mn_api_admin_socket_path); 00960 00961 unlink(MN_PID_FILE); 00962 00963 /* unregister all handlers */ 00964 /* FA_ADV_RECEIVE */ 00965 i = handler_unregister_all(FA_ADV_RECEIVE); 00966 DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) " 00967 "removed\n", i, event_type_str(FA_ADV_RECEIVE)); 00968 /* FA_ADV_EXPIRE */ 00969 i = handler_unregister_all(FA_ADV_EXPIRE); 00970 DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) " 00971 "removed\n", i, event_type_str(FA_ADV_EXPIRE)); 00972 /* FA_GET */ 00973 i = handler_unregister_all(FA_GET); 00974 DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) " 00975 "removed\n", i, event_type_str(FA_GET)); 00976 /* INTERFACE_INIT */ 00977 i = handler_unregister_all(INTERFACE_INIT); 00978 DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) " 00979 "removed\n", i, event_type_str(INTERFACE_INIT)); 00980 /* INTERFACE_DOWN */ 00981 i = handler_unregister_all(INTERFACE_DOWN); 00982 DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) " 00983 "removed\n", i, event_type_str(INTERFACE_DOWN)); 00984 00985 syslog(LOG_INFO, "stopped"); 00986 closelog(); 00987 00988 #ifdef MN_LOCUPD_PROFILER 00989 fclose(mn.profile); 00990 #endif 00991 00992 DEBUG(DEBUG_INFO, "cleaned up\n"); 00993 00994 exit(0); 00995 }
Here is the call graph for this function:
int copy_str | ( | char * | buffer, | |
int | len, | |||
int * | curr, | |||
char * | str, | |||
char * | attr | |||
) |
Definition at line 1147 of file mn_util.c.
References DEBUG(), and DEBUG_INFO.
01148 { 01149 int l; 01150 01151 l = strlen(str) + strlen(attr) + 1; 01152 if (*curr+l > len) { 01153 DEBUG(DEBUG_INFO, "copy_str: Not enough room (%d/%d)\n", 01154 l, len); 01155 return 1; 01156 } 01157 sprintf(buffer+*curr, "%s%s\n", str, attr); 01158 *curr += l; 01159 01160 return 0; 01161 }
Here is the call graph for this function:
int create_registration_socket | ( | void | ) |
create_registration_socket:
Create registration socket and bind it to specified port.
Returns: created socket or -1 on error.
Definition at line 492 of file mn_util.c.
References DEBUG(), DEBUG_INFO, LOG2, and mn_config::socket_priority.
Referenced by mn_init().
00493 { 00494 int s; 00495 unsigned char ttl; 00496 #ifdef BIND_UDP_SOCKET 00497 struct sockaddr_in addr; 00498 #endif 00499 00500 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 00501 LOG2(LOG_ERR, "create_reg_socket - socket: %s\n", 00502 strerror(errno)); 00503 return -1; 00504 } 00505 #ifdef BIND_UDP_SOCKET 00506 memset(&addr, 0, sizeof(addr)); 00507 addr.sin_family = AF_INET; 00508 addr.sin_addr.s_addr = config.bind_addr.s_addr; 00509 addr.sin_port = config.bind_port; 00510 DEBUG(DEBUG_INFO, "binding UDP socket to %s:%i\n", 00511 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); 00512 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 00513 LOG2(LOG_ERR, "create_reg_socket - bind: %s\n", 00514 strerror(errno)); 00515 return -1; 00516 } 00517 #endif 00518 00519 if (config.socket_priority > -1 && 00520 setsockopt(s, SOL_SOCKET, SO_PRIORITY, 00521 (char *)&config.socket_priority, 00522 sizeof(config.socket_priority)) < 0) { 00523 LOG2(LOG_ERR, 00524 "create_reg_socket - setsockopt SO_PRIORITY: %s\n", 00525 strerror(errno)); 00526 /* continue without SO_PRIORITY set */ 00527 } 00528 00529 /* send registration request with TTL 255 [RFC 2344, Chap. 3.2] */ 00530 ttl = 255; 00531 if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) { 00532 LOG2(LOG_ERR, "setsockopt: IP_TTL failed: %s\n", 00533 strerror(errno)); 00534 /* continue with the default setting anyway */ 00535 #ifdef DYN_TARGET_WINDOWS 00536 if (dyn_ip_set_ttl(255) < 0) { 00537 DEBUG(DEBUG_INFO, "Also dyn_ip_set_ttl() failed\n"); 00538 } 00539 #endif /* DYN_TARGET_WINDOWS */ 00540 } 00541 00542 return s; 00543 }
Here is the call graph for this function:
int device_up | ( | int | ifindex | ) |
Definition at line 1061 of file mn_util.c.
References mn_data::iface, interface_data::index, MAX_INTERFACES, mn, and interface_data::s.
Referenced by clean_agentadv(), and stop_tunneling().
01062 { 01063 int i; 01064 for (i = 0; i < MAX_INTERFACES; i++) { 01065 if (mn.iface[i].s > -1 && 01066 mn.iface[i].index == ifindex) 01067 return 1; 01068 } 01069 return 0; 01070 }
char* event_type_str | ( | int | event_type | ) |
Definition at line 1073 of file mn_util.c.
References FA_ADV_EXPIRE, FA_ADV_RECEIVE, FA_GET, INTERFACE_DOWN, and INTERFACE_INIT.
Referenced by clean_up(), handler_call_all(), handler_register(), and handler_unregister().
01074 { 01075 switch (event_type) { 01076 case FA_ADV_RECEIVE: 01077 return "FA Advertisement receive"; 01078 case FA_ADV_EXPIRE: 01079 return "FA Advertisement expire"; 01080 case FA_GET: 01081 return "Get best FA"; 01082 case INTERFACE_INIT: 01083 return "Initialize interface"; 01084 case INTERFACE_DOWN: 01085 return "Interface down"; 01086 default: 01087 return "Unknown event type!"; 01088 } 01089 }
struct fa_spi_entry* get_fa_spi | ( | int | spi, | |
struct in_addr | addr | |||
) |
Definition at line 88 of file mn_util.c.
References fa_spi_entry::addr, fa_spi_entry::created, DEBUG(), DEBUG_INFO, mn_config::fa_spi_list, fa_spi_entry::lifetime, and fa_spi_entry::spi.
Referenced by add_fa_spi().
00089 { 00090 struct fa_spi_entry *s; 00091 struct node *node; 00092 time_t now; 00093 00094 time(&now); 00095 00096 node = list_get_first(&config.fa_spi_list); 00097 while (node != NULL) { 00098 s = (struct fa_spi_entry *) node; 00099 node = list_get_next(node); 00100 00101 /* Expire dynamic entries that are not infinite (lifetime=0) */ 00102 if (s->created != 0 && s->lifetime != 0 && 00103 now > s->created + s->lifetime) { 00104 DEBUG(DEBUG_INFO, "get_fa_spi: dynamic " 00105 "security association (SPI=%i, addr=%s) " 00106 "expired\n", s->spi, inet_ntoa(s->addr)); 00107 list_remove((struct node *) s); 00108 free(s); 00109 continue; 00110 } 00111 00112 if ((spi != 0 && s->spi != spi) || 00113 s->addr.s_addr != addr.s_addr) 00114 continue; 00115 00116 return s; 00117 } 00118 return NULL; 00119 }
Here is the call graph for this function:
int is_coloc_addr_foreign | ( | void | ) |
int mn_init | ( | void | ) |
Definition at line 669 of file mn_util.c.
References mn_data::agentadv, mn_data::api_ro_socket, mn_data::api_rw_socket, mn_config::auth_alg, check_interfaces(), clean_up(), mn_data::clock_correction, create_registration_socket(), mn_data::cur_route_info, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEFAULT_DEVICE_INFO_PATH, mn_data::dev_info_addr, mn_config::enable_fa_decapsulation, mn_data::fa_addr, mn_data::force_fa_addr, mn_data::ha_error_count, interface_data::handlers_off, mn_config::home_net_addr, mn_config::home_net_addr_plen, mn_config::home_net_gateway, mn_data::iface, IFNAMSIZ, init_pcap_for_advs(), init_tunneling(), mn_data::last_nonce, mn_data::last_reg_send_time, mn_data::last_req_FA_NAI, load_mn(), mn_data::local_addr, LOG2, MAX_FA_NAI_LEN, MAX_INTERFACES, mn, mn_config::mn_api_admin_socket_group, mn_config::mn_api_admin_socket_owner, mn_config::mn_api_admin_socket_path, mn_config::mn_api_admin_socket_permissions, mn_config::mn_api_read_socket_group, mn_config::mn_api_read_socket_owner, mn_config::mn_api_read_socket_path, mn_config::mn_api_read_socket_permissions, MN_DISCONNECTED, MN_GLOBAL_CONF_FILE, mn_handlers_init(), MONITOR_register_module(), opt_config, mn_data::opt_connect, mn_data::pcap_capturer, program_name, mn_data::registration_id, mn_data::registration_socket, mn_data::rtnetlink_socket, interface_data::s, interface_data::s_adv, mn_data::session_key, mn_data::session_key_len, mn_config::solicitation_interval, mn_config::spi, mn_data::start_default_device, mn_data::state, mn_config::syslog_facility, SYSLOG_IDENT, SYSLOG_OPTIONS, TIMER_COUNT, TIMER_SOLICITATION, TIMER_WLAN_AP_POLL, timers, mn_data::tunnel_mode, mn_data::tunnel_up, mn_data::use_auth_alg, and mn_config::wlan_ap_poll_interval.
Referenced by main(), and main_vanha().
00670 { 00671 int i; 00672 00673 /* Load configuration */ 00674 DEBUG(DEBUG_INFO, "Load config\n"); 00675 if (!load_mn(&config, program_name, 00676 opt_config == NULL ? MN_GLOBAL_CONF_FILE : opt_config)) { 00677 LOG2(LOG_ERR, "init: unable to load configuration\n"); 00678 00679 return 0; 00680 } 00681 mn.use_auth_alg = config.auth_alg; 00682 mn.agentadv = hashtable_init(256); 00683 if (mn.agentadv == NULL) { 00684 LOG2(LOG_ERR, "init: unable to init agentadv hashtable\n"); 00685 return 0; 00686 } 00687 mn.last_req_FA_NAI = (struct fa_nai_ext *) malloc(MAX_FA_NAI_LEN); 00688 if (mn.last_req_FA_NAI == NULL) { 00689 LOG2(LOG_ERR, "init: not enough memory\n"); 00690 return 0; 00691 } 00692 memset(mn.last_req_FA_NAI, 0, MAX_FA_NAI_LEN); 00693 00694 if (!config.enable_fa_decapsulation) 00695 check_kernel_support(CHECK_KERNEL_IPIP); 00696 check_kernel_support(CHECK_KERNEL_NETLINK); 00697 00698 #ifdef DYN_TARGET_LINUX 00699 if (getuid() || geteuid()) { 00700 fprintf(stderr, "This program must be run by root.\n"); 00701 return 0; 00702 } 00703 #endif 00704 #ifdef DYN_TARGET_WINDOWS 00705 /* FIX: on Windows NT and Windows 2000 check for Administrator 00706 * privileges */ 00707 #endif 00708 00709 if ((mn.registration_socket = create_registration_socket()) < 0) 00710 return 0; 00711 00712 mn_handlers_init(); 00713 mn.dev_info_addr.sun_family = AF_LOCAL; 00714 /* initialize default socket info path */ 00715 dynamics_strlcpy(mn.dev_info_addr.sun_path, DEFAULT_DEVICE_INFO_PATH, 00716 sizeof(mn.dev_info_addr.sun_path)); 00717 00718 #ifdef WITH_WIRELESS 00719 /* If wireless extensions enabled, monitor will register it's own 00720 handlers also */ 00721 DEBUG(DEBUG_INFO, "REGISTER MODULE(S)\n"); 00722 if (wireless_extensions) 00723 MONITOR_register_module(); 00724 #endif 00725 00726 /* Check interfaces */ 00727 for (i = 0; i < MAX_INTERFACES; i++) { 00728 mn.iface[i].s = -1; 00729 mn.iface[i].s_adv = -1; 00730 mn.iface[i].handlers_off = 1; 00731 } 00732 00733 #ifdef INCLUDE_IPAY 00734 /* register Ipay handlers after monitor */ 00735 ipay_init(); 00736 #endif 00737 00738 if (config.home_net_addr_plen < 0 || 00739 dyn_ip_route_get(config.home_net_addr, mn.start_default_device, 00740 IFNAMSIZ) != 0) 00741 mn.start_default_device[0] = '\0'; 00742 else 00743 DEBUG(DEBUG_INFO, "Initial default device: %s\n", 00744 mn.start_default_device); 00745 00746 #ifdef DYN_TARGET_LINUX 00747 if ((mn.api_ro_socket = 00748 api_open_socket(config.mn_api_read_socket_path, 00749 config.mn_api_read_socket_group, 00750 config.mn_api_read_socket_owner, 00751 config.mn_api_read_socket_permissions)) < 0) { 00752 LOG2(LOG_ERR, "init - open_api_ro_socket: %s\n", 00753 strerror(errno)); 00754 return 0; 00755 } 00756 00757 if ((mn.api_rw_socket = 00758 api_open_socket(config.mn_api_admin_socket_path, 00759 config.mn_api_admin_socket_group, 00760 config.mn_api_admin_socket_owner, 00761 config.mn_api_admin_socket_permissions)) < 0) { 00762 LOG2(LOG_ERR, "init - open api_rw_socket: %s\n", 00763 strerror(errno)); 00764 return 0; 00765 } 00766 #endif 00767 #ifdef DYN_TARGET_WINDOWS 00768 mn.api_ro_socket = windows_api_socket(0); 00769 mn.api_rw_socket = windows_api_socket(1); 00770 #endif 00771 00772 #ifdef INCLUDE_IPAY 00773 mn.ipay_sock = socket(AF_INET, SOCK_DGRAM, 0); 00774 if (mn.ipay_sock < 0) { 00775 LOG2(LOG_ERR, "init - open ipay_sock: %s\n", strerror(errno)); 00776 return 0; 00777 } 00778 if (config.ipay_mn_port > 0) { 00779 struct sockaddr_in addr; 00780 memset(&addr, 0, sizeof(addr)); 00781 addr.sin_family = AF_INET; 00782 addr.sin_addr = config.ipay_mn_addr; 00783 addr.sin_port = htons(config.ipay_mn_port); 00784 if (bind(mn.ipay_sock, (struct sockaddr *) &addr, 00785 sizeof(addr)) < 0) { 00786 LOG2(LOG_ERR, "init - bind ipay_sock: %s\n", 00787 strerror(errno)); 00788 return 0; 00789 } 00790 } 00791 mn.ipay_sock_fa = socket(AF_INET, SOCK_DGRAM, 0); 00792 if (mn.ipay_sock_fa < 0) { 00793 LOG2(LOG_ERR, "init - open ipay_sock_fa: %s\n", 00794 strerror(errno)); 00795 return 0; 00796 } 00797 if (config.ipay_fa_port > 0) { 00798 struct sockaddr_in addr; 00799 memset(&addr, 0, sizeof(addr)); 00800 addr.sin_family = AF_INET; 00801 addr.sin_addr.s_addr = INADDR_ANY; 00802 addr.sin_port = htons(config.ipay_fa_port); 00803 if (bind(mn.ipay_sock_fa, (struct sockaddr *) &addr, 00804 sizeof(addr)) < 0) { 00805 LOG2(LOG_ERR, "init - bind ipay_sock_fa: %s\n", 00806 strerror(errno)); 00807 return 0; 00808 } 00809 } 00810 #endif 00811 00812 mn.rtnetlink_socket = dyn_ip_monitor_open(); 00813 if (mn.rtnetlink_socket < 0) 00814 DEBUG(DEBUG_INFO, "init - rtnetlink socket opening failed\n"); 00815 00816 /* set own ip-addr */ 00817 mn.local_addr = config.mn_home_ip_addr; 00818 00819 init_tunneling(); 00820 00821 /* init variables */ 00822 mn.registration_id[0] = 0; 00823 mn.registration_id[1] = 0; 00824 mn.last_nonce = 0; 00825 mn.clock_correction = 0; 00826 mn.state = MN_DISCONNECTED; 00827 mn.fa_addr.s_addr = 0; 00828 mn.current_adv = NULL; 00829 mn.force_fa_addr.s_addr = 0; 00830 mn.session_key = NULL; 00831 mn.session_key_len = 0; 00832 mn.tunnel_up = 0; 00833 mn.tunnel_mode = API_TUNNEL_NONE; 00834 mn.ha_error_count = 0; 00835 memset(&mn.cur_route_info, 0, sizeof(mn.cur_route_info)); 00836 mn.cur_route_info.net.s_addr = config.home_net_addr.s_addr; 00837 mn.cur_route_info.prefix_len = config.home_net_addr_plen; 00838 00839 timerclear(&mn.last_reg_send_time); 00840 00841 for (i = 0; i < TIMER_COUNT; i++) timerclear(&timers[i]); 00842 if (config.wlan_ap_poll_interval > -1) 00843 gettimeofday(&timers[TIMER_WLAN_AP_POLL], NULL); 00844 if (config.solicitation_interval > -1) 00845 gettimeofday(&timers[TIMER_SOLICITATION], NULL); 00846 00847 openlog(SYSLOG_IDENT, SYSLOG_OPTIONS, config.syslog_facility); 00848 00849 dyn_ip_route_save_default(config.home_net_gateway.s_addr != 0 ? 00850 &config.home_net_gateway : NULL); 00851 00852 #ifdef MN_LOCUPD_PROFILER 00853 mn.profile = fopen("mn.prof.log", "a"); 00854 if (mn.profile == NULL) { 00855 fprintf(stderr, "Cannot open mn.prof.log\n"); 00856 return 0; 00857 } 00858 gettimeofday(&mn.last_api, NULL); 00859 fprintf(mn.profile, "START %u.%06u\n", 00860 (unsigned int) mn.last_api.tv_sec, 00861 (unsigned int) mn.last_api.tv_usec); 00862 #endif 00863 00864 /* Setup signals */ 00865 signal(SIGTERM, clean_up); 00866 signal(SIGINT, clean_up); 00867 signal(SIGHUP, SIG_IGN); 00868 signal(SIGPIPE, SIG_IGN); 00869 00870 /* if (!opt_foreground && dynamics_fork_daemon() == -1) 00871 clean_up(0); 00872 dynamics_write_pid_file(MN_PID_FILE); 00873 */ 00874 DEBUG(DEBUG_INFO, " MN initialized to %sconnected state,\n" 00875 " SPI: %d, HA: %s,\n", (mn.opt_connect ? "" : "dis"), 00876 config.spi, inet_ntoa(config.ha_ip_addr)); 00877 DEBUG(DEBUG_INFO, " HomeAddr: %s", 00878 inet_ntoa(config.mn_home_ip_addr)); 00879 DEBUG(DEBUG_INFO, ", CurrentAddr: %s\n", inet_ntoa(mn.local_addr)); 00880 00881 00882 syslog(LOG_INFO, "Started."); 00883 00884 check_interfaces(mn.iface, MAX_INTERFACES); 00885 00886 #ifdef DYN_TARGET_WINDOWS 00887 mn.pcap_capturer = init_pcap_for_advs(); 00888 #else 00889 mn.pcap_capturer = -1; 00890 #endif /* DYN_TARGET_WINDOWS */ 00891 00892 return 1; 00893 }
Here is the call graph for this function:
int mn_parse_command_line | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 560 of file mn_util.c.
References DEBUG(), DEBUG_INFO, mn, mn_data::opt_connect, optarg, and mn_data::policy_bits.
Referenced by main_vanha().
00561 { 00562 int c, oindex = 0; 00563 00564 static struct option long_options[] = { 00565 {"help", no_argument, NULL, 'h'}, 00566 {"version", no_argument, NULL, 'v'}, 00567 {"debug", no_argument, NULL, 0}, 00568 {"fg", no_argument, NULL, 0}, 00569 {"config", required_argument, NULL, 'c'}, 00570 /* MN specific arguments */ 00571 {"no-wireless", no_argument, NULL, 'n'}, 00572 {"wireless_policy", required_argument, NULL, 'p'}, 00573 {"disconnect", no_argument, NULL, 'd'}, 00574 /* end of arguments */ 00575 {0, 0, 0, 0} 00576 }; 00577 00578 mn.opt_connect = 1; 00579 mn.policy_bits = 0; 00580 00581 /* parse mn specific options */ 00582 wireless_extensions = 1; 00583 while ((c = getopt_long(argc, argv, "+hv", long_options, &oindex)) != 00584 EOF) { 00585 switch (c) { 00586 case 'n': 00587 wireless_extensions = 0; 00588 break; 00589 case 'p': 00590 mn.policy_bits = atoi(optarg); 00591 /* 0: no timestamps */ 00592 /* 1: with timestamps */ 00593 DEBUG(DEBUG_INFO, "Option: %s" 00594 " 0x%02x (wireless policy)\n", 00595 long_options[oindex].name, 00596 mn.policy_bits); 00597 break; 00598 case 'h': 00599 /* show MN specific parameters */ 00600 show_usage(); 00601 exit(1); 00602 break; 00603 00604 case 'd': 00605 mn.opt_connect = 0; 00606 break; 00607 00608 case '?': 00609 printf("Command line parsing failed - aborting\n"); 00610 exit(1); 00611 00612 case 'v': 00613 case 'c': 00614 case 0: 00615 break; 00616 00617 default: 00618 printf("getopt returned character code 0%o\n", c); 00619 exit(1); 00620 } 00621 } 00622 00623 return 0; 00624 }
Here is the call graph for this function:
int mn_remove_dynamic_home_addr | ( | void | ) |
mn_remove_dynamic_home_addr:
Remove dynamic home address from interface if it is maintained by Dynamics MN.
Returns: 1 on success (address removed), 0 if no dynamic home address, or -1 on failure
Definition at line 1102 of file mn_util.c.
References DEBUG(), DEBUG_INFO, mn_data::dynamic_home_addr, mn_data::dynamic_home_addr_dev, mn_config::ha_ip_addr_orig, mn_data::local_addr, and mn.
Referenced by at_home(), clean_up(), and disconnect().
01103 { 01104 if (mn.dynamic_home_addr.s_addr == 0) 01105 return 0; 01106 01107 if (dyn_ip_addr_del(mn.dynamic_home_addr_dev, mn.dynamic_home_addr) == 01108 0) { 01109 DEBUG(DEBUG_INFO, "Dynamic home address '%s' removed from " 01110 "interface '%s'\n", inet_ntoa(mn.dynamic_home_addr), 01111 mn.dynamic_home_addr_dev); 01112 if (config.mn_home_ip_addr.s_addr == 01113 mn.dynamic_home_addr.s_addr) { 01114 DEBUG(DEBUG_INFO, "\treset home address to 0 (use " 01115 "discovery)\n"); 01116 config.mn_home_ip_addr.s_addr = 01117 mn.local_addr.s_addr = 0; 01118 if (config.ha_ip_addr_orig.s_addr == 0) { 01119 DEBUG(DEBUG_INFO, "\treset home agent address " 01120 "to 0 (use discovery)\n"); 01121 config.ha_ip_addr.s_addr = 0; 01122 } 01123 } else { 01124 DEBUG(DEBUG_INFO, "\tDEBUG: config: %s, ", 01125 inet_ntoa(config.mn_home_ip_addr)); 01126 DEBUG(DEBUG_INFO, "obtained: %s\n", 01127 inet_ntoa(mn.dynamic_home_addr)); 01128 } 01129 01130 mn.dynamic_home_addr.s_addr = 0; 01131 return 1; 01132 } 01133 01134 DEBUG(DEBUG_INFO, "Could not remove dynamic home address '%s' " 01135 "from interface '%s'\n", inet_ntoa(mn.dynamic_home_addr), 01136 mn.dynamic_home_addr_dev); 01137 return -1; 01138 }
Here is the call graph for this function:
int monitor_check_policy | ( | int | bit | ) |
void remove_fa_host_routes | ( | int | all | ) |
Definition at line 1042 of file mn_util.c.
References mn_data::agentadv, mn_data::current_adv, DEBUG(), DEBUG_INFO, and mn.
Referenced by connected(), and stop_tunneling().
01043 { 01044 DEBUG(DEBUG_INFO, "remove_fa_host_routes(%i)\n", all); 01045 hashtable_iterator(mn.agentadv, clean_routes, 01046 all ? NULL: mn.current_adv); 01047 }
Here is the call graph for this function:
void remove_fa_spi | ( | struct fa_spi_entry * | spi | ) |
Definition at line 150 of file mn_util.c.
References DEBUG(), DEBUG_INFO, and fa_spi_entry::spi.
Referenced by add_fa_spi().
00151 { 00152 DEBUG(DEBUG_INFO, "remove_fa_spi: removing security association " 00153 "(SPI=%i, addr=%s)\n", spi->spi, inet_ntoa(spi->addr)); 00154 list_remove(&spi->node); 00155 }
Here is the call graph for this function:
void send_gratuitous_arp | ( | struct in_addr | route_addr, | |
struct in_addr | gratuitous_addr | |||
) |
send_gratuitous_arp: : :
A gratuituous arp message for address will be sent on the interface where there is a route to .
Definition at line 166 of file mn_util.c.
References DEBUG(), DEBUG_INFO, and IFNAMSIZ.
Referenced by at_home(), and close_for_home().
00168 { 00169 char arp_if[IFNAMSIZ]; 00170 00171 if (dyn_ip_route_get(route_addr, arp_if, IFNAMSIZ) != 0) { 00172 DEBUG(DEBUG_INFO, "Could not get ARP interface\n"); 00173 return; 00174 } 00175 proxyarp_gratuitous(gratuitous_addr, arp_if); 00176 }
Here is the call graph for this function:
int update_fa_decaps_routes | ( | const char * | ifname, | |
int | ifindex, | |||
struct in_addr | fa_addr, | |||
struct in_addr | home_net_addr, | |||
int | home_net_addr_plen | |||
) |
update_fa_decsps_routes: : interface name : interface index : foreign agent addres : home network addres : home network prefix length, -1 if no home network
Set the default route to via and delete all routes to /.
Returns: 0 if successful
Definition at line 206 of file mn_util.c.
References mn_data::cur_route_info, DEBUG(), DEBUG_INFO, mn_data::home_net_route_set_via_fa, IFNAMSIZ, LOG2, and mn.
Referenced by start_tunneling().
00210 { 00211 DEBUG(DEBUG_INFO, "FA decapsulation - setting default route to " 00212 "%s via %s\n", ifname, inet_ntoa(fa_addr)); 00213 00214 mn.cur_route_info.known = 1; 00215 mn.cur_route_info.via.s_addr = fa_addr.s_addr; 00216 mn.cur_route_info.ifindex = ifindex; 00217 memcpy(mn.cur_route_info.ifname, ifname, IFNAMSIZ); 00218 mn.cur_route_info.ifindex_net = -1; 00219 00220 if (dyn_ip_route_replace_default(ifname, &fa_addr, 00221 &config.mn_home_ip_addr) != 0) { 00222 LOG2(LOG_ERR, "Set default route (to %s via %s) failed\n", 00223 ifname, inet_ntoa(fa_addr)); 00224 return -1; 00225 } 00226 if (home_net_addr_plen > -1) { 00227 int count; 00228 DEBUG(DEBUG_INFO, "Deleting home net route (%s/%i)\n", 00229 inet_ntoa(home_net_addr), home_net_addr_plen); 00230 count = dyn_ip_route_delete_net_routes(&home_net_addr, 00231 home_net_addr_plen); 00232 if (count < 0) { 00233 LOG2(LOG_ERR, "Home net route (%s/%i) delete failed\n", 00234 inet_ntoa(home_net_addr), home_net_addr_plen); 00235 #ifdef DYN_TARGET_WINDOWS 00236 /* at least Win98 does not seem to like to remove 00237 * home net route.. */ 00238 DEBUG(DEBUG_INFO, "Trying to set net route via the FA " 00239 "to circumvent failed net route removal\n"); 00240 00241 if (dyn_ip_route_set_net(ifname, &home_net_addr, 00242 home_net_addr_plen, 00243 NULL, 2) < 0) { 00244 DEBUG(DEBUG_INFO, "Could not increase home " 00245 "net route metric\n"); 00246 } 00247 00248 if (dyn_ip_route_set_net(ifname, &home_net_addr, 00249 home_net_addr_plen, 00250 &fa_addr, 1) < 0) { 00251 DEBUG(DEBUG_INFO, "Could not set net route via" 00252 " FA\n"); 00253 } else 00254 mn.home_net_route_set_via_fa = 1; 00255 #endif /* DYN_TARGET_WINDOWS */ 00256 } else { 00257 DEBUG(DEBUG_INFO, 00258 " %i net route%s deleted\n", count, 00259 count != 1 ? "s" : ""); 00260 } 00261 } 00262 00263 return 0; 00264 }
Here is the call graph for this function:
Definition at line 44 of file mn.c.
Referenced by adv_ok_fa(), at_home(), check_expired_agent_advs(), clean_agentadv(), clean_up(), close_for_home(), connected(), create_mobile(), degrade_current_fa_priority(), device_up(), disconnect(), find_agent(), get_fa(), handle_api(), handle_icmp(), handle_registration(), load_mn(), main_vanha(), mn_init(), mn_parse_command_line(), mn_remove_dynamic_home_addr(), monitor_poll_ap_addresses(), passive_find(), remove_fa_host_routes(), reply_waiting_api(), request_tunnel(), restart_tunneling(), send_registration(), start_tunneling(), stop_tunneling(), and update_fa_decaps_routes().
char* opt_config |
Referenced by mn_init().
int opt_foreground |
char* program_name |
int real_tunnel_up |
Definition at line 30 of file mn_tunnel.c.
struct timeval timers[TIMER_COUNT] |
Definition at line 47 of file mn.c.
Referenced by at_home(), close_for_home(), connected(), disconnect(), find_agent(), mn_init(), request_tunnel(), and send_registration().