#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_entry * | get_fa_spi (int spi, struct in_addr addr) |
int | add_fa_spi (struct fa_spi_entry *spi, int replace_any_spi) |
void | remove_fa_spi (struct fa_spi_entry *spi) |
void | send_gratuitous_arp (struct in_addr route_addr, struct in_addr gratuitous_addr) |
send_gratuitous_arp: : : | |
int | 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 ASSERT assert |
#define CON_HA 0 |
#define DEBUG_AGENTADV '1' |
#define DEBUG_API 'A' |
#define DEBUG_HANDLERS '2' |
#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_PRIO_DEGRADE_DEGRADE 0.9 |
#define DEFAULT_PRIO_DEGRADE_FACTOR 2 |
#define DEFAULT_PRIO_DEGRADE_INITIAL 10 |
#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_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 |
#define MAX_REGISTRATION_TIME 32 |
#define MAXMSG 2048 |
#define MIN_ALLOWED_LIFETIME 1 |
#define MIN_REGISTRATION_DELAY 1000000 |
#define MIN_REGISTRATION_TIME 1 |
#define MN_DEFAULT_SYSLOG_FACILITY LOG_LOCAL0 |
#define MN_DEFAULT_TUNNEL_LIFETIME 400 |
#define MN_GLOBAL_CONF_FILE SYSCONFDIR "/" MN_CONF_FILE |
#define MN_PID_FILE PIDDIR "/dynmnd.pid" |
#define MNDECAPS_ROUTE_DEFAULT 0 |
#define MNDECAPS_ROUTE_HOME_NET 1 |
#define MNDECAPS_ROUTE_NONE 2 |
#define OLD_TUNNEL_EXTRA_TIME 3 |
#define POLICY | ( | bit | ) | POLICY_BIT(mn.policy_bits, bit) |
#define REG_CONNECT 1 |
#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 |
#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 SYSLOG_OPTIONS LOG_PID | LOG_CONS |
#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 |
#define TIMER_REQUEST 3 |
#define TIMER_REREG 4 |
#define TUNMODE_AUTO_REVERSE 1 |
#define TUNMODE_AUTO_TRIANGLE 2 |
#define TUNMODE_REVERSE 3 |
#define TUNMODE_TRIANGLE 4 |
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 |
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 };
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 | ) |
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 | ) |
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: