mn_util.c File Reference

#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_entryget_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


Function Documentation

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   ) 

Definition at line 1051 of file mn_util.c.

References IFNAMSIZ.

Referenced by main_vanha().

01052 {
01053         char dev[IFNAMSIZ];
01054         if (dyn_ip_route_get(config.mn_home_ip_addr, dev, IFNAMSIZ) != 0 ||
01055             strcmp(dev, "lo") != 0)
01056                 return 1;
01057         return 0;
01058 }

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  ) 

Definition at line 1141 of file mn_util.c.

References POLICY.

01142 {
01143         return POLICY(bit);
01144 }

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:


Variable Documentation

struct mn_config config

Definition at line 45 of file mn.c.

struct mn_data mn

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

Definition at line 48 of file mn.c.

Referenced by main_vanha(), and mn_init().

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().


Generated on Tue Jan 15 08:50:53 2008 for Virtual foreign agent generator version 0.1 by  doxygen 1.5.1