2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
16 * * Neither the name of olsr.org, olsrd nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * Visit http://www.olsr.org for more information.
35 * If you find this software useful feel free to make a donation
36 * to the project. For more information see the website or contact
37 * the copyright holders.
41 #include <arpa/inet.h>
50 #include "builddata.h"
53 #include "scheduler.h"
55 #include "generate_msg.h"
56 #include "plugin_loader.h"
59 #include "build_msg.h"
62 #include "mpr_selector_set.h"
64 #include "olsr_niit.h"
67 #include <linux/types.h>
68 #include <linux/rtnetlink.h>
69 #include "kernel_routes.h"
71 #endif /* __linux__ */
76 #define olsr_shutdown(x) SignalHandler(x)
77 #define close(x) closesocket(x)
78 int __stdcall SignalHandler(unsigned long signo) __attribute__ ((noreturn));
79 void ListInterfaces(void);
80 void DisableIcmpRedirects(void);
81 bool olsr_win32_end_request = false;
82 bool olsr_win32_end_flag = false;
84 static void olsr_shutdown(int) __attribute__ ((noreturn));
87 #if defined __ANDROID__
88 #define DEFAULT_LOCKFILE_PREFIX "/data/local/olsrd"
89 #elif defined linux || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
90 #define DEFAULT_LOCKFILE_PREFIX "/var/run/olsrd"
92 #define DEFAULT_LOCKFILE_PREFIX "C:\\olsrd"
93 #else /* defined _WIN32 */
94 #define DEFAULT_LOCKFILE_PREFIX "olsrd"
95 #endif /* defined _WIN32 */
98 * Local function prototypes
100 void olsr_reconfigure(int signo) __attribute__ ((noreturn));
102 static void print_usage(bool error);
104 static int set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
106 static int olsr_process_arguments(int, char *[], struct olsrd_config *,
107 struct if_config_options *);
110 static char **olsr_argv;
114 copyright_string[] __attribute__ ((unused)) =
115 "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
117 /* Data for OLSR locking */
119 static int lock_fd = 0;
121 static char lock_file_name[FILENAME_MAX];
122 struct olsr_cookie_info *def_timer_ci = NULL;
125 * Creates a zero-length locking file and use fcntl to
126 * place an exclusive lock over it. The lock will be
127 * automatically erased when the olsrd process ends,
128 * so it will even work well with a SIGKILL.
130 * Additionally the lock can be killed by removing the
133 static int olsr_create_lock_file(bool noExitOnFail) {
138 lck = CreateFile(lock_file_name,
139 GENERIC_READ | GENERIC_WRITE,
140 FILE_SHARE_READ | FILE_SHARE_WRITE,
143 FILE_ATTRIBUTE_NORMAL |
144 FILE_FLAG_DELETE_ON_CLOSE,
146 CreateEvent(NULL, TRUE, FALSE, lock_file_name);
147 if (INVALID_HANDLE_VALUE == lck || ERROR_ALREADY_EXISTS == GetLastError()) {
153 "Error, cannot create OLSR lock '%s'.\n",
158 "Error, cannot aquire OLSR lock '%s'.\n"
159 "Another OLSR instance might be running.\n",
162 olsr_exit("", EXIT_FAILURE);
165 success = LockFile( lck, 0, 0, 0, 0);
173 "Error, cannot aquire OLSR lock '%s'.\n"
174 "Another OLSR instance might be running.\n",
176 olsr_exit("", EXIT_FAILURE);
182 /* create file for lock */
183 lock_fd = open(lock_file_name, O_WRONLY | O_CREAT, S_IRWXU);
189 "Error, cannot create OLSR lock '%s'.\n",
191 olsr_exit("", EXIT_FAILURE);
194 /* create exclusive lock for the whole file */
195 lck.l_type = F_WRLCK;
196 lck.l_whence = SEEK_SET;
201 if (fcntl(lock_fd, F_SETLK, &lck) == -1) {
207 "Error, cannot aquire OLSR lock '%s'.\n"
208 "Another OLSR instance might be running.\n",
210 olsr_exit("", EXIT_FAILURE);
217 * Write the current PID to the configured PID file (if one is configured)
219 static void writePidFile(void) {
220 if (olsr_cnf->pidfile) {
221 char buf[PATH_MAX + 256];
223 /* create / open the PID file */
225 mode_t mode = S_IRUSR | S_IWUSR;
227 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
229 int fd = open(olsr_cnf->pidfile, O_CREAT | O_WRONLY, mode);
231 snprintf(buf, sizeof(buf), "Could not open PID file %s", olsr_cnf->pidfile);
238 pid_t pid = getpid();
239 int chars = snprintf(buf, sizeof(buf), "%d", (int)pid);
240 ssize_t chars_written = write(fd, buf, chars);
241 if (chars_written != chars) {
243 snprintf(buf, sizeof(buf), "Could not write the PID %d to the PID file %s", (int)pid, olsr_cnf->pidfile);
245 if (remove(olsr_cnf->pidfile) < 0) {
246 snprintf(buf, sizeof(buf), "Could not remove the PID file %s", olsr_cnf->pidfile);
254 snprintf(buf, sizeof(buf), "Could not close PID file %s", olsr_cnf->pidfile);
256 if (remove(olsr_cnf->pidfile) < 0) {
257 snprintf(buf, sizeof(buf), "Could not remove the PID file %s", olsr_cnf->pidfile);
266 * loads a config file
267 * @return <0 if load failed, 0 otherwise
270 olsrmain_load_config(char *file) {
273 if (stat(file, &statbuf) < 0) {
274 fprintf(stderr, "Could not find specified config file %s!\n%s\n\n",
275 file, strerror(errno));
279 if (olsrd_parse_cnf(file) < 0) {
280 fprintf(stderr, "Error while reading config file %s!\n", file);
286 static void initRandom(void) {
287 unsigned int seed = (unsigned int)time(NULL);
292 randomFile = open("/dev/urandom", O_RDONLY);
293 if (randomFile == -1) {
294 randomFile = open("/dev/random", O_RDONLY);
297 if (randomFile != -1) {
298 if (read(randomFile, &seed, sizeof(seed)) != sizeof(seed)) {
299 ; /* to fix an 'unused result' compiler warning */
312 int main(int argc, char *argv[]) {
313 struct if_config_options *default_ifcnf;
314 char conf_file_name[FILENAME_MAX];
315 struct ipaddr_str buf;
316 bool loadedConfig = false;
320 struct interface_olsr *ifn;
321 #endif /* __linux__ */
326 #endif /* __linux__ */
328 /* paranoia checks */
329 assert(sizeof(uint8_t) == 1);
330 assert(sizeof(uint16_t) == 2);
331 assert(sizeof(uint32_t) == 4);
332 assert(sizeof(int8_t) == 1);
333 assert(sizeof(int16_t) == 2);
334 assert(sizeof(int32_t) == 4);
336 printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n",
337 olsrd_version, build_date, build_host);
340 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "/?") == 0)) {
344 if (strcmp(argv[1], "-v") == 0) {
349 debug_handle = stdout;
353 setbuf(stdout, NULL);
354 setbuf(stderr, NULL);
357 /* Check if user is root */
359 fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
363 DisableIcmpRedirects();
365 if (WSAStartup(0x0202, &WsaData)) {
366 fprintf(stderr, "Could not initialize WinSock.\n");
367 olsr_exit(__func__, EXIT_FAILURE);
372 olsr_openlog("olsrd");
374 /* setup random seed */
377 /* Init widely used statics */
378 memset(&all_zero, 0, sizeof(union olsr_ip_addr));
381 * Set configfile name and
382 * check if a configfile name was given as parameter
386 GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
388 conf_file_name[0] = 0;
391 len = strlen(conf_file_name);
393 if (len == 0 || conf_file_name[len - 1] != '\\')
394 conf_file_name[len++] = '\\';
396 strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
398 strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
401 olsr_cnf = olsrd_get_default_cnf();
402 for (i=1; i < argc-1;) {
403 if (strcmp(argv[i], "-f") == 0) {
406 if (olsrmain_load_config(argv[i+1]) < 0) {
411 memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1));
421 * set up configuration prior to processing commandline options
423 if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) {
428 olsrd_free_cnf(olsr_cnf);
429 olsr_cnf = olsrd_get_default_cnf();
432 default_ifcnf = get_default_if_config();
433 if (default_ifcnf == NULL) {
434 fprintf(stderr, "No default ifconfig found!\n");
438 /* Initialize timers */
442 * Process olsrd options.
444 if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) {
446 olsr_exit(__func__, EXIT_FAILURE);
450 * Set configuration for command-line specified interfaces
452 set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
454 /* free the default ifcnf */
457 /* Sanity check configuration */
458 if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
459 fprintf(stderr, "Bad configuration!\n");
460 olsr_exit(__func__, EXIT_FAILURE);
464 * Establish file lock to prevent multiple instances
466 if (olsr_cnf->lock_file) {
467 strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name));
470 #ifdef DEFAULT_LOCKFILE_PREFIX
471 strscpy(lock_file_name, DEFAULT_LOCKFILE_PREFIX, sizeof(lock_file_name));
472 #else /* DEFAULT_LOCKFILE_PREFIX */
473 strscpy(lock_file_name, conf_file_name, sizeof(lock_file_name));
474 #endif /* DEFAULT_LOCKFILE_PREFIX */
475 l = strlen(lock_file_name);
476 snprintf(&lock_file_name[l], sizeof(lock_file_name) - l, "-ipv%d.lock",
477 olsr_cnf->ip_version == AF_INET ? 4 : 6);
481 * Print configuration
483 if (olsr_cnf->debug_level > 1) {
484 olsrd_print_cnf(olsr_cnf);
487 def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);
490 * socket for ioctl calls
492 olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
493 if (olsr_cnf->ioctl_s < 0) {
495 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
497 olsr_exit(__func__, 0);
500 olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
501 if (olsr_cnf->rtnl_s < 0) {
502 olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
503 olsr_exit(__func__, 0);
506 if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
507 olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
510 if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
511 olsr_syslog(OLSR_LOG_ERR, "rtmonitor socket: %m");
512 olsr_exit(__func__, 0);
514 #endif /* __linux__ */
517 * create routing socket
519 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
520 olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
521 if (olsr_cnf->rts < 0) {
522 olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
523 olsr_exit(__func__, 0);
525 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
528 /* initialize gateway system */
529 if (olsr_cnf->smart_gw_active) {
530 if (olsr_init_gateways()) {
531 olsr_exit("Cannot initialize gateway tunnels", 1);
535 /* initialize niit if index */
536 if (olsr_cnf->use_niit) {
539 #endif /* __linux__ */
541 /* Init empty TC timer */
542 set_empty_tc_timer(GET_TIMESTAMP(0));
544 /* enable ip forwarding on host */
545 /* Disable redirects globally (not for WIN32) */
546 net_os_set_global_ifoptions();
548 /* Initialize parser */
551 /* Initialize route-exporter */
552 olsr_init_export_route();
554 /* Initialize message sequencnumber */
557 /* Initialize dynamic willingness calculation */
558 olsr_init_willingness();
561 *Set up willingness/APM
563 if (olsr_cnf->willingness_auto) {
564 if (apm_init() < 0) {
565 OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
567 olsr_syslog(OLSR_LOG_ERR,
568 "Could not read APM info - setting default willingness(%d)\n",
571 olsr_cnf->willingness_auto = 0;
572 olsr_cnf->willingness = WILL_DEFAULT;
574 olsr_cnf->willingness = olsr_calculate_willingness();
576 OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double)olsr_cnf->will_int);
583 /* Initializing networkinterfaces */
584 if (!olsr_init_interfacedb()) {
585 if (olsr_cnf->allow_no_interfaces) {
588 "No interfaces detected! This might be intentional, but it also might mean that your configuration is fubar.\nI will continue after 5 seconds...\n");
589 olsr_startup_sleep(5);
591 fprintf(stderr, "No interfaces detected!\nBailing out!\n");
592 olsr_exit(__func__, EXIT_FAILURE);
597 /* startup gateway system */
598 if (olsr_cnf->smart_gw_active) {
599 if (olsr_startup_gateways()) {
600 olsr_exit("Cannot startup gateway tunnels", 1);
603 #endif /* __linux__ */
605 olsr_do_startup_sleep();
607 /* Print heartbeat to stdout */
610 if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
611 olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC,
612 &generate_stdout_pulse, NULL, 0);
614 #endif /* !defined WINCE */
616 /* Initialize the IPC socket */
618 if (olsr_cnf->ipc_connections > 0) {
620 olsr_exit("ipc_init failure", 1);
623 /* Initialisation of different tables to be used. */
628 if (olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) {
629 printf("%s detaching from the current process...\n", olsrd_version);
630 if (daemon(0, 0) < 0) {
631 printf("daemon(3) failed: %s\n", strerror(errno));
640 * Create locking file for olsrd, will be cleared after olsrd exits
642 for (i=5; i>=0; i--) {
643 OLSR_PRINTF(3, "Trying to get olsrd lock...\n");
644 if (!olsr_cnf->host_emul && olsr_create_lock_file(i > 0) == 0) {
645 /* lock sucessfully created */
654 OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
657 /* create policy routing rules with priorities if necessary */
658 if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
659 olsr_os_policy_rule(olsr_cnf->ip_version,
660 olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true);
662 if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
663 olsr_os_policy_rule(olsr_cnf->ip_version,
664 olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true);
666 if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
667 olsr_os_policy_rule(olsr_cnf->ip_version,
668 olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true);
671 /* rule to default table on all olsrd interfaces */
672 if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
673 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
674 olsr_os_policy_rule(olsr_cnf->ip_version,
675 olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true);
679 /* trigger gateway selection */
680 if (olsr_cnf->smart_gw_active) {
681 olsr_trigger_inetgw_startup();
684 /* trigger niit static route setup */
685 if (olsr_cnf->use_niit) {
686 olsr_setup_niit_routes();
689 /* create lo:olsr interface */
690 if (olsr_cnf->use_src_ip_routes) {
691 olsr_os_localhost_if(&olsr_cnf->main_addr, true);
693 #endif /* __linux__ */
695 /* Start syslog entry */
696 olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
702 /* ctrl-C and friends */
705 SetConsoleCtrlHandler(SignalHandler, true);
708 signal(SIGHUP, olsr_reconfigure);
709 signal(SIGINT, olsr_shutdown);
710 signal(SIGQUIT, olsr_shutdown);
711 signal(SIGILL, olsr_shutdown);
712 signal(SIGABRT, olsr_shutdown);
713 // signal(SIGSEGV, olsr_shutdown);
714 signal(SIGTERM, olsr_shutdown);
715 signal(SIGPIPE, SIG_IGN);
716 // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins
717 signal(SIGUSR1, SIG_IGN);
718 signal(SIGUSR2, SIG_IGN);
721 link_changes = false;
723 /* Starting scheduler */
726 /* Like we're ever going to reach this ;-) */
732 * Reconfigure olsrd. Currently kind of a hack...
734 *@param signo the signal that triggered this callback
736 void olsr_reconfigure(int signo __attribute__ ((unused))) {
740 /* if we are started with -nofork, we do not want to go into the
741 * background here. So we can simply stop on -HUP
743 olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
744 if (!olsr_cnf->no_fork) {
751 sigaddset(&sigs, SIGHUP);
752 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
753 for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
756 printf("Restarting %s\n", olsr_argv[0]);
757 olsr_syslog(OLSR_LOG_INFO, "Restarting %s\n", olsr_argv[0]);
758 execv(olsr_argv[0], olsr_argv);
759 olsr_syslog(OLSR_LOG_ERR, "execv(%s) fails: %s!\n", olsr_argv[0],
762 olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING!\n");
772 static void olsr_shutdown_messages(void) {
773 struct interface_olsr *ifn;
776 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
777 /* clean output buffer */
780 /* send 'I'm gone' messages */
781 if (olsr_cnf->lq_level > 0) {
782 olsr_output_lq_tc(ifn);
783 olsr_output_lq_hello(ifn);
794 *Function called at shutdown. Signal handler
796 * @param signo the signal that triggered this call
800 SignalHandler(unsigned long signo)
802 static void olsr_shutdown(int signo __attribute__ ((unused)))
808 struct interface_olsr *ifn;
811 OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
814 OLSR_PRINTF(1, "Waiting for the scheduler to stop.\n");
816 olsr_win32_end_request = TRUE;
818 while (!olsr_win32_end_flag)
821 OLSR_PRINTF(1, "Scheduler stopped.\n");
824 /* clear all links and send empty hellos/tcs */
825 olsr_reset_all_links();
827 /* deactivate fisheye and immediate TCs */
828 olsr_cnf->lq_fish = 0;
829 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
830 ifn->immediate_send_tc = false;
832 increase_local_ansn();
834 /* send first shutdown message burst */
835 olsr_shutdown_messages();
837 /* delete all routes */
838 olsr_delete_all_kernel_routes();
840 /* send second shutdown message burst */
841 olsr_shutdown_messages();
843 /* now try to cleanup the rest of the mess */
844 olsr_delete_all_tc_entries();
846 olsr_delete_all_mid_entries();
849 /* trigger gateway selection */
850 if (olsr_cnf->smart_gw_active) {
851 olsr_shutdown_gateways();
852 olsr_cleanup_gateways();
855 /* trigger niit static route cleanup */
856 if (olsr_cnf->use_niit) {
857 olsr_cleanup_niit_routes();
860 /* cleanup lo:olsr interface */
861 if (olsr_cnf->use_src_ip_routes) {
862 olsr_os_localhost_if(&olsr_cnf->main_addr, false);
864 #endif /* __linux__ */
866 olsr_destroy_parser();
868 OLSR_PRINTF(1, "Closing sockets...\n");
870 /* front-end IPC socket */
871 if (olsr_cnf->ipc_connections > 0) {
876 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
877 close(ifn->olsr_socket);
878 close(ifn->send_socket);
881 if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
882 olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default,
883 olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, false);
885 #endif /* __linux__ */
888 /* Closing plug-ins */
889 olsr_close_plugins();
891 /* Reset network settings */
892 net_os_restore_ifoptions();
895 close(olsr_cnf->ioctl_s);
898 if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
899 olsr_os_policy_rule(olsr_cnf->ip_version,
900 olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, false);
902 if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
903 olsr_os_policy_rule(olsr_cnf->ip_version,
904 olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, false);
906 if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
907 olsr_os_policy_rule(olsr_cnf->ip_version,
908 olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, false);
910 close(olsr_cnf->rtnl_s);
911 close (olsr_cnf->rt_monitor_socket);
912 #endif /* __linux__ */
914 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
916 close(olsr_cnf->rts);
917 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
919 /* Free cookies and memory pools attached. */
920 OLSR_PRINTF(0, "Free all memory...\n");
921 olsr_delete_all_cookies();
923 olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
925 OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n", olsrd_version);
927 exit_value = olsr_cnf->exit_value;
928 olsrd_free_cnf(olsr_cnf);
937 * Print the command line usage
939 static void print_usage(bool error) {
943 "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n"
944 " [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n"
945 " [-lql <LQ level>] [-lqw <LQ winsize>] [-lqnt <nat threshold>]\n"
946 " [-bcast <broadcastaddr>] [-ipc] [-delgw]\n"
947 " [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
948 " [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
949 " [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>]\n"
950 " [-lql <LQ level>] [-lqa <LQ aging factor>]\n"
951 " [-pidfile <pid file>]\n",
952 error ? "Error in command line parameters!\n" : "");
956 * Sets the provided configuration on all unconfigured
959 * @param ifs a linked list of interfaces to check and possible update
960 * @param cnf the default configuration to set on unconfigured interfaces
962 int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
966 if (ifs->cnf == NULL) {
967 ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
968 "Set default config");
977 #define NEXT_ARG do { argv++;argc--; } while (0)
978 #define CHECK_ARGC do { if(!argc) { \
980 fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
981 olsr_exit(__func__, EXIT_FAILURE); \
985 * Process command line arguments passed to olsrd
988 static int olsr_process_arguments(int argc, char *argv[],
989 struct olsrd_config *cnf, struct if_config_options *ifcnf) {
996 if (strcmp(*argv, "-int") == 0) {
1005 if (strcmp(*argv, "-f") == 0) {
1006 fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
1007 olsr_exit(__func__, EXIT_FAILURE);
1013 if (strcmp(*argv, "-ipv6") == 0) {
1014 cnf->ip_version = AF_INET6;
1021 if (strcmp(*argv, "-bcast") == 0) {
1026 if (inet_pton(AF_INET, *argv, &in) == 0) {
1027 printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
1030 memcpy(&ifcnf->ipv4_multicast.v4, &in.s_addr, sizeof(ifcnf->ipv4_multicast.v4));
1037 if (strcmp(*argv, "-lql") == 0) {
1042 /* Sanity checking is done later */
1043 sscanf(*argv, "%d", &tmp_lq_level);
1044 olsr_cnf->lq_level = tmp_lq_level;
1051 if (strcmp(*argv, "-lqa") == 0) {
1056 sscanf(*argv, "%f", &tmp_lq_aging);
1058 if (tmp_lq_aging < (float)MIN_LQ_AGING || tmp_lq_aging > (float)MAX_LQ_AGING) {
1059 printf("LQ aging factor %f not allowed. Range [%f-%f]\n", (double)tmp_lq_aging,
1060 (double)MIN_LQ_AGING, (double)MAX_LQ_AGING);
1061 olsr_exit(__func__, EXIT_FAILURE);
1063 olsr_cnf->lq_aging = tmp_lq_aging;
1070 if (strcmp(*argv, "-lqnt") == 0) {
1071 float tmp_lq_nat_thresh;
1075 sscanf(*argv, "%f", &tmp_lq_nat_thresh);
1077 if (tmp_lq_nat_thresh < 0.1f || tmp_lq_nat_thresh > 1.0f) {
1078 printf("NAT threshold %f not allowed. Range [%f-%f]\n",
1079 (double)tmp_lq_nat_thresh, (double)0.1, (double)1.0);
1080 olsr_exit(__func__, EXIT_FAILURE);
1082 olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
1087 * Enable additional debugging information to be logged.
1089 if (strcmp(*argv, "-d") == 0) {
1093 sscanf(*argv, "%d", &cnf->debug_level);
1098 * Interfaces to be used by olsrd.
1100 if (strcmp(*argv, "-i") == 0) {
1104 if (*argv[0] == '-') {
1105 fprintf(stderr, "You must provide an interface label!\n");
1106 olsr_exit(__func__, EXIT_FAILURE);
1108 printf("Queuing if %s\n", *argv);
1109 olsr_create_olsrif(*argv, false);
1111 while ((argc - 1) && (argv[1][0] != '-')) {
1113 printf("Queuing if %s\n", *argv);
1114 olsr_create_olsrif(*argv, false);
1120 * Set the hello interval to be used by olsrd.
1123 if (strcmp(*argv, "-hint") == 0) {
1126 sscanf(*argv, "%f", &ifcnf->hello_params.emission_interval);
1127 ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval
1133 * Set the HNA interval to be used by olsrd.
1136 if (strcmp(*argv, "-hnaint") == 0) {
1139 sscanf(*argv, "%f", &ifcnf->hna_params.emission_interval);
1140 ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
1145 * Set the MID interval to be used by olsrd.
1148 if (strcmp(*argv, "-midint") == 0) {
1151 sscanf(*argv, "%f", &ifcnf->mid_params.emission_interval);
1152 ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
1157 * Set the tc interval to be used by olsrd.
1160 if (strcmp(*argv, "-tcint") == 0) {
1163 sscanf(*argv, "%f", &ifcnf->tc_params.emission_interval);
1164 ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
1169 * Set the polling interval to be used by olsrd.
1171 if (strcmp(*argv, "-T") == 0) {
1174 sscanf(*argv, "%f", &cnf->pollrate);
1179 * Should we set up and send on a IPC socket for the front-end?
1181 if (strcmp(*argv, "-ipc") == 0) {
1182 cnf->ipc_connections = 1;
1187 * IPv6 multicast addr
1189 if (strcmp(*argv, "-multi") == 0) {
1190 struct in6_addr in6;
1193 if (inet_pton(AF_INET6, *argv, &in6) <= 0) {
1194 fprintf(stderr, "Failed converting IP address %s\n", *argv);
1198 memcpy(&ifcnf->ipv6_multicast, &in6, sizeof(struct in6_addr));
1206 if (strcmp(*argv, "-hemu") == 0) {
1208 struct olsr_if *ifa;
1212 if (inet_pton(AF_INET, *argv, &in) <= 0) {
1213 fprintf(stderr, "Failed converting IP address %s\n", *argv);
1216 /* Add hemu interface */
1218 ifa = olsr_create_olsrif("hcif01", true);
1223 ifa->cnf = get_default_if_config();
1224 ifa->host_emul = true;
1225 memset(&ifa->hemu_ip, 0, sizeof(ifa->hemu_ip));
1226 memcpy(&ifa->hemu_ip, &in, sizeof(in));
1227 cnf->host_emul = true;
1233 * Delete possible default GWs
1235 if (strcmp(*argv, "-delgw") == 0) {
1236 olsr_cnf->del_gws = true;
1240 if (strcmp(*argv, "-nofork") == 0) {
1241 cnf->no_fork = true;
1245 if (strcmp(*argv, "-pidfile") == 0) {
1249 cnf->pidfile = *argv;
1261 * indent-tabs-mode: nil