mn.h File Reference

#include "config.h"
#include <stdio.h>
#include <syslog.h>
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include "message.h"
#include "list.h"
#include "mn_agentadv.h"
#include "dyn_api.h"
#include "dyn_ip.h"

Include dependency graph for mn.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  fa_spi_entry
struct  ignore_iflist_entry
struct  dev_prio_entry
struct  alt_ha_entry
struct  mn_config
struct  interface_data
struct  mn_data
struct  policy_vars

Defines

#define TRUE   1
#define FALSE   0
#define DEBUG_MESSAGES   'M'
#define DEBUG_STATES   'S'
#define DEBUG_INFO   'I'
#define DEBUG_API   'A'
#define DEBUG_AGENTADV   '1'
#define DEBUG_HANDLERS   '2'
#define DEBUG_TIMERS   't'
#define MN_ENABLE_TUNNELING
#define MN_ENABLE_VALIDATION
#define MIN_REGISTRATION_DELAY   1000000
#define MIN_SOLICITATION_DELAY   1000000
#define ASSERT   assert
#define MIN(x, y)   (((x) < (y)) ? (x) : (y))
#define MAX(x, y)   (((x) > (y)) ? (x) : (y))
#define LOG2(lev, fmt, args...)
#define MAXMSG   2048
#define MAX_INTERFACES   10
#define DEFAULT_INTERFACE_PRIORITY   100
#define SYSLOG_IDENT   "mobile node"
#define SYSLOG_OPTIONS   LOG_PID | LOG_CONS
#define TIMER_GEN   0
#define TIMER_LIFETIME   1
#define TIMER_ADV   2
#define TIMER_REQUEST   3
#define TIMER_REREG   4
#define TIMER_WLAN_AP_POLL   5
#define TIMER_SOLICITATION   6
#define TIMER_COUNT   7
#define REG_DISC   0
#define REG_CONNECT   1
#define REG_REREG   2
#define CON_HA   0
#define CON_FA   1
#define STATE_INIT   0
#define STATE_TIMEOUT   1
#define OLD_TUNNEL_EXTRA_TIME   3
#define MIN_REGISTRATION_TIME   1
#define MAX_REGISTRATION_TIME   32
#define DEREGISTRATION_INTERVAL   8
#define DEFAULT_PRIO_DEGRADE_INITIAL   10
#define DEFAULT_PRIO_DEGRADE_FACTOR   2
#define DEFAULT_PRIO_DEGRADE_DEGRADE   0.9
#define SOLICITATION_PRIO_DEGRADE   10
#define MAX_AGENTSOL_REPLY_WAIT   1500000
#define SOLICITATION_INTERVALS   {1, 1, 1, 2, 4, 8, 16, 32, 64}
#define MAX_RANDOM_SOLICITATION_DELAY   500000
#define NORMAL_REREGISTRATION_TIME   32
#define MN_AAA_REG_TIME   15
#define MAX_DEREGISTRATION_TO_HA   5
#define MIN_ALLOWED_LIFETIME   1
#define MAX_HA_ERRORS   5
#define MN_CONF_FILE   "dynmnd.conf"
#define MN_LOCAL_CONF_FILE   MN_CONF_FILE
#define MN_GLOBAL_CONF_FILE   SYSCONFDIR "/" MN_CONF_FILE
#define MN_PID_FILE   PIDDIR "/dynmnd.pid"
#define MAXFILENAMELEN   256
#define MAXSHAREDSECRETLEN   32
#define MAXDEVICENAMELEN   80
#define MAXOWNERNAMELEN   8
#define MAXGROUPNAMELEN   8
#define MAXROUTELEN   256
#define MN_DEFAULT_TUNNEL_LIFETIME   400
#define MN_DEFAULT_SYSLOG_FACILITY   LOG_LOCAL0
#define MNDECAPS_ROUTE_DEFAULT   0
#define MNDECAPS_ROUTE_HOME_NET   1
#define MNDECAPS_ROUTE_NONE   2
#define TUNMODE_AUTO_REVERSE   1
#define TUNMODE_AUTO_TRIANGLE   2
#define TUNMODE_REVERSE   3
#define TUNMODE_TRIANGLE   4
#define POLICY_SET_BIT(bits, bit)   (bits |= bit)
#define POLICY_CLR_BIT(bits, bit)   (bits &= ~bit)
#define POLICY_BIT(bits, bit)   (bits & bit)
#define POLICY(bit)   POLICY_BIT(mn.policy_bits, bit)
#define POLICY_SET(bit)   POLICY_SET_BIT(mn.policy_bits, bit)
#define POLICY_CLR(bit)   POLICY_CLR_BIT(mn.policy_bits, bit)
#define DEFAULT_POLICY_BIT   0
#define EARLY_EXPIRE_BIT   1
#define NEWEST_FA_BIT   2
#define EAGER_SWITCH_BIT   4
#define NEWEST_ADV_BIT   8
#define EARLY_EXPIRE_STR   "Early-expire "
#define NEWEST_FA_STR   "Newest-FA "
#define EAGER_SWITCH_STR   "Eager-switching "
#define NEWEST_ADV_STR   "Newest-ADV "

Enumerations

enum  mobile_state {
  MN_STARTUP, MN_DISCONNECTED, MN_FIND_AGENT, MN_PASSIVE_FIND,
  MN_REQUEST_TUNNEL, MN_CONNECTED, MN_CLOSE_FOR_HOME, MN_AT_HOME,
  MN_ERROR, MN_STOP, MN_STATE_COUNT
}

Functions

void request_tunnel (int entry, int forced, int check_timer)
 rqeuest_tunnel: : STATE_INIT to move to this state, STATE_TIMEOUT to indicate timeout in this state, i.e.
void close_for_home (int entry)
void at_home (void)
void passive_find (void)
void find_agent (int entry)
 find_agent: - STATE_INIT to move to this state STATE_TIMEOUT to indicate timeout in this state, ie.
void disconnect (void)
void connected (int type, __u16 lifetime)
int degrade_current_fa_priority (void)
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 check_interfaces (struct interface_data *iface, int iface_n)
 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 restart_tunneling (void)
int start_tunneling (void)
 start_tunneling:
int stop_tunneling (void)
 stop_tunneling:
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)
void check_old_tunnel_expiration (void)
int is_coloc_addr_foreign (void)
int device_up (int ifindex)
char * event_type_str (int event_type)
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 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)
int load_mn (struct mn_config *cfg, char *program_name, char *config_file)
void handle_api (int sock, int admin)
void reply_waiting_api (int code, unsigned char *data, int datalen)
int send_registration (int request_type)
int handle_registration (int s)
int adv_ok_fa (struct agentadv_data *adv)
int check_expired_agent_advs (void)
pid_t init_pcap_for_advs (void)


Define Documentation

#define ASSERT   assert

Definition at line 75 of file mn.h.

Referenced by connected().

#define CON_FA   1

Definition at line 116 of file mn.h.

#define CON_HA   0

Definition at line 115 of file mn.h.

Referenced by connected().

#define DEBUG_AGENTADV   '1'

Definition at line 57 of file mn.h.

Referenced by clean_agentadv().

#define DEBUG_API   'A'

Definition at line 56 of file mn.h.

Referenced by handle_api(), and reply_waiting_api().

#define DEBUG_HANDLERS   '2'

Definition at line 58 of file mn.h.

Referenced by clean_up().

#define DEBUG_INFO   'I'

Definition at line 55 of file mn.h.

Referenced by add_fa_host_route(), add_fa_spi(), at_home(), check_interfaces(), clean_agentadv(), clean_up(), close_for_home(), close_tunneling(), connected(), copy_str(), create_registration_socket(), degrade_current_fa_priority(), disconnect(), find_agent(), get_fa_spi(), handle_api(), handle_registration(), init_tunneling(), mn_init(), mn_parse_command_line(), mn_remove_dynamic_home_addr(), remove_fa_host_routes(), remove_fa_spi(), request_tunnel(), restart_tunneling(), send_gratuitous_arp(), send_registration(), start_tunneling(), stop_tunneling(), and update_fa_decaps_routes().

#define DEBUG_MESSAGES   'M'

Definition at line 53 of file mn.h.

Referenced by clean_up(), close_for_home(), disconnect(), handle_registration(), and send_registration().

#define DEBUG_STATES   'S'

Definition at line 54 of file mn.h.

Referenced by at_home(), close_for_home(), connected(), disconnect(), find_agent(), passive_find(), and request_tunnel().

#define DEBUG_TIMERS   't'

Definition at line 59 of file mn.h.

Referenced by at_home(), close_for_home(), connected(), disconnect(), find_agent(), request_tunnel(), and send_registration().

#define DEFAULT_INTERFACE_PRIORITY   100

Definition at line 85 of file mn.h.

#define DEFAULT_POLICY_BIT   0

Definition at line 463 of file mn.h.

#define DEFAULT_PRIO_DEGRADE_DEGRADE   0.9

Definition at line 143 of file mn.h.

Referenced by handle_icmp().

#define DEFAULT_PRIO_DEGRADE_FACTOR   2

Definition at line 139 of file mn.h.

Referenced by degrade_current_fa_priority().

#define DEFAULT_PRIO_DEGRADE_INITIAL   10

Definition at line 135 of file mn.h.

Referenced by degrade_current_fa_priority().

#define DEREGISTRATION_INTERVAL   8

Definition at line 132 of file mn.h.

#define EAGER_SWITCH_BIT   4

Definition at line 467 of file mn.h.

#define EAGER_SWITCH_STR   "Eager-switching "

Definition at line 473 of file mn.h.

#define EARLY_EXPIRE_BIT   1

Definition at line 464 of file mn.h.

#define EARLY_EXPIRE_STR   "Early-expire "

Definition at line 471 of file mn.h.

#define FALSE   0

Definition at line 50 of file mn.h.

#define LOG2 ( lev,
fmt,
args...   ) 

Value:

{ DEBUG(DEBUG_INFO, fmt, ## args); \
  syslog(lev, fmt, ## args); }

Definition at line 78 of file mn.h.

Referenced by check_old_tunnel_expiration(), clean_agentadv(), close_for_home(), connected(), create_registration_socket(), handle_api(), handle_registration(), main_vanha(), mn_init(), send_registration(), start_tunneling(), stop_tunneling(), and update_fa_decaps_routes().

#define MAX ( x,
 )     (((x) > (y)) ? (x) : (y))

Definition at line 77 of file mn.h.

#define MAX_AGENTSOL_REPLY_WAIT   1500000

Definition at line 151 of file mn.h.

#define MAX_DEREGISTRATION_TO_HA   5

Definition at line 169 of file mn.h.

#define MAX_HA_ERRORS   5

Definition at line 175 of file mn.h.

#define MAX_INTERFACES   10

Definition at line 84 of file mn.h.

Referenced by clean_up(), device_up(), handle_icmp(), mn_init(), monitor_api_get_ch(), monitor_api_set_ch(), monitor_get_dev(), and print_entries().

#define MAX_RANDOM_SOLICITATION_DELAY   500000

Definition at line 159 of file mn.h.

Referenced by find_agent().

#define MAX_REGISTRATION_TIME   32

Definition at line 130 of file mn.h.

Referenced by close_for_home(), and request_tunnel().

#define MAXDEVICENAMELEN   80

Definition at line 187 of file mn.h.

#define MAXFILENAMELEN   256

Definition at line 185 of file mn.h.

#define MAXGROUPNAMELEN   8

Definition at line 189 of file mn.h.

#define MAXMSG   2048

Definition at line 82 of file mn.h.

Referenced by handle_registration(), and send_registration().

#define MAXOWNERNAMELEN   8

Definition at line 188 of file mn.h.

#define MAXROUTELEN   256

Definition at line 190 of file mn.h.

#define MAXSHAREDSECRETLEN   32

Definition at line 186 of file mn.h.

#define MIN ( x,
 )     (((x) < (y)) ? (x) : (y))

Definition at line 76 of file mn.h.

#define MIN_ALLOWED_LIFETIME   1

Definition at line 172 of file mn.h.

Referenced by handle_icmp().

#define MIN_REGISTRATION_DELAY   1000000

Definition at line 72 of file mn.h.

Referenced by request_tunnel().

#define MIN_REGISTRATION_TIME   1

Definition at line 129 of file mn.h.

Referenced by close_for_home(), and request_tunnel().

#define MIN_SOLICITATION_DELAY   1000000

Definition at line 73 of file mn.h.

#define MN_AAA_REG_TIME   15

Definition at line 166 of file mn.h.

#define MN_CONF_FILE   "dynmnd.conf"

Definition at line 178 of file mn.h.

#define MN_DEFAULT_SYSLOG_FACILITY   LOG_LOCAL0

Definition at line 193 of file mn.h.

Referenced by load_mn().

#define MN_DEFAULT_TUNNEL_LIFETIME   400

Definition at line 192 of file mn.h.

Referenced by load_mn().

#define MN_ENABLE_TUNNELING

Definition at line 63 of file mn.h.

#define MN_ENABLE_VALIDATION

Definition at line 66 of file mn.h.

#define MN_GLOBAL_CONF_FILE   SYSCONFDIR "/" MN_CONF_FILE

Definition at line 180 of file mn.h.

Referenced by mn_init().

#define MN_LOCAL_CONF_FILE   MN_CONF_FILE

Definition at line 179 of file mn.h.

#define MN_PID_FILE   PIDDIR "/dynmnd.pid"

Definition at line 183 of file mn.h.

Referenced by clean_up().

#define MNDECAPS_ROUTE_DEFAULT   0

Definition at line 202 of file mn.h.

Referenced by load_mn(), and start_tunneling().

#define MNDECAPS_ROUTE_HOME_NET   1

Definition at line 203 of file mn.h.

Referenced by start_tunneling().

#define MNDECAPS_ROUTE_NONE   2

Definition at line 204 of file mn.h.

Referenced by start_tunneling().

#define NEWEST_ADV_BIT   8

Definition at line 468 of file mn.h.

#define NEWEST_ADV_STR   "Newest-ADV "

Definition at line 474 of file mn.h.

#define NEWEST_FA_BIT   2

Definition at line 465 of file mn.h.

#define NEWEST_FA_STR   "Newest-FA "

Definition at line 472 of file mn.h.

#define NORMAL_REREGISTRATION_TIME   32

Definition at line 162 of file mn.h.

#define OLD_TUNNEL_EXTRA_TIME   3

Definition at line 123 of file mn.h.

Referenced by restart_tunneling().

#define POLICY ( bit   )     POLICY_BIT(mn.policy_bits, bit)

Definition at line 458 of file mn.h.

Referenced by monitor_check_policy().

#define POLICY_BIT ( bits,
bit   )     (bits & bit)

Definition at line 456 of file mn.h.

#define POLICY_CLR ( bit   )     POLICY_CLR_BIT(mn.policy_bits, bit)

Definition at line 460 of file mn.h.

#define POLICY_CLR_BIT ( bits,
bit   )     (bits &= ~bit)

Definition at line 455 of file mn.h.

#define POLICY_SET ( bit   )     POLICY_SET_BIT(mn.policy_bits, bit)

Definition at line 459 of file mn.h.

#define POLICY_SET_BIT ( bits,
bit   )     (bits |= bit)

Definition at line 454 of file mn.h.

#define REG_CONNECT   1

Definition at line 109 of file mn.h.

Referenced by request_tunnel(), and send_messages().

#define REG_DISC   0

Definition at line 108 of file mn.h.

Referenced by clean_up(), close_for_home(), disconnect(), send_messages(), and send_registration().

#define REG_REREG   2

Definition at line 110 of file mn.h.

Referenced by request_tunnel().

#define SOLICITATION_INTERVALS   {1, 1, 1, 2, 4, 8, 16, 32, 64}

Definition at line 154 of file mn.h.

#define SOLICITATION_PRIO_DEGRADE   10

Definition at line 147 of file mn.h.

#define STATE_INIT   0

Definition at line 119 of file mn.h.

Referenced by close_for_home(), find_agent(), handle_api(), main_vanha(), and request_tunnel().

#define STATE_TIMEOUT   1

Definition at line 120 of file mn.h.

#define SYSLOG_IDENT   "mobile node"

Definition at line 87 of file mn.h.

Referenced by mn_init().

#define SYSLOG_OPTIONS   LOG_PID | LOG_CONS

Definition at line 88 of file mn.h.

Referenced by mn_init().

#define TIMER_ADV   2

Definition at line 95 of file mn.h.

#define TIMER_COUNT   7

Definition at line 104 of file mn.h.

Referenced by mn_init().

#define TIMER_GEN   0

Definition at line 91 of file mn.h.

Referenced by at_home(), close_for_home(), connected(), disconnect(), find_agent(), and request_tunnel().

#define TIMER_LIFETIME   1

Definition at line 93 of file mn.h.

Referenced by connected().

#define TIMER_REQUEST   3

Definition at line 97 of file mn.h.

Referenced by connected(), and send_registration().

#define TIMER_REREG   4

Definition at line 99 of file mn.h.

Referenced by connected().

#define TIMER_SOLICITATION   6

Definition at line 103 of file mn.h.

Referenced by mn_init().

#define TIMER_WLAN_AP_POLL   5

Definition at line 101 of file mn.h.

Referenced by mn_init().

#define TRUE   1

Definition at line 47 of file mn.h.

#define TUNMODE_AUTO_REVERSE   1

Definition at line 206 of file mn.h.

Referenced by load_mn(), and send_registration().

#define TUNMODE_AUTO_TRIANGLE   2

Definition at line 207 of file mn.h.

Referenced by send_registration().

#define TUNMODE_REVERSE   3

Definition at line 208 of file mn.h.

Referenced by adv_ok_fa(), and send_registration().

#define TUNMODE_TRIANGLE   4

Definition at line 209 of file mn.h.

Referenced by adv_ok_fa(), and send_registration().


Enumeration Type Documentation

enum mobile_state

Enumerator:
MN_STARTUP 
MN_DISCONNECTED 
MN_FIND_AGENT 
MN_PASSIVE_FIND 
MN_REQUEST_TUNNEL 
MN_CONNECTED 
MN_CLOSE_FOR_HOME 
MN_AT_HOME 
MN_ERROR 
MN_STOP 
MN_STATE_COUNT 

Definition at line 214 of file mn.h.

00214                   {
00215         MN_STARTUP,
00216         MN_DISCONNECTED,
00217         MN_FIND_AGENT,
00218         MN_PASSIVE_FIND,
00219         MN_REQUEST_TUNNEL,
00220         MN_CONNECTED,
00221         MN_CLOSE_FOR_HOME,
00222         MN_AT_HOME,
00223         MN_ERROR,
00224         MN_STOP,
00225         MN_STATE_COUNT
00226 };


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 adv_ok_fa ( struct agentadv_data adv  ) 

Definition at line 61 of file mn_agentadv.c.

References agentadv_data::addr, agentadv_data::adv, mn_data::force_fa_addr, mn, TUNMODE_REVERSE, TUNMODE_TRIANGLE, and mn_config::tunneling_mode.

00062 {
00063         int opts;
00064 
00065         if (mn.force_fa_addr.s_addr != 0 &&
00066             mn.force_fa_addr.s_addr != adv->addr.s_addr)
00067                 return 0;
00068 
00069         if (adv->adv.ext == NULL)
00070                 return 0;
00071 
00072         opts = ntohs(adv->adv.ext->opts);
00073         if ((opts & AGENT_ADV_BUSY) || !(opts & AGENT_ADV_FOREIGN_AGENT))
00074                 return 0;
00075 
00076         if (config.tunneling_mode == TUNMODE_REVERSE &&
00077             !(opts & AGENT_ADV_BIDIR_TUNNELING))
00078                 return 0;
00079 
00080         if (config.tunneling_mode == TUNMODE_TRIANGLE &&
00081             adv->adv.own_ext != NULL &&
00082             !(adv->adv.own_ext->opts & AGENT_ADV_OWN_TRIANGLE_TUNNELING))
00083                 return 0;
00084 
00085         return 1;
00086 }

void at_home ( void   ) 

Definition at line 730 of file mn.c.

References DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, mn, MN_AT_HOME, mn_remove_dynamic_home_addr(), send_gratuitous_arp(), mn_data::state, TIMER_GEN, and timers.

Referenced by close_for_home(), and main_vanha().

00731 {
00732         DEBUG(DEBUG_INFO, "at_home()\n");
00733         send_gratuitous_arp(config.ha_ip_addr, config.mn_home_ip_addr);
00734         mn.state = MN_AT_HOME;
00735         DEBUG(DEBUG_STATES, "State: At home\n");
00736         DEBUG(DEBUG_TIMERS, "Clearing TIMER_GEN\n");
00737         timerclear(&timers[TIMER_GEN]);
00738         mn_remove_dynamic_home_addr();
00739 }

Here is the call graph for this function:

int check_expired_agent_advs ( void   ) 

Definition at line 508 of file mn_agentadv.c.

References ADV_CLEANUP_FREQ, ADV_EXTRA_TIME, mn_data::agentadv, clean_agentadv(), DEBUG(), FALSE, and mn.

Referenced by main_vanha().

00509 {
00510         static time_t prev_check = 0;
00511         struct timeval now;
00512         struct timeval tmp;
00513         
00514         gettimeofday(&now, NULL);
00515 
00516         if (prev_check <= now.tv_sec &&
00517             now.tv_sec < prev_check + ADV_CLEANUP_FREQ)
00518                 return 0;
00519                 
00520         prev_check = now.tv_sec;
00521         current_agent_expired = FALSE;
00522 
00523         tmp.tv_sec = now.tv_sec - ADV_EXTRA_TIME;
00524         tmp.tv_usec = now.tv_usec;
00525         DEBUG(DEBUG_AGENTADV,
00526               "\tchecking for expired agentadv data\n");
00527         hashtable_iterator(mn.agentadv, clean_agentadv, &tmp);
00528         
00529         if (current_agent_expired) {
00530                 DEBUG(DEBUG_AGENTADV, "Current agent's adv. expired - try to "
00531                       "find new FA\n");
00532                 return 1;
00533         }
00534         
00535         return 0;
00536 }

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 check_old_tunnel_expiration ( void   ) 

Definition at line 151 of file mn_tunnel.c.

Referenced by main_vanha().

00152 {
00153 #ifdef MN_ENABLE_TUNNELING
00154         if (old_tunnel_expire == 0 ||
00155             time(NULL) <= old_tunnel_expire)
00156                 return;
00157 
00158         old_tunnel_expire = 0;
00159         if (dyn_ip_tunnel_del(old_tunnel_device) != 0) {
00160                 LOG2(LOG_ERR, "tunnel delete failed for old tunnel\n");
00161                 return;
00162         }
00163 #endif
00164 }

void clean_up ( int  sig  ) 

Definition at line 52 of file histogram.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.

00053 {
00054         close(sock);
00055 }

Here is the call graph for this function:

void close_for_home ( int  entry  ) 

Definition at line 649 of file mn.c.

References agentadv_data::addr, at_home(), mn_data::co_addr, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, DEBUG_STATES, DEBUG_TIMERS, mn_data::fa_addr, mn_data::HA_reg_retry_time, mn_data::local_addr, LOG2, MAX_REGISTRATION_TIME, MIN_REGISTRATION_TIME, mn, MN_CLOSE_FOR_HOME, real_tunnel_up, REG_DISC, agentadv_data::reg_retry_time, send_gratuitous_arp(), send_registration(), mn_data::session_key, mn_data::session_key_len, mn_config::shared_secret_len, mn_data::state, STATE_INIT, stop_tunneling(), TIMER_GEN, and timers.

00650 {
00651         int retry_time;
00652 
00653         DEBUG(DEBUG_INFO, "close_for_home(%i)\n", entry);
00654 
00655         if (mn.current_adv == NULL) {
00656                 LOG2(LOG_ALERT, "close_for_home - current_adv == NULL\n");
00657         }
00658         if (entry == STATE_INIT) {
00659                 mn.state = MN_CLOSE_FOR_HOME;
00660                 if (real_tunnel_up)
00661                         stop_tunneling();
00662                 else if (config.shared_secret_len < 0 ||
00663                          config.mn_home_ip_addr.s_addr == 0) {
00664                         DEBUG(DEBUG_INFO,
00665                               "close_for_home - not registered; going directly"
00666                               " to home\n");
00667                         at_home();
00668                         return;
00669                 } else {
00670                         DEBUG(DEBUG_INFO,
00671                               "close_for_home - not registered, but trying to "
00672                               "deregister possible old bindings at HA\n");
00673                         if (mn.co_addr.s_addr == 0)
00674                                 mn.co_addr.s_addr = mn.local_addr.s_addr;
00675                 }
00676                 if (mn.current_adv != NULL) {
00677                         DEBUG(DEBUG_TIMERS, "FA[%s] reg_retry_time: "
00678                               "%i => %i (close_for_home)\n",
00679                               inet_ntoa(mn.current_adv->addr),
00680                               mn.current_adv->reg_retry_time,
00681                               MIN_REGISTRATION_TIME);
00682                         mn.current_adv->reg_retry_time = MIN_REGISTRATION_TIME;
00683                 } else
00684                         mn.HA_reg_retry_time = MIN_REGISTRATION_TIME;
00685 
00686                 /* drop the previous session key so that locupd to FA with the
00687                  * old binding goes to the HA */
00688                 if (mn.session_key != NULL)
00689                         free(mn.session_key);
00690                 mn.session_key = NULL;
00691                 mn.session_key_len = 0;
00692         } else if (mn.current_adv == NULL ||
00693                    mn.current_adv->reg_retry_time >= MAX_REGISTRATION_TIME) {
00694                 DEBUG(DEBUG_MESSAGES,
00695                       "Could not get reply from HA - assuming deregistration "
00696                       "worked\n");
00697                 at_home();
00698                 return;
00699         } else if (mn.current_adv != NULL) {
00700                 DEBUG(DEBUG_TIMERS, "FA[%s] reg_retry_time: %i => ",
00701                       inet_ntoa(mn.current_adv->addr),
00702                       mn.current_adv->reg_retry_time);
00703                 if (mn.current_adv->reg_retry_time == 0)
00704                         mn.current_adv->reg_retry_time = 1;
00705                 else
00706                         mn.current_adv->reg_retry_time *= 2;
00707                 DEBUG(DEBUG_TIMERS, "%i\n", mn.current_adv->reg_retry_time);
00708         }
00709 
00710         send_gratuitous_arp(config.ha_ip_addr, config.mn_home_ip_addr);
00711 
00712         /* send deregistration message to HA */
00713         mn.fa_addr = config.ha_ip_addr;
00714         send_registration(REG_DISC);
00715 
00716         /* at least full retry time should be waited */
00717         gettimeofday(&timers[TIMER_GEN], NULL);
00718         retry_time = mn.current_adv ? mn.current_adv->reg_retry_time :
00719                 mn.HA_reg_retry_time;
00720         DEBUG(DEBUG_TIMERS, "close_for_home - TIMER_GEN: set now+%i sec\n",
00721               retry_time);
00722         timers[TIMER_GEN].tv_sec += retry_time;
00723 
00724         DEBUG(DEBUG_STATES, "State: Close for home\n");
00725 }

Here is the call graph for this function:

void connected ( int  type,
__u16  lifetime 
)

Definition at line 513 of file mn.c.

References agentadv_data::addr, ASSERT, CON_HA, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, mn_config::enable_fa_decapsulation, mn_data::fa_addr, agentadv_data::in_use, mn_data::info_str, LOG2, mn, MN_CONNECTED, mn_config::mn_default_tunnel_lifetime, agentadv_data::prio_degrade_percent, real_tunnel_up, remove_fa_host_routes(), restart_tunneling(), start_tunneling(), mn_data::state, TIMER_GEN, TIMER_LIFETIME, TIMER_REQUEST, TIMER_REREG, timers, mn_data::tunnel_addr, mn_data::tunnel_up, and mn_data::warn_str.

00514 {
00515         DEBUG(DEBUG_INFO, "connected(%i, %i)\n", type, lifetime);
00516         ASSERT(lifetime > 0);
00517 
00518         if (mn.current_adv != NULL) {
00519                 if (mn.current_adv->addr.s_addr != mn.fa_addr.s_addr) {
00520                         DEBUG(DEBUG_INFO, "fa_addr=%s != ",
00521                               inet_ntoa(mn.fa_addr));
00522                         DEBUG(DEBUG_INFO, "current_adv->addr=%s\n",
00523                               inet_ntoa(mn.current_adv->addr));
00524                 }
00525                 mn.current_adv->in_use = 1;
00526                 /* This FA works, so don't degrade priority: */
00527                 mn.current_adv->prio_degrade_percent = 0; 
00528         } else {
00529                 LOG2(LOG_WARNING, "connected - current_adv == NULL\n");
00530                 mn.warn_str = "connected - current_adv == NULL";
00531         }
00532 
00533         /* HA MUST NOT use larger lifetime and the FAs cannot change the
00534          * requested lifetime - force the lifetime to be at maximum the
00535          * configured time */
00536         if (lifetime > config.mn_default_tunnel_lifetime) {
00537                 LOG2(LOG_WARNING, "Lifetime in the reply (%i sec) larger than "
00538                      "expected (%i sec) - lowering it\n", lifetime,
00539                      config.mn_default_tunnel_lifetime);
00540                 mn.warn_str = "lifetime in the reply larger than expected";
00541                 lifetime = config.mn_default_tunnel_lifetime;
00542         }
00543 
00544         if (config.enable_fa_decapsulation &&
00545             mn.fa_addr.s_addr != mn.tunnel_addr.s_addr &&
00546             mn.tunnel_addr.s_addr != 0 &&
00547             mn.current_adv != NULL)
00548                 remove_fa_host_routes(0);
00549 
00550         /* if tunnel endpoint has changed, or tunnel is down, create tunnel to
00551          * FA */
00552         if (mn.fa_addr.s_addr != mn.tunnel_addr.s_addr || !real_tunnel_up) {
00553                 if (real_tunnel_up) {
00554                         DEBUG(DEBUG_STATES, "Restart tunneling\n");
00555                         restart_tunneling();
00556                 } else {
00557                         DEBUG(DEBUG_STATES, "Start tunneling\n");
00558                         start_tunneling();
00559                 }
00560         }
00561 
00562         /* set lifetime timer */
00563         timers[TIMER_LIFETIME].tv_sec = timers[TIMER_REQUEST].tv_sec +
00564                 lifetime;
00565         timers[TIMER_LIFETIME].tv_usec = timers[TIMER_REQUEST].tv_usec;
00566 
00567           /* If connection was approved by HA,
00568            * reset timer for reregistering the tunnel */
00569         if (type == CON_HA) {
00570                 set_reregistration_time(lifetime);
00571         }
00572         if (mn.state != MN_CONNECTED && type == CON_HA) {
00573                 LOG2(LOG_INFO, "Connection established.\n");
00574                 mn.info_str = "connection established";
00575         }
00576 
00577         DEBUG(DEBUG_TIMERS, "setting TIMER_GEN = TIMER_REREG %li.%06li (in %li"
00578               " sec)\n",
00579               timers[TIMER_REREG].tv_sec, timers[TIMER_REREG].tv_usec,
00580               timers[TIMER_REREG].tv_sec - time(NULL));
00581         timers[TIMER_GEN] = timers[TIMER_REREG];
00582         mn.state = MN_CONNECTED;
00583         mn.tunnel_up = 1;
00584         DEBUG(DEBUG_STATES, "State: Connected\n");
00585 }

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 degrade_current_fa_priority ( void   ) 

Definition at line 80 of file mn.c.

References mn_data::current_adv, DEBUG(), DEBUG_INFO, DEFAULT_PRIO_DEGRADE_FACTOR, DEFAULT_PRIO_DEGRADE_INITIAL, mn, and agentadv_data::prio_degrade_percent.

Referenced by request_tunnel().

00081 {
00082         if (mn.current_adv == NULL)
00083                 return 1;
00084 
00085         if (mn.current_adv->prio_degrade_percent == 0) {
00086                 mn.current_adv->prio_degrade_percent = 
00087                         DEFAULT_PRIO_DEGRADE_INITIAL;
00088         } else {
00089                 mn.current_adv->prio_degrade_percent *= 
00090                         DEFAULT_PRIO_DEGRADE_FACTOR;
00091         }
00092 
00093         if (mn.current_adv->prio_degrade_percent > 100) {
00094                 mn.current_adv->prio_degrade_percent = 100;
00095         }
00096 
00097         DEBUG(DEBUG_INFO, "degrade_current_fa_priority: %d\n",
00098               mn.current_adv->prio_degrade_percent);
00099         
00100         return 0;
00101 }

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 }

void disconnect ( void   ) 

Definition at line 744 of file mn.c.

References mn_data::cur_route_info, DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, DEBUG_STATES, DEBUG_TIMERS, mn, MN_CONNECTED, MN_DISCONNECTED, mn_remove_dynamic_home_addr(), real_tunnel_up, REG_DISC, send_registration(), mn_data::session_key, mn_data::session_key_len, mn_data::state, stop_tunneling(), TIMER_GEN, and timers.

Referenced by handle_api().

00745 {
00746         DEBUG(DEBUG_INFO, "disconnect()\n");
00747 
00748         mn.cur_route_info.known = 0;
00749 
00750         /* if we are connected, we'd better throw out a
00751          * deregistration message */
00752         if (mn.state == MN_CONNECTED) {
00753                 send_registration(REG_DISC);
00754                 DEBUG(DEBUG_MESSAGES, "Deregistration message sent\n");
00755         }
00756         if (real_tunnel_up) stop_tunneling();
00757 
00758         /* free session key */
00759         if (mn.session_key) {
00760                 free(mn.session_key);
00761                 mn.session_key = NULL;
00762                 mn.session_key_len = 0;
00763         }
00764 
00765         DEBUG(DEBUG_TIMERS, "Clearing TIMER_GEN\n");
00766         timerclear(&timers[TIMER_GEN]);
00767         mn.state = MN_DISCONNECTED;
00768         DEBUG(DEBUG_STATES, "State: Disconnected\n");
00769         syslog(LOG_INFO, "Disconnected.");
00770         mn_remove_dynamic_home_addr();
00771 }

Here is the call graph for this function:

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 }

void find_agent ( int  entry  ) 

find_agent: - STATE_INIT to move to this state STATE_TIMEOUT to indicate timeout in this state, ie.

we haven't received an agent adv to our last sent solicitation

Enter find agent state

Definition at line 308 of file mn.c.

References mn_data::co_addr, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, mn_data::device_count, mn_data::fa_addr, FA_GET_NO, get_fa(), mn_config::home_net_addr_plen, mn_config::home_net_subnet_bc, agentadv_data::in_use, mn_data::local_addr, MAX_RANDOM_SOLICITATION_DELAY, mn, mn_config::mn_default_tunnel_lifetime, MN_FIND_AGENT, passive_find(), mn_data::req_lifetime, request_tunnel(), mn_data::state, STATE_INIT, TIMER_GEN, timers, mn_data::tunnel_mode, and mn_data::tunnel_up.

Referenced by handle_api(), main_vanha(), and request_tunnel().

00309 {
00310         int t, chg;
00311         static int retry_time = 0; /* time in seconds between retries of agent
00312                                     * solicitations */
00313 
00314         DEBUG(DEBUG_INFO, "find_agent(%i)\n", entry);
00315 
00316         mn.tunnel_up = 0;
00317 
00318         if (mn.device_count == 0) {
00319                 passive_find();
00320                 return;
00321         }
00322 
00323         if (mn.tunnel_mode == API_TUNNEL_FULL_HA) {
00324                 DEBUG(DEBUG_INFO,
00325                       "find_agent: trying to register directly to HA\n");
00326                 if (config.ha_ip_addr.s_addr == 0 &&
00327                     config.home_net_addr_plen > -1) {
00328                         /* dynamic HA address resolution */
00329                         mn.fa_addr.s_addr = config.home_net_subnet_bc.s_addr;
00330                 } else
00331                         mn.fa_addr.s_addr = config.ha_ip_addr.s_addr;
00332                 mn.co_addr.s_addr = mn.local_addr.s_addr;
00333                 if (mn.current_adv != NULL) {
00334                         mn.current_adv->in_use = 0;
00335                         mn.current_adv = NULL;
00336                 }
00337                 request_tunnel(STATE_INIT, 0, 0);
00338                 return;
00339         }
00340 
00341         /* try to find the best FA from the previously received agentadvs;
00342          * if a valid entry is found, use it; otherwise send agent
00343          * solicitation */
00344         chg = get_fa(NULL);
00345         if (chg != FA_GET_NO) {
00346                 DEBUG(DEBUG_INFO, "find_agent: found FA from stored agentadv "
00347                       "data - FA=%s, HFA=", inet_ntoa(mn.fa_addr));
00348                 DEBUG(DEBUG_INFO, "%s\n", inet_ntoa(mn.co_addr));
00349                 request_tunnel(STATE_INIT, 0, 0);
00350                 return;
00351         }
00352 
00353         if (entry == STATE_INIT) {
00354                 mn.state = MN_FIND_AGENT;
00355                 retry_time = 0;
00356                 mn.req_lifetime = config.mn_default_tunnel_lifetime;
00357         }
00358 
00359         t = get_solicitation_interval(&retry_time);
00360         if (t == 0) {
00361                 passive_find();
00362                 return;
00363         }
00364 
00365         /* send agent solicitation to all the active interfaces */
00366         send_solicitations(&mn);
00367 
00368         DEBUG(DEBUG_TIMERS, "find_agent - TIMER_GEN: set now+%i sec\n", t);
00369         gettimeofday(&timers[TIMER_GEN], NULL);
00370         timers[TIMER_GEN].tv_sec += t;
00371         add_usecs(&timers[TIMER_GEN],
00372                   get_rand32() % MAX_RANDOM_SOLICITATION_DELAY);
00373 
00374         DEBUG(DEBUG_STATES, "State: Find agent\n");
00375 }

Here is the call graph for this function:

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:

void handle_api ( int  sock,
int  admin 
)

Definition at line 523 of file mn_api.c.

References check_interfaces(), mn_data::co_addr, DEBUG(), DEBUG_API, DEBUG_INFO, disconnect(), find_agent(), GET_MONCONF, GET_MONCONF_VAR, mn_data::ha_error_count, mn_data::iface, IFNAMSIZ, mn_data::last_reg_send_time, mn_data::local_addr, LOG2, mn, MN_CONNECTED, MN_DISCONNECTED, MN_REQUEST_TUNNEL, request_tunnel(), SET_MONCONF_VAR, mn_data::state, STATE_INIT, and mn_data::tunnel_mode.

Referenced by main_vanha().

00524 {
00525         dyn_api_sockaddr addr;
00526         unsigned int addrlen;
00527         struct api_msg msg;
00528 #ifdef MN_LOCUPD_PROFILER
00529         char *name;
00530         char tmp[30];
00531         struct in_addr faaddr;
00532 #endif
00533 
00534         DEBUG(DEBUG_API, "receive from api\n");
00535         addrlen = sizeof(addr);
00536         memset(&addr, 0, addrlen);
00537         if (api_receive(sock, &addr, &addrlen, &msg) < 0) {
00538                 LOG2(LOG_ERR, "api receive: %s\n", strerror(errno));
00539                 return;
00540         }
00541         if (msg.type != API_CALL_MSG) return;
00542 #ifdef MN_LOCUPD_PROFILER
00543         switch (msg.code) {
00544         case API_FORCE_FA:
00545                 memcpy(&faaddr, msg.params, 4);
00546                 snprintf(tmp, sizeof(tmp), "FORCE %s", inet_ntoa(faaddr));
00547                 name = tmp;
00548                 break;
00549         case API_UPDATE_LOCATION: name = "UPDATE"; break;
00550         case API_UPDATE_LOCATION_BLOCK: name = "UPDATEB"; break;
00551         case API_DISCONNECT: name = "DISCONNECT"; break;
00552         case API_CONNECT: name = "CONNECT"; break;
00553         default:
00554                 snprintf(tmp, sizeof(tmp), "%i", msg.code);
00555                 name = tmp;
00556                 break;
00557         }
00558         gettimeofday(&mn.last_api, NULL);
00559         fprintf(mn.profile, "API %s %u.%06u\n", name,
00560                 (unsigned int) mn.last_api.tv_sec,
00561                 (unsigned int) mn.last_api.tv_usec);
00562 #endif
00563         switch (msg.code) {
00564         case API_CONNECT:
00565                 DEBUG(DEBUG_API, "api connect\n");
00566                 if (!admin) break;
00567                 mn.ha_error_count = 0;
00568                 if (mn.state == MN_DISCONNECTED) {
00569                         /* allow quick locupd */
00570                         timerclear(&mn.last_reg_send_time);
00571                         check_interfaces(mn.iface, MAX_INTERFACES);
00572                         memcpy(&mn.tunnel_mode, msg.params,
00573                                sizeof(mn.tunnel_mode));
00574                         DEBUG(DEBUG_API, "tunnel_mode=%i\n", mn.tunnel_mode);
00575                         if (mn.tunnel_mode == API_TUNNEL_FULL_HA &&
00576                             mn.local_addr.s_addr ==
00577                             config.mn_home_ip_addr.s_addr) {
00578                                 struct in_addr iaddr;
00579                                 char device[IFNAMSIZ + 1];
00580                                 if (dyn_ip_route_get(config.ha_ip_addr, device,
00581                                                      IFNAMSIZ) == 0 &&
00582                                     dyn_ip_get_ifaddr(device, &iaddr) == 0 &&
00583                                     mn.local_addr.s_addr != iaddr.s_addr) {
00584                                         DEBUG(DEBUG_INFO,
00585                                               "Address changed to %s\n",
00586                                               inet_ntoa(iaddr));
00587                                         mn.local_addr.s_addr = iaddr.s_addr;
00588                                 }
00589                         }
00590                         find_agent(STATE_INIT);
00591                         memcpy(&api_addr, &addr, sizeof(addr));
00592                         api_addr_len = addrlen;
00593                         /* this API call is replied with reply_waiting_api
00594                          * after the status of the connection attempt is known
00595                          */
00596                 } else {
00597                         api_send_reply(sock, &addr, addrlen, API_NOT_PERMITTED,
00598                                        NULL, 0);
00599                 }
00600                 break;
00601         case API_UPDATE_LOCATION:
00602                 DEBUG(DEBUG_API, "api update location\n");
00603                 if (!admin) break;
00604                 check_interfaces(mn.iface, MAX_INTERFACES);
00605                 handle_api_locupd(sock, &addr, addrlen, &msg, 0);
00606                 break;
00607         case API_UPDATE_LOCATION_BLOCK:
00608                 DEBUG(DEBUG_API, "api update location (block)\n");
00609                 if (!admin) break;
00610                 check_interfaces(mn.iface, MAX_INTERFACES);
00611                 handle_api_locupd(sock, &addr, addrlen, &msg, 1);
00612                 memcpy(&api_addr, &addr, sizeof(addr));
00613                 api_addr_len = addrlen;
00614                 /* this API call is replied with reply_waiting_api
00615                  * after the status of the connection attempt is known */
00616                 break;
00617         case API_CANCEL:
00618                 DEBUG(DEBUG_API, "Cancel received.\n");
00619                 if (!admin) break;
00620 
00621                 api_send_reply(sock, &addr, addrlen, API_SUCCESS, NULL, 0);
00622                 break;
00623         case API_DISCONNECT:
00624                 DEBUG(DEBUG_API, "api disconnect\n");
00625                 if (!admin) break;
00626                 check_interfaces(mn.iface, MAX_INTERFACES);
00627                 disconnect();
00628                 api_send_reply(sock, &addr, addrlen, API_SUCCESS, NULL, 0);
00629                 break;
00630         case API_GET_CAREOF_ADDR:
00631                 api_send_reply(sock, &addr, addrlen, API_SUCCESS,
00632                                (unsigned char *) &mn.co_addr,
00633                                sizeof(mn.co_addr));
00634                 break;
00635         case API_GET_TUNNELING_MODE:
00636                 api_send_reply(sock, &addr, addrlen, API_SUCCESS,
00637                                (unsigned char *) &mn.tunnel_mode, sizeof(int));
00638                 break;
00639         case API_GET_STATUS:
00640                 api_send_reply(sock, &addr, addrlen, API_SUCCESS,
00641                                (unsigned char *) get_mobile_status(),
00642                                sizeof(struct dynamics_mobile_status));
00643                 break;
00644         case API_CONFIRM:
00645                 DEBUG(DEBUG_API, "api confirm\n");
00646                 if (!admin) break;
00647                 if (mn.state != MN_CONNECTED &&
00648                     mn.state != MN_REQUEST_TUNNEL)  {
00649                         api_send_reply(sock, &addr, addrlen,
00650                                        API_NOT_PERMITTED, NULL, 0);
00651                         break;
00652 
00653                 }
00654                 memcpy(&api_addr, &addr, sizeof(addr));
00655                 api_addr_len = addrlen;
00656                 request_tunnel(STATE_INIT, 1, 0);
00657                 break;
00658         case API_FORCE_FA:
00659                 DEBUG(DEBUG_API, "api force fa\n");
00660                 if (!admin) break;
00661                 handle_api_force_fa(sock, &addr, addrlen, &msg);
00662                 break;
00663         case API_GET_FA_LIST:
00664                 DEBUG(DEBUG_API, "api get fa list\n");
00665                 handle_api_get_fa_list(sock, &addr, addrlen, &msg);
00666                 break;
00667         case API_GET_FA_INFO:
00668                 DEBUG(DEBUG_API, "api get fa info\n");
00669                 handle_api_get_fa_info(sock, &addr, addrlen, &msg);
00670                 break;
00671 #ifdef WITH_WIRELESS
00672         case API_IW_GET_CH:
00673                 DEBUG(DEBUG_API, "api get wireless channel info\n");
00674                 handle_api_get_iw_ch(sock, &addr, addrlen, &msg);
00675                 break;
00676         case API_IW_SET_CH:
00677                 DEBUG(DEBUG_API, "api set wireless channel info\n");
00678                 if (!admin) break;
00679                 handle_api_set_iw_ch(sock, &addr, addrlen, &msg);
00680                 break;
00681 #endif
00682         case API_RESCAN:
00683                 DEBUG(DEBUG_API, "api rescan interfaces\n");
00684                 handle_api_rescan(sock, &addr, addrlen, &msg);
00685                 break;
00686         case API_REGISTER_DEV_INFO_SOCKET:
00687                 DEBUG(DEBUG_API, "api register dev info socket\n");
00688                 if (!admin) break;
00689                 handle_register_dev_info_socket(sock, &addr, addrlen, &msg);
00690                 break;
00691         case API_POLICY_OFF:
00692                 DEBUG(DEBUG_API, "api policy off\n");
00693                 if (!admin) break;
00694                 handle_policy(sock, &addr, addrlen, &msg, 0);
00695                 break;
00696         case API_POLICY_ON:
00697                 DEBUG(DEBUG_API, "api policy on\n");
00698                 if (!admin) break;
00699                 handle_policy(sock, &addr, addrlen, &msg, 1);
00700                 break;
00701         case API_GET_POLICY:
00702                 DEBUG(DEBUG_API, "api get policy\n");
00703                 handle_get_policy(sock, &addr, addrlen, &msg);
00704                 break;
00705 #ifdef WITH_WIRELESS
00706         case API_GET_MON_CONF:
00707                 DEBUG(DEBUG_API, "api get mon conf\n");
00708                 handle_mon_conf(sock, &addr, addrlen, &msg, GET_MONCONF);
00709                 break;
00710         case API_GET_MON_CONF_VAR:
00711                 DEBUG(DEBUG_API, "api get mon conf var\n");
00712                 handle_mon_conf(sock, &addr, addrlen, &msg, GET_MONCONF_VAR);
00713                 break;
00714         case API_SET_MON_CONF_VAR:
00715                 DEBUG(DEBUG_API, "api set mon conf\n");
00716                 if (!admin) break;
00717                 handle_mon_conf(sock, &addr, addrlen, &msg, SET_MONCONF_VAR);
00718                 break;
00719 #endif
00720         default:
00721                 /* Just send a message indicating that the function is not
00722                  * supported. No need to confirm that message gets through. */
00723                 DEBUG(DEBUG_API, "api call not supported\n");
00724                 api_send_reply(sock, &addr, addrlen, API_NOT_SUPPORTED, NULL,
00725                                0);
00726                 break;
00727         }
00728 }

Here is the call graph for this function:

int handle_registration ( int  s  ) 

Definition at line 1402 of file mn_reg.c.

References DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, mn_data::discarded_msgs, mn_data::last_challenge_ext, mn_data::last_challenge_time, mn_data::last_nonce, mn_data::last_reply_code, mn_data::last_reply_rcvd, LOG2, MAXMSG, mobile::mn, mn, mobile_array, mn_data::prev_req_replied, and mn_data::try_to_fix_sec_assoc.

Referenced by main_vanha().

01403 {
01404         char msg[MAXMSG];
01405         unsigned int len;
01406         struct sockaddr_in addr;
01407         int n, res;
01408         struct msg_extensions ext;
01409 
01410         len = sizeof(addr);
01411 
01412         n = recvfrom(s, msg, MAXMSG, 0, (struct sockaddr*) &addr, &len);
01413         if (n < 0) {
01414                 LOG2(LOG_ERR, "registration recv: %s\n", strerror(errno));
01415                 return 0;
01416         }
01417         DEBUG(DEBUG_MESSAGES, "Received %d bytes from %s:%d\n", n,
01418                inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
01419 
01420         res = parse_msg(msg, n, &ext);
01421         if (res != 0 || ext.double_auth_ext != 0) {
01422                 char *reason = "N/A";
01423                 DEBUG(DEBUG_MESSAGES, "Dropping invalid message\n");
01424                 mobile_array[cur_mobile].mn.discarded_msgs++;
01425                 if (res == -1)
01426                         reason = "unknown extension";
01427                 else if (res == -2)
01428                         reason = "malformed message";
01429                 else if (res == -3 || res == -4 || res == -5)
01430                         reason = "unknown vendor extension";
01431                 else if (ext.double_auth_ext != 0)
01432                         reason = "double authentication extension";
01433                 report_discarded_msg(msg, n, &addr, reason);
01434                 return 0;
01435         }
01436 
01437         mobile_array[cur_mobile].mn.try_to_fix_sec_assoc = 0;
01438         if (is_valid_reply(&ext, addr)) {
01439                 mobile_array[cur_mobile].mn.prev_req_replied = 1;
01440                 time(&mobile_array[cur_mobile].mn.last_reply_rcvd);
01441                 mobile_array[cur_mobile].mn.last_reply_code = ext.rep->code;
01442                 mobile_array[cur_mobile].mn.last_nonce = ext.rep->id[0];
01443                 if (ext.challenge != NULL) {
01444                         int len;
01445                         gettimeofday(&mobile_array[cur_mobile].mn.last_challenge_time, NULL);
01446                         len = GET_CHALLENGE_EXT_LEN(ext.challenge);
01447                         if (mobile_array[cur_mobile].mn.last_challenge_ext == NULL ||
01448                             GET_CHALLENGE_EXT_LEN(mobile_array[cur_mobile].mn.last_challenge_ext) !=
01449                             len) {
01450                                 if (mobile_array[cur_mobile].mn.last_challenge_ext != NULL)
01451                                         free(mobile_array[cur_mobile].mn.last_challenge_ext);
01452                                 mobile_array[cur_mobile].mn.last_challenge_ext =
01453                                         (struct challenge_ext *) malloc(len);
01454                         }
01455 
01456                         if (mobile_array[cur_mobile].mn.last_challenge_ext != NULL)
01457                                 memcpy(mobile_array[cur_mobile].mn.last_challenge_ext, ext.challenge,
01458                                        len);
01459                         else
01460                                 DEBUG(DEBUG_INFO, "Could not malloc() memory "
01461                                       "for challenge extension\n");
01462                 }
01463                 if (IS_REGREP_ACCEPTED(ext.rep->code))
01464                         handle_reg_accept(&ext);
01465                 else
01466                         return handle_reg_denied(&ext);
01467         } else {
01468                 report_discarded_msg(msg, n, &addr, "invalid reply");
01469                 mobile_array[cur_mobile].mn.discarded_msgs++;
01470         }
01471 
01472         return 0;
01473 }

Here is the call graph for this function:

pid_t init_pcap_for_advs ( void   ) 

Definition at line 78 of file win_adv_capture.c.

References dst_data::addr, DEBUG(), and dst_data::s.

Referenced by mn_init().

00079 {
00080         pcap_t *fp;
00081         char error[PCAP_ERRBUF_SIZE];
00082         char *dev;
00083         struct dst_data dst;
00084         pid_t pid;
00085 
00086         pid = fork();
00087         if (pid < 0) {
00088                 DEBUG(DEBUG_INFO, "init_pcap_for_advs: fork failed: %s\n",
00089                       strerror(errno));
00090                 return -1;
00091         }
00092 
00093         if (pid > 0) {
00094                 /* in parent - return */
00095                 return pid;
00096         }
00097 
00098         dst.s = socket(AF_INET, SOCK_DGRAM, 0);
00099         if (dst.s < 0) {
00100                 perror("socket");
00101                 exit(1);
00102         }
00103         dst.addr.sin_family = AF_INET;
00104         dst.addr.sin_addr.s_addr = htonl((127 << 24 | 1));
00105         dst.addr.sin_port = htons(4344);
00106 
00107         /* FIX: should support more than one interface and also detect new
00108          * interfaces when, e.g., wireless LAN card is inserted */
00109 
00110         dev = pcap_lookupdev(error);
00111         if (dev == NULL) {
00112                 DEBUG(DEBUG_INFO,
00113                       "init_pcap_for_advs: Could not get device (%s)\n",
00114                       error);
00115                 return -1;
00116         }
00117 
00118         DEBUG(DEBUG_INFO, "init_pcap_for_advs: using device '%s'\n", dev);
00119         fp = pcap_open_live(dev, 1500, 0, 20, error);
00120         if (fp == NULL) {
00121                 DEBUG(DEBUG_INFO, "pcap_open_live failed (%s)\n", error);
00122                 return -1;
00123         }
00124 
00125         if (pcap_setfilter(fp, &agentadv_fprog) < 0) {
00126                 DEBUG(DEBUG_INFO,
00127                       "init_pcap_for_advs: Could not attach BPF\n");
00128                 return -1;
00129         }
00130 
00131         /* in child - start capturing packets */
00132         DEBUG(DEBUG_INFO, "init_pcap_for_advs: child starting to capture "
00133               "packets\n");
00134 
00135         pcap_loop(fp, 0, dispatcher_handler, (u_char *) &dst);
00136 
00137         /* never reached */
00138         DEBUG(DEBUG_INFO, "pcap_loop returned?!\n");
00139         return 0;
00140 }

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 load_mn ( struct mn_config cfg,
char *  program_name,
char *  config_file 
)

Definition at line 543 of file mn_config.c.

References mn_config::alt_ha_ip_addrs, mn_config::auth_alg, load_mn_data::cfg, mn_config::fa_spi_list, FALSE, mn_config::ha_ip_addr_orig, mn_config::home_net_addr, mn_config::home_net_addr_plen, mn_config::home_net_subnet_bc, mn_config::ignore_iflist, mn, MN_DEFAULT_SYSLOG_FACILITY, mn_config::mn_default_tunnel_lifetime, MN_DEFAULT_TUNNEL_LIFETIME, mn_config::mn_home_ip_addr_orig, MNDECAPS_ROUTE_DEFAULT, mn_config::mndecaps_route_handling, mn_config::replay_meth, mn_config::shared_secret_len, mn_config::socket_priority, mn_config::solicitation_interval, mn_config::syslog_facility, TRUE, TUNMODE_AUTO_REVERSE, mn_config::tunneling_mode, mn_config::udp_port, mn_config::use_hadisc, and mn_config::wlan_ap_poll_interval.

Referenced by mn_init().

00543                                                                           {
00544         FILE *file;
00545         struct load_mn_data mn;
00546         int i;
00547 
00548         mn.cfg = cfg;
00549         memset(cfg, '\0', sizeof(struct mn_config));
00550         cfg->mn_default_tunnel_lifetime = MN_DEFAULT_TUNNEL_LIFETIME;
00551         cfg->syslog_facility = MN_DEFAULT_SYSLOG_FACILITY;
00552 
00553         cfg->shared_secret_len = -1;
00554         cfg->auth_alg = 1;
00555         cfg->replay_meth = 1;
00556         cfg->udp_port = 434;
00557         cfg->socket_priority = -1;
00558         cfg->home_net_addr_plen = -1;
00559         cfg->mndecaps_route_handling = MNDECAPS_ROUTE_DEFAULT;
00560         cfg->tunneling_mode = TUNMODE_AUTO_REVERSE;
00561         cfg->wlan_ap_poll_interval = -1;
00562         cfg->solicitation_interval = -1;
00563         mn.process_fa_spi_list = FALSE;
00564         mn.process_ignore_iflist = FALSE;
00565         list_init(&cfg->fa_spi_list);
00566         list_init(&cfg->ignore_iflist);
00567         list_init(&cfg->alt_ha_ip_addrs);
00568 
00569 #ifdef BIND_UDP_SOCKET
00570         cfg->bind_addr.s_addr = INADDR_ANY;
00571         cfg->bind_port = htons(cfg->udp_port);
00572 #endif
00573 
00574         file = fopen(config_file, "r");
00575         if (file == NULL) {
00576                 fprintf(stderr,
00577                         "%s: Could not open configuration file '%s'.\n",
00578                         program_name, config_file);
00579                 return FALSE;
00580         }
00581         if (load_data(&mn, file, process_load_mn) == FALSE) {
00582                 fprintf(stderr,
00583                         "load_mn: Error while interpreting file '%s'!\n",
00584                         config_file);
00585                 fclose(file);
00586                 return FALSE;
00587         }
00588         fclose(file);
00589 
00590         if (cfg->home_net_addr_plen > -1) {
00591                 /* determine home net's subnet-direct broadcast address */
00592                 __u32 ones = 0;
00593                 for (i = cfg->home_net_addr_plen; i < 32; i++) {
00594                         ones |= 1 << (31 - i);
00595                 }
00596                 cfg->home_net_subnet_bc.s_addr = cfg->home_net_addr.s_addr |
00597                         htonl(ones);
00598         }
00599 
00600         if (cfg->ha_ip_addr.s_addr == 0)
00601                 cfg->use_hadisc = TRUE;
00602 
00603         cfg->ha_ip_addr_orig.s_addr = cfg->ha_ip_addr.s_addr;
00604         cfg->mn_home_ip_addr_orig.s_addr = cfg->mn_home_ip_addr.s_addr;
00605 
00606         return check_config_data(cfg);
00607 }

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 passive_find ( void   ) 

Definition at line 268 of file mn.c.

References DEBUG(), DEBUG_STATES, mn, MN_PASSIVE_FIND, and mn_data::state.

Referenced by find_agent().

00269 {
00270         mn.state = MN_PASSIVE_FIND;
00271         DEBUG(DEBUG_STATES, "State: Passive find\n");
00272 }

Here is the call graph for this function:

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 reply_waiting_api ( int  code,
unsigned char *  data,
int  datalen 
)

Definition at line 736 of file mn_api.c.

References mn_data::api_rw_socket, DEBUG(), DEBUG_API, and mn.

Referenced by clean_up(), close_tunneling(), and request_tunnel().

00737 {
00738 #ifdef DYN_TARGET_LINUX
00739         if (api_addr_len > 0) {
00740 #endif
00741 #ifdef DYN_TARGET_WINDOWS
00742         if (api_addr.sin_port != 0) {
00743 #endif
00744                 DEBUG(DEBUG_API, "Replying to waiting API call\n");
00745                 api_send_reply(mn.api_rw_socket, &api_addr, api_addr_len, code,
00746                                data, datalen);
00747                 memset(&api_addr, 0, sizeof(api_addr));
00748                 api_addr_len = 0;
00749         } else DEBUG(DEBUG_API, "reply_waiting_api: no waiting call\n");

Here is the call graph for this function:

void request_tunnel ( int  entry,
int  forced,
int  check_timer 
)

rqeuest_tunnel: : STATE_INIT to move to this state, STATE_TIMEOUT to indicate timeout in this state, i.e.

no reply for last request within retry time

Enter request tunnel state

Definition at line 386 of file mn.c.

References add_fa_host_route(), agentadv_data::addr, mn_data::agentadv, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, degrade_current_fa_priority(), mn_config::enable_fa_decapsulation, mn_data::fa_addr, find_agent(), mn_data::HA_reg_retry_time, agentadv_data::ifindex, agentadv_data::ifname, mn_data::info_str, mn_data::last_reg_send_time, MAX_REGISTRATION_TIME, MIN_REGISTRATION_DELAY, MIN_REGISTRATION_TIME, mn, MN_REQUEST_TUNNEL, REG_CONNECT, REG_REREG, agentadv_data::reg_retry_time, reply_waiting_api(), send_registration(), mn_data::state, STATE_INIT, TIMER_GEN, timers, mn_data::tunnel_up, mn_config::use_hadisc, and mn_data::warn_str.

Referenced by find_agent(), and handle_api().

00387 {
00388         int retry_time;
00389 
00390         DEBUG(DEBUG_INFO, "request_tunnel(%i, %i, %i)\n", entry, forced,
00391               check_timer);
00392 
00393         if (mn.current_adv == NULL) {
00394                 retry_time = mn.HA_reg_retry_time;
00395                 DEBUG(DEBUG_INFO, "No current agent advertisement " 
00396                       "when requesting tunnel (direct tunnel to HA?)\n");
00397         } else
00398                 retry_time = mn.current_adv->reg_retry_time;
00399 
00400         if (check_timer && retry_time > 1) {
00401                 struct timeval now;
00402                 gettimeofday(&now, NULL);
00403                 if (timerisset(&timers[TIMER_GEN]) &&
00404                     cmp_timeval(&now, &timers[TIMER_GEN]) < 0) {
00405                         DEBUG(DEBUG_TIMERS, "request_tunnel: TIMER_GEN not "
00406                               "yet reached\n");
00407                         return;
00408                 }
00409         }
00410 
00411         if (config.enable_fa_decapsulation && mn.current_adv != NULL)
00412                 add_fa_host_route(mn.current_adv->ifname, mn.agentadv,
00413                                   mn.current_adv->ifindex, mn.fa_addr);
00414 
00415         if (entry == STATE_INIT) {
00416                 mn.state = MN_REQUEST_TUNNEL;
00417                 if (!forced)
00418                         mn.tunnel_up = 0;
00419 
00420                 /* if last registration was sent less than a second ago,
00421                    wait a second before sending the request */
00422                 if (usec_passed(&mn.last_reg_send_time, NULL) <
00423                     MIN_REGISTRATION_DELAY) {
00424                         DEBUG(DEBUG_INFO, "Too frequent registration request "
00425                               "- delaying\n");
00426                         DEBUG(DEBUG_TIMERS, "request_tunnel: TIMER_GEN: set "
00427                               "now+1 sec (too freq.)\n");
00428                         gettimeofday(&timers[TIMER_GEN], NULL);
00429                         timers[TIMER_GEN].tv_sec++;
00430                         return;
00431                 }
00432         } else if (retry_time > MAX_REGISTRATION_TIME) {
00433                 /* STATE_TIMEOUT */
00434                 if (config.use_hadisc) {
00435                         DEBUG(DEBUG_INFO, "HA does not reply - try to discover"
00436                               " another HA\n");
00437                         mn.info_str = "restarting HA discovery";
00438                         config.ha_ip_addr.s_addr = 0;
00439                         if (mn.current_adv != NULL)
00440                                 mn.current_adv->reg_retry_time =
00441                                         MIN_REGISTRATION_TIME;
00442                         else
00443                                 mn.HA_reg_retry_time =
00444                                         MIN_REGISTRATION_TIME;
00445                 } else {
00446                         /* give up, switch to find agent */
00447                         if (forced) {
00448                                 DEBUG(DEBUG_INFO,
00449                                       "Could not confirm tunnel.\n");
00450                                 reply_waiting_api(API_FAILED, NULL, 0);
00451                         } else {
00452                                 DEBUG(DEBUG_INFO, "Could not register.\n");
00453                         }
00454                         find_agent(STATE_INIT);
00455                         return;
00456                 }
00457         } else if (mn.current_adv != NULL) {
00458                 /* STATE_TIMEOUT */
00459 #ifndef NO_PRIO_DEGRADE
00460                 /* degrade the FA priority */
00461                 degrade_current_fa_priority();
00462 #endif /* NO_PRIO_DEGRADE */
00463                 DEBUG(DEBUG_TIMERS, "FA[%s] reg_retry_time: %i => ",
00464                       inet_ntoa(mn.current_adv->addr),
00465                       mn.current_adv->reg_retry_time);
00466                 if (mn.current_adv->reg_retry_time == 0)
00467                         mn.current_adv->reg_retry_time = MIN_REGISTRATION_TIME;
00468                 else
00469                         mn.current_adv->reg_retry_time *= 2;
00470                 DEBUG(DEBUG_TIMERS, "%i\n", mn.current_adv->reg_retry_time);
00471         } else {
00472                 if (mn.HA_reg_retry_time == 0)
00473                         mn.HA_reg_retry_time = MIN_REGISTRATION_TIME;
00474                 else
00475                         mn.HA_reg_retry_time *= 2;
00476         }
00477 
00478         if (send_registration(forced ? REG_REREG : REG_CONNECT) < 0) {
00479                 DEBUG(DEBUG_INFO, "Registration failed for this FA - trying to"
00480                       " find a new one\n");
00481                 mn.warn_str = "Registration failed for this FA, trying to find"
00482                         " a new one";
00483                 find_agent(STATE_INIT);
00484                 return;
00485         }
00486 
00487         gettimeofday(&timers[TIMER_GEN], NULL);
00488         if (mn.current_adv != NULL) {
00489                 if (mn.current_adv->reg_retry_time < MIN_REGISTRATION_TIME)
00490                         mn.current_adv->reg_retry_time = MIN_REGISTRATION_TIME;
00491                 retry_time = mn.current_adv->reg_retry_time;
00492         } else {
00493                 if (mn.HA_reg_retry_time < MIN_REGISTRATION_TIME)
00494                         mn.HA_reg_retry_time = MIN_REGISTRATION_TIME;
00495                 retry_time = mn.HA_reg_retry_time;
00496         }
00497         DEBUG(DEBUG_TIMERS, "request_tunnel - TIMER_GEN: set now+%i sec\n",
00498               retry_time);
00499         timers[TIMER_GEN].tv_sec += retry_time;
00500 
00501         DEBUG(DEBUG_STATES, "State: Request tunnel%s\n",
00502               forced ? " (forced)" : "");
00503 }

Here is the call graph for this function:

int restart_tunneling ( void   ) 

Definition at line 359 of file mn_tunnel.c.

Referenced by connected().

00360 {
00361 #ifdef MN_ENABLE_TUNNELING
00362         struct in_addr old;
00363 
00364         /* roll tunnel device names */
00365         if (!tunnel_b_up) {
00366                 dynamics_strlcpy(tunnel_device, TUNNEL_DEVICE_B,
00367                                  sizeof(tunnel_device));
00368                 tunnel_b_up = 1;
00369         } else {
00370                 dynamics_strlcpy(tunnel_device, TUNNEL_DEVICE,
00371                                  sizeof(tunnel_device));
00372                 tunnel_b_up = 0;
00373         }
00374         old.s_addr = mn.tunnel_addr.s_addr;
00375 
00376         mn.tunnel_up = 0;
00377         real_tunnel_up = 0;
00378         start_tunneling();
00379 
00380         if (tunnel_b_up)
00381                 dynamics_strlcpy(old_tunnel_device, TUNNEL_DEVICE,
00382                                  sizeof(old_tunnel_device));
00383         else
00384                 dynamics_strlcpy(old_tunnel_device, TUNNEL_DEVICE_B,
00385                                  sizeof(old_tunnel_device));
00386 
00387         if (!config.enable_fa_decapsulation) {
00388                 /* Mark the old tunnel to be deleted */
00389                 old_tunnel_addr.s_addr = old.s_addr;
00390                 old_tunnel_expire = time(NULL) + OLD_TUNNEL_EXTRA_TIME;
00391         }
00392 
00393 #else
00394         DEBUG(DEBUG_INFO, "Restart tunneling - tunneling disabled\n");
00395 #endif
00396         return 0;
00397 }

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 send_registration ( int  request_type  ) 

Definition at line 580 of file mn_reg.c.

References add_fa_host_route(), agentadv_data::addr, agentadv_data::adv, agentadv_data::adv_type, mn_data::agentadv, agentadv_data::arpentry, mobile::config, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, DEBUG_TIMERS, mn_config::enable_fa_decapsulation, mn_data::fa_addr, agentadv_data::ifindex, agentadv_data::ifname, agentadv_data::in_use, mn_data::last_reg_send_time, mn_data::last_request_sent, LOG2, MAXMSG, mn, mobile::mn, MN_ADV_TYPE_FA, mobile_array, REG_DISC, agentadv_data::reg_failed, mn_data::registration_id, mn_data::registration_socket, agentadv_data::routeentry, TIMER_REQUEST, timers, TUNMODE_AUTO_REVERSE, TUNMODE_AUTO_TRIANGLE, TUNMODE_REVERSE, TUNMODE_TRIANGLE, mn_config::tunneling_mode, and mn_config::udp_port.

Referenced by clean_up(), close_for_home(), disconnect(), request_tunnel(), and send_messages().

00581 {
00582         char sendbuf[MAXMSG];
00583         char *pos; /* pointer to next byte to write in sendbuf */
00584         int n, len;
00585         struct sockaddr_in addr;
00586         int use_reverse;
00587         struct msg_extensions ext;
00588 
00589         if (MAXMSG < (sizeof(struct reg_req) +
00590                       2 * (sizeof(struct msg_auth) + 16))) {
00591                 DEBUG(DEBUG_INFO, "MN: send_reg: too small send buffer!");
00592 
00593                 return -1;
00594         }
00595 
00596         use_reverse = mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_AUTO_REVERSE ||
00597                 mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_REVERSE;
00598 
00599         if (mobile_array[cur_mobile].mn.current_adv != NULL) {
00600                 if (mobile_array[cur_mobile].mn.current_adv->addr.s_addr != mobile_array[cur_mobile].mn.fa_addr.s_addr) {
00601                         DEBUG(DEBUG_INFO, "fa_addr=%s != ",
00602                               inet_ntoa(mobile_array[cur_mobile].mn.fa_addr));
00603                         DEBUG(DEBUG_INFO, "current_adv->addr=%s\n",
00604                               inet_ntoa(mobile_array[cur_mobile].mn.current_adv->addr));
00605                 }
00606 
00607                 DEBUG(DEBUG_INFO, "Setting in_use=%i for FA %s (send reg)\n",
00608                       request_type == REG_DISC ? 0 : 1,
00609                       inet_ntoa(mobile_array[cur_mobile].mn.current_adv->addr));
00610                 mobile_array[cur_mobile].mn.current_adv->in_use = request_type == REG_DISC ? 0 : 1;
00611                 if (mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_AUTO_REVERSE &&
00612                     (ntohs(mobile_array[cur_mobile].mn.current_adv->adv.ext->opts) &
00613                      AGENT_ADV_BIDIR_TUNNELING) == 0)
00614                         use_reverse = 0;
00615                 if (mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_AUTO_TRIANGLE &&
00616                     mobile_array[cur_mobile].mn.current_adv->adv.own_ext != NULL &&
00617                     (mobile_array[cur_mobile].mn.current_adv->adv.own_ext->opts &
00618                      AGENT_ADV_OWN_TRIANGLE_TUNNELING) == 0)
00619                         use_reverse = 1;
00620         } else {
00621                 DEBUG(DEBUG_INFO,
00622                       "send_registration: current_adv == NULL!?\n");
00623         }
00624 
00625         if ((use_reverse && mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_TRIANGLE) ||
00626             (!use_reverse && mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_REVERSE)) {
00627                 DEBUG(DEBUG_INFO, "FA does not support wanted tunneling mode -"
00628                       " aborting registration\n");
00629                 if (mobile_array[cur_mobile].mn.current_adv != NULL)
00630                         mobile_array[cur_mobile].mn.current_adv->reg_failed = 1;
00631                 return -1;
00632         }
00633 
00634         if (use_reverse)
00635                 DEBUG(DEBUG_MESSAGES, "Requesting reverse tunneling\n");
00636 
00637         pos = sendbuf;
00638 
00639         DEBUG(DEBUG_MESSAGES, "Sending registration message:\n * header\n");
00640         n = fill_req_header(pos, request_type, use_reverse);
00641         if (n < 0) return -1;
00642         pos += n;
00643 
00644         n = add_req_extensions(pos, MAXMSG - n, sendbuf, request_type,
00645                                use_reverse);
00646         if (n < 0) {
00647                 LOG2(LOG_ERR, "Registration request buffer overflow - unable"
00648                      " to send the request\n");
00649                 return -1;
00650         }
00651         pos += n;
00652 
00653         len = (int) (pos - sendbuf);
00654         assert(len <= MAXMSG);
00655 
00656         /* call parse_msg() to parse the message in order to get the details
00657          * of the sent message into debug output; in addition, this validates
00658          * the format of the request */
00659         if (parse_msg(sendbuf, len, &ext) != 0) {
00660                 DEBUG(DEBUG_INFO, "WARNING! Own registration request was not "
00661                       "valid!\n");
00662         }
00663 
00664         /* add ARP entry, if not already added */
00665         if (mobile_array[cur_mobile].mn.current_adv != NULL &&
00666             mobile_array[cur_mobile].mn.current_adv->adv_type == MN_ADV_TYPE_FA &&
00667             !mobile_array[cur_mobile].mn.current_adv->arpentry) {
00668                 struct sockaddr hwaddr;
00669                 DEBUG(DEBUG_INFO, "Adding ARP entry for FA\n");
00670                 memset(&hwaddr, 0, sizeof(hwaddr));
00671                 hwaddr.sa_family = ARPHRD_ETHER;
00672 #ifdef DYN_TARGET_LINUX
00673                 memcpy(hwaddr.sa_data, mobile_array[cur_mobile].mn.current_adv->adv.from.sll_addr,
00674                        mobile_array[cur_mobile].mn.current_adv->adv.from.sll_halen);
00675 #else
00676                 memcpy(hwaddr.sa_data, mobile_array[cur_mobile].mn.current_adv->adv.eth->h_source,
00677                        ETH_ALEN);
00678 #endif
00679                 if (arp_add_permanent_item(mobile_array[cur_mobile].mn.current_adv->addr,
00680                                            mobile_array[cur_mobile].mn.current_adv->ifname,
00681                                            &hwaddr) < 0) {
00682                         LOG2(LOG_WARNING, "arp_add_permanent_item(%s, %s, %s) "
00683                              "failed\n", inet_ntoa(mobile_array[cur_mobile].mn.current_adv->addr),
00684                              mobile_array[cur_mobile].mn.current_adv->ifname,
00685                              ether_hwtoa((unsigned char *)hwaddr.sa_data));
00686                 }
00687                 mobile_array[cur_mobile].mn.current_adv->arpentry = 1;
00688         }
00689 
00690         /* add host route to FA, if not already added */
00691         if (mobile_array[cur_mobile].config.enable_fa_decapsulation &&
00692             mobile_array[cur_mobile].mn.current_adv != NULL &&
00693             mobile_array[cur_mobile].mn.current_adv->adv_type == MN_ADV_TYPE_FA &&
00694             !mobile_array[cur_mobile].mn.current_adv->routeentry) {
00695                 DEBUG(DEBUG_INFO, "Adding routing entry for FA\n");
00696                 add_fa_host_route(mobile_array[cur_mobile].mn.current_adv->ifname, mobile_array[cur_mobile].mn.agentadv,
00697                                   mobile_array[cur_mobile].mn.current_adv->ifindex, mobile_array[cur_mobile].mn.fa_addr);
00698         }
00699 
00700         /* send the message */
00701         memset(&addr, 0, sizeof(addr));
00702         addr.sin_family = AF_INET;
00703        // addr.sin_addr.s_addr = mobile_array[cur_mobile].mn.fa_addr.s_addr;
00704          //addr.sin_addr.s_addr = inet_addr("172.16.0.2");
00705         addr.sin_addr.s_addr=mobile_array[cur_mobile].config.ha_ip_addr.s_addr;
00706         addr.sin_port = htons(mobile_array[cur_mobile].config.udp_port);
00707         DEBUG(DEBUG_MESSAGES, "sending registration request to %s:%i, "
00708               "type=%i\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
00709               request_type);
00710 
00711         gettimeofday(&mobile_array[cur_mobile].mn.last_reg_send_time, NULL);
00712         DEBUG(DEBUG_TIMERS, "last_reg_send_time=%li.%06li (FA=%s)\n",
00713               mobile_array[cur_mobile].mn.last_reg_send_time.tv_sec,
00714               mobile_array[cur_mobile].mn.last_reg_send_time.tv_usec,
00715               inet_ntoa(addr.sin_addr));
00716 
00717         
00718 
00719 
00720         n = sendto(mobile_array[cur_mobile].mn.registration_socket, sendbuf, len, 0,
00721                    (struct sockaddr *) &addr, sizeof(addr));
00722         if (n == len) {
00723                 /* store id for reply */
00724                 mobile_array[cur_mobile].mn.registration_id[0] =
00725                         ntohl(((struct reg_req *)sendbuf)->id[0]);
00726                 mobile_array[cur_mobile].mn.registration_id[1] =
00727                         ntohl(((struct reg_req *)sendbuf)->id[1]);
00728                 /* set registration time */
00729                 gettimeofday(&timers[TIMER_REQUEST], NULL);
00730                 mobile_array[cur_mobile].mn.last_request_sent = timers[TIMER_REQUEST].tv_sec;
00731                 return 0;
00732         } else {
00733                 LOG2(LOG_ERR, "send_reg - sendto: %s\n", strerror(errno));
00734                 return -1;
00735         }
00736 }

Here is the call graph for this function:

int start_tunneling ( void   ) 

start_tunneling:

Create tunnel and set default route to tunnel and set route for FA.

Returns: 0 if successful.

Definition at line 260 of file mn_tunnel.c.

Referenced by connected(), and restart_tunneling().

00261 {
00262         int failed = 0;
00263 
00264         if (real_tunnel_up) {
00265                 DEBUG(DEBUG_INFO, "Start tunneling - tunnel is already up\n");
00266                 mn.tunnel_up = 1;
00267                 return 0;
00268         }
00269 
00270 #ifdef MN_ENABLE_TUNNELING
00271 
00272         DEBUG(DEBUG_INFO, "Start tunneling - FA addr %s\n",
00273               inet_ntoa(mn.fa_addr));
00274 
00275         if (mn.tunnel_mode == API_TUNNEL_FULL_HA) {
00276                 /* set a host route to the HA so that the default route
00277                  * replacing will not kill the route */
00278                 if (dyn_ip_route_to_host(config.ha_ip_addr) != 0) {
00279                         LOG2(LOG_ERR, "Could not set host route to the HA\n");
00280                 }
00281         }
00282 
00283         if (!config.enable_fa_decapsulation) {
00284                 if (make_tunnel(config.mn_home_ip_addr, mn.fa_addr) < 0)
00285                         return -1;
00286 
00287                 switch (config.mndecaps_route_handling) {
00288                 case MNDECAPS_ROUTE_DEFAULT:
00289                         /* set default route to the tunnel */
00290                         DEBUG(DEBUG_INFO, "Setting default route to %s\n",
00291                               tunnel_device);
00292                         if (dyn_ip_route_replace_default(
00293                                 tunnel_device, NULL,
00294                                 &config.mn_home_ip_addr) != 0) {
00295                                 LOG2(LOG_ERR,
00296                                      "Set default route to dev %s failed\n",
00297                                      tunnel_device);
00298                                 failed = 1;
00299                         }
00300                         break;
00301                 case MNDECAPS_ROUTE_HOME_NET:
00302                         /* only set home net route to the tunnel
00303                          * This entry will be automatically removed when the
00304                          * tunnel is set down. */
00305                         DEBUG(DEBUG_INFO, "Setting home net route to %s\n",
00306                               tunnel_device);
00307                         if (dyn_ip_route_replace_net(tunnel_device,
00308                                                      &config.home_net_addr,
00309                                                      config.home_net_addr_plen)
00310                             != 0) {
00311                                 LOG2(LOG_ERR,
00312                                      "Set home net route to dev %s failed\n",
00313                                      tunnel_device);
00314                                 failed = 1;
00315                         }
00316                         break;
00317                 case MNDECAPS_ROUTE_NONE:
00318                         DEBUG(DEBUG_INFO, "No route set to %s\n",
00319                               tunnel_device);
00320                         break;
00321                 }
00322 
00323                 if (failed) {
00324                         /* rollback */
00325                         if (dyn_ip_tunnel_del(tunnel_device) != 0) {
00326                                 DEBUG(DEBUG_INFO, "tunnel delete failed\n");
00327                         }
00328                         return -1;
00329                 }
00330         } else if (mn.current_adv != NULL) {
00331                 /* FA decapsulation and we have heard an advertisement:
00332                  * set default route to FA, and remove all routes to
00333                  * home network */
00334                 if (update_fa_decaps_routes(mn.current_adv->ifname,
00335                                             mn.current_adv->ifindex,
00336                                             mn.fa_addr,
00337                                             config.home_net_addr,
00338                                             config.home_net_addr_plen) < 0)
00339                         return -1;
00340         } else
00341                 LOG2(LOG_WARNING, "start_tunneling() - current_adv == NULL\n");
00342 
00343 #else
00344         DEBUG(DEBUG_INFO, "Start tunneling - tunneling disabled\n");
00345 #endif
00346         mn.tunnel_addr.s_addr = mn.fa_addr.s_addr;
00347         mn.tunnel_up = 1;
00348         real_tunnel_up = 1;
00349         return 0;
00350 }

int stop_tunneling ( void   ) 

stop_tunneling:

Close tunnel, reset routing.

Returns: 0 if successful.

Definition at line 406 of file mn_tunnel.c.

Referenced by close_for_home(), close_tunneling(), and disconnect().

00407 {
00408         int ret = 1;
00409         char dev[IFNAMSIZ], *home_dev = NULL;
00410 
00411 #ifdef MN_ENABLE_TUNNELING
00412         DEBUG(DEBUG_INFO, "Stop tunneling\n");
00413 
00414         if (mn.current_adv == NULL)
00415                 LOG2(LOG_WARNING, "stop_tunneling - current_adv == NULL\n");
00416 
00417         if (mn.tunnel_mode == API_TUNNEL_FULL_HA) {
00418                 /* remove the host route to the HA */
00419                 dev[0] = '\0';
00420                 if (dyn_ip_route_get(config.ha_ip_addr, dev, IFNAMSIZ) != 0 ||
00421                     dyn_ip_route_del(config.ha_ip_addr, dev) != 0) {
00422                         LOG2(LOG_ERR, "Could not remove host route to the "
00423                              "HA (dev=%s)\n", dev);
00424                 }
00425         }
00426 
00427         if (config.enable_fa_decapsulation)
00428                 home_dev = return_home_net_route();
00429 
00430         /* restore default route */
00431         DEBUG(DEBUG_INFO, "Restoring default route\n");
00432         if (dyn_ip_route_restore_default(home_dev) != 0 &&
00433             device_up(dyn_ip_get_saved_ifindex())) {
00434                 LOG2(LOG_ERR, "restoring default route failed\n");
00435                 ret = 0;
00436         }
00437 
00438         if (config.enable_fa_decapsulation) {
00439                 if (mn.current_adv)
00440                         remove_fa_host_routes(1);
00441         } else {
00442                 if (dyn_ip_tunnel_del(tunnel_device) != 0) {
00443                         LOG2(LOG_ERR, "tunnel delete failed\n");
00444                         ret = 0;
00445                 }
00446                 if (old_tunnel_expire != 0 &&
00447                     dyn_ip_tunnel_del(old_tunnel_device) != 0) {
00448                         LOG2(LOG_ERR, "tunnel delete failed for old tunnel\n");
00449                 }
00450                 old_tunnel_expire = 0;
00451         }
00452 #else
00453         DEBUG(DEBUG_INFO, "Stop tunneling - tunneling disabled\n");
00454 #endif
00455         mn.tunnel_up = 0;
00456         real_tunnel_up = 0;
00457         if (mn.current_adv != NULL) mn.current_adv->in_use = 0;
00458         return ret;
00459 }

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:


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