/** *Do initialization of various data needed for *network interface management. *This function also tries to set up the given interfaces. * *@return the number of interfaces configured */ int olsr_init_interfacedb(void) { struct olsr_if *tmp_if; /* Initial values */ ifnet = NULL; /* * Get some cookies for getting stats to ease troubleshooting. */ interface_poll_timer_cookie = olsr_alloc_cookie("Interface Polling", OLSR_COOKIE_TYPE_TIMER); hello_gen_timer_cookie = olsr_alloc_cookie("Hello Generation", OLSR_COOKIE_TYPE_TIMER); tc_gen_timer_cookie = olsr_alloc_cookie("TC Generation", OLSR_COOKIE_TYPE_TIMER); mid_gen_timer_cookie = olsr_alloc_cookie("MID Generation", OLSR_COOKIE_TYPE_TIMER); hna_gen_timer_cookie = olsr_alloc_cookie("HNA Generation", OLSR_COOKIE_TYPE_TIMER); OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n"); /* Run trough all interfaces immedeatly */ for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) { if (!tmp_if->host_emul) { if (!olsr_cnf->host_emul) /* XXX: TEMPORARY! */ chk_if_up(tmp_if, 1); } else { add_hemu_if(tmp_if); } } /* Kick a periodic timer for the network interface update function */ olsr_start_timer((unsigned int)olsr_cnf->nic_chgs_pollrate * MSEC_PER_SEC, 5, OLSR_TIMER_PERIODIC, &check_interface_updates, NULL, interface_poll_timer_cookie); return (ifnet == NULL) ? 0 : 1; }
/** * Init datastructures for maintaining timers. */ void olsr_init_timers(void) { int idx; OLSR_PRINTF(3, "Initializing scheduler.\n"); /* Grab initial timestamp */ if (gettimeofday(&first_tv, NULL)) { olsr_exit("OS clock is not working, have to shut down OLSR", 1); } last_tv = first_tv; now_times = olsr_times(); for (idx = 0; idx < TIMER_WHEEL_SLOTS; idx++) { list_head_init(&timer_wheel[idx]); } /* * Reset the last timer run. */ timer_last_run = now_times; /* Allocate a cookie for the block based memeory manager. */ timer_mem_cookie = olsr_alloc_cookie("timer_entry", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(timer_mem_cookie, sizeof(struct timer_entry)); }
/** * Initialize the routingtree and kernel change queues. */ void olsr_init_routing_table(void) { OLSR_PRINTF(5, "RIB: init routing tree\n"); /* the routing tree */ avl_init(&routingtree, avl_comp_prefix_default); routingtree_version = 0; /* * Get some cookies for memory stats and memory recycling. */ rt_mem_cookie = olsr_alloc_cookie("rt_entry", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(rt_mem_cookie, sizeof(struct rt_entry)); rtp_mem_cookie = olsr_alloc_cookie("rt_path", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(rtp_mem_cookie, sizeof(struct rt_path)); }
/** * Initialize the HNA set */ int olsr_init_hna_set(void) { int idx; for (idx = 0; idx < HASHSIZE; idx++) { hna_set[idx].next = &hna_set[idx]; hna_set[idx].prev = &hna_set[idx]; } hna_net_timer_cookie = olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER); hna_net_mem_cookie = olsr_alloc_cookie("hna_net", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(hna_net_mem_cookie, sizeof(struct hna_net)); hna_entry_mem_cookie = olsr_alloc_cookie("hna_entry", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(hna_entry_mem_cookie, sizeof(struct hna_entry)); return 1; }
/** * Initialize the topology set * */ void olsr_init_tc(void) { OLSR_PRINTF(5, "TC: init topo\n"); avl_init(&tc_tree, avl_comp_default); /* * Get some cookies for getting stats to ease troubleshooting. */ tc_edge_gc_timer_cookie = olsr_alloc_cookie("TC edge GC", OLSR_COOKIE_TYPE_TIMER); tc_validity_timer_cookie = olsr_alloc_cookie("TC validity", OLSR_COOKIE_TYPE_TIMER); tc_edge_mem_cookie = olsr_alloc_cookie("tc_edge_entry", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(tc_edge_mem_cookie, sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size); tc_mem_cookie = olsr_alloc_cookie("tc_entry", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(tc_mem_cookie, sizeof(struct tc_entry)); /* * Add a TC entry for ourselves. */ tc_myself = olsr_add_tc_entry(&olsr_cnf->main_addr); }
int olsr_os_init_iptunnel(const char * dev) { tunnel_cookie = olsr_alloc_cookie("iptunnel", OLSR_COOKIE_TYPE_MEMORY); olsr_cookie_set_memory_size(tunnel_cookie, sizeof(struct olsr_iptunnel_entry)); avl_init(&tunnel_tree, avl_comp_default); store_iptunnel_state = olsr_if_isup(dev); if (store_iptunnel_state) { return 0; } if (olsr_if_set_state(dev, true)) { return -1; } return olsr_os_ifip(if_nametoindex(dev), &olsr_cnf->main_addr, true); }
int main(int argc, char *argv[]) { struct if_config_options *default_ifcnf; char conf_file_name[FILENAME_MAX]; struct ipaddr_str buf; bool loadedConfig = false; int i; #ifdef LINUX_NETLINK_ROUTING struct interface *ifn; #endif #ifdef WIN32 WSADATA WsaData; size_t len; #endif /* paranoia checks */ assert(sizeof(uint8_t) == 1); assert(sizeof(uint16_t) == 2); assert(sizeof(uint32_t) == 4); assert(sizeof(int8_t) == 1); assert(sizeof(int16_t) == 2); assert(sizeof(int32_t) == 4); printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n", olsrd_version, build_date, build_host); if (argc == 2) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "/?") == 0) { print_usage(false); exit(0); } if (strcmp(argv[1], "-v") == 0) { exit(0); } } debug_handle = stdout; #ifndef WIN32 olsr_argv = argv; #endif setbuf(stdout, NULL); setbuf(stderr, NULL); #ifndef WIN32 /* Check if user is root */ if (geteuid()) { fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n"); exit(EXIT_FAILURE); } #else DisableIcmpRedirects(); if (WSAStartup(0x0202, &WsaData)) { fprintf(stderr, "Could not initialize WinSock.\n"); olsr_exit(__func__, EXIT_FAILURE); } #endif /* Open syslog */ olsr_openlog("olsrd"); /* Using PID as random seed */ srandom(getpid()); /* Init widely used statics */ memset(&all_zero, 0, sizeof(union olsr_ip_addr)); /* * Set configfile name and * check if a configfile name was given as parameter */ #ifdef WIN32 #ifndef WINCE GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11); #else conf_file_name[0] = 0; #endif len = strlen(conf_file_name); if (len == 0 || conf_file_name[len - 1] != '\\') conf_file_name[len++] = '\\'; strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len); #else strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name)); #endif olsr_cnf = olsrd_get_default_cnf(); for (i=1; i < argc-1;) { if (strcmp(argv[i], "-f") == 0) { loadedConfig = true; if (olsrmain_load_config(argv[i+1]) < 0) { exit(EXIT_FAILURE); } if (i+2 < argc) { memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1)); } argc -= 2; } else { i++; } } /* * set up configuration prior to processing commandline options */ if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) { loadedConfig = true; } if (!loadedConfig) { olsrd_free_cnf(olsr_cnf); olsr_cnf = olsrd_get_default_cnf(); } default_ifcnf = get_default_if_config(); if (default_ifcnf == NULL) { fprintf(stderr, "No default ifconfig found!\n"); exit(EXIT_FAILURE); } /* Initialize timers */ olsr_init_timers(); /* * Process olsrd options. */ if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) { print_usage(true); olsr_exit(__func__, EXIT_FAILURE); } /* * Set configuration for command-line specified interfaces */ set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf); /* free the default ifcnf */ free(default_ifcnf); /* Sanity check configuration */ if (olsrd_sanity_check_cnf(olsr_cnf) < 0) { fprintf(stderr, "Bad configuration!\n"); olsr_exit(__func__, EXIT_FAILURE); } /* * Establish file lock to prevent multiple instances */ if (olsr_cnf->lock_file) { strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name)); } else { size_t l; #ifdef DEFAULT_LOCKFILE_PREFIX strscpy(lock_file_name, DEFAULT_LOCKFILE_PREFIX, sizeof(lock_file_name)); #else strscpy(lock_file_name, conf_file_name, sizeof(lock_file_name)); #endif l = strlen(lock_file_name); snprintf(&lock_file_name[l], sizeof(lock_file_name) - l, "-ipv%d.lock", olsr_cnf->ip_version == AF_INET ? 4 : 6); } /* * Print configuration */ if (olsr_cnf->debug_level > 1) { olsrd_print_cnf(olsr_cnf); } def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER); /* * socket for ioctl calls */ olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0); if (olsr_cnf->ioctl_s < 0) { #ifndef WIN32 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m"); #endif olsr_exit(__func__, 0); } #ifdef LINUX_NETLINK_ROUTING olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); if (olsr_cnf->rtnl_s < 0) { olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m"); olsr_exit(__func__, 0); } fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK); if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) { olsr_syslog(OLSR_LOG_ERR, "rtmonitor socket: %m"); olsr_exit(__func__, 0); } #endif /* * create routing socket */ #if defined __FreeBSD__ || __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__ olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0); if (olsr_cnf->rts < 0) { olsr_syslog(OLSR_LOG_ERR, "routing socket: %m"); olsr_exit(__func__, 0); } #endif #ifdef LINUX_NETLINK_ROUTING /* initialize gateway system */ if (olsr_cnf->smart_gw_active) { if (olsr_init_gateways()) { olsr_exit("Cannot initialize gateway tunnels", 1); } } /* initialize niit if index */ if (olsr_cnf->use_niit) { olsr_init_niit(); } #endif /* Init empty TC timer */ set_empty_tc_timer(GET_TIMESTAMP(0)); /* enable ip forwarding on host */ /* Disable redirects globally */ #ifndef WIN32 net_os_set_global_ifoptions(); #endif /* Initialize parser */ olsr_init_parser(); /* Initialize route-exporter */ olsr_init_export_route(); /* Initialize message sequencnumber */ init_msg_seqno(); /* Initialize dynamic willingness calculation */ olsr_init_willingness(); /* *Set up willingness/APM */ if (olsr_cnf->willingness_auto) { if (apm_init() < 0) { OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT); olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT); olsr_cnf->willingness_auto = 0; olsr_cnf->willingness = WILL_DEFAULT; } else { olsr_cnf->willingness = olsr_calculate_willingness(); OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, olsr_cnf->will_int); } } /* Initialize net */ init_net(); /* Initializing networkinterfaces */ if (!olsr_init_interfacedb()) { if (olsr_cnf->allow_no_interfaces) { fprintf( stderr, "No interfaces detected! This might be intentional, but it also might mean that your configuration is fubar.\nI will continue after 5 seconds...\n"); olsr_startup_sleep(5); } else { fprintf(stderr, "No interfaces detected!\nBailing out!\n"); olsr_exit(__func__, EXIT_FAILURE); } } olsr_do_startup_sleep(); /* Print heartbeat to stdout */ #if !defined WINCE if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) { olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, 0); } #endif /* Initialize the IPC socket */ if (olsr_cnf->ipc_connections > 0) { ipc_init(); } /* Initialisation of different tables to be used. */ olsr_init_tables(); /* daemon mode */ #ifndef WIN32 if (olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) { printf("%s detaching from the current process...\n", olsrd_version); if (daemon(0, 0) < 0) { printf("daemon(3) failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } #endif /* * Create locking file for olsrd, will be cleared after olsrd exits */ for (i=5; i>=0; i--) { OLSR_PRINTF(3, "Trying to get olsrd lock...\n"); if (olsr_create_lock_file(i > 0) == 0) { /* lock sucessfully created */ break; } sleep (1); } /* Load plugins */ olsr_load_plugins(); OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr)); #ifdef LINUX_NETLINK_ROUTING /* create policy routing priorities if necessary */ if (DEF_RT_NONE != olsr_cnf->rt_table_pri) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true); } if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true); } if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true); } /* OLSR sockets */ if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) { for (ifn = ifnet; ifn; ifn = ifn->int_next) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true); } } /* trigger gateway selection */ if (olsr_cnf->smart_gw_active) { olsr_trigger_inetgw_startup(); } /* trigger niit static route setup */ if (olsr_cnf->use_niit) { olsr_setup_niit_routes(); } /* create lo:olsr interface */ if (olsr_cnf->use_src_ip_routes) { olsr_os_localhost_if(&olsr_cnf->main_addr, true); } #endif /* Start syslog entry */ olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version); /* *signal-handlers */ /* ctrl-C and friends */ #ifdef WIN32 #ifndef WINCE SetConsoleCtrlHandler(SignalHandler, true); #endif #else signal(SIGHUP, olsr_reconfigure); signal(SIGINT, olsr_shutdown); signal(SIGQUIT, olsr_shutdown); signal(SIGILL, olsr_shutdown); signal(SIGABRT, olsr_shutdown); // signal(SIGSEGV, olsr_shutdown); signal(SIGTERM, olsr_shutdown); signal(SIGPIPE, SIG_IGN); // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); #endif link_changes = false; /* Starting scheduler */ olsr_scheduler(); /* Like we're ever going to reach this ;-) */ return 1; } /* main */