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.
51 #include "scheduler.h"
53 #include "generate_msg.h"
54 #include "plugin_loader.h"
55 #include "socket_parser.h"
58 #include "build_msg.h"
61 #include "mpr_selector_set.h"
63 #include "olsr_niit.h"
65 #if LINUX_POLICY_ROUTING
66 #include <linux/types.h>
67 #include <linux/rtnetlink.h>
68 #include "kernel_routes.h"
74 #define close(x) closesocket(x)
75 int __stdcall SignalHandler(unsigned long signo) __attribute__ ((noreturn));
76 void ListInterfaces(void);
77 void DisableIcmpRedirects(void);
78 bool olsr_win32_end_request = false;
79 bool olsr_win32_end_flag = false;
81 static void olsr_shutdown(int) __attribute__ ((noreturn));
84 #if defined linux || __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
85 #define DEFAULT_LOCKFILE_PREFIX "/var/run/olsrd"
89 * Local function prototypes
91 void olsr_reconfigure(int) __attribute__ ((noreturn));
93 static void print_usage(void);
96 static const char* ipip_default_name = "olsr_tunnel";
99 static int set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
101 static int olsr_process_arguments(int, char *[], struct olsrd_config *,
102 struct if_config_options *);
105 static char **olsr_argv;
109 copyright_string[] __attribute__ ((unused)) =
110 "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
112 /* Data for OLSR locking */
114 static int lock_fd = 0;
116 static char lock_file_name[FILENAME_MAX];
119 * Creates a zero-length locking file and use fcntl to
120 * place an exclusive lock over it. The lock will be
121 * automatically erased when the olsrd process ends,
122 * so it will even work well with a SIGKILL.
124 * Additionally the lock can be killed by removing the
127 static void olsr_create_lock_file(void) {
129 HANDLE lck = CreateEvent(NULL, TRUE, FALSE, lock_file_name);
130 if (NULL == lck || ERROR_ALREADY_EXISTS == GetLastError()) {
133 "Error, cannot create OLSR lock '%s'.\n",
138 "Error, cannot aquire OLSR lock '%s'.\n"
139 "Another OLSR instance might be running.\n",
142 olsr_exit("", EXIT_FAILURE);
147 /* create file for lock */
148 lock_fd = open(lock_file_name, O_WRONLY | O_CREAT, S_IRWXU);
152 "Error, cannot create OLSR lock '%s'.\n",
154 olsr_exit("", EXIT_FAILURE);
157 /* create exclusive lock for the whole file */
158 lck.l_type = F_WRLCK;
159 lck.l_whence = SEEK_SET;
164 if (fcntl(lock_fd, F_SETLK, &lck) == -1) {
167 "Error, cannot aquire OLSR lock '%s'.\n"
168 "Another OLSR instance might be running.\n",
170 olsr_exit("", EXIT_FAILURE);
177 * loads a config file
178 * @return <0 if load failed, 0 otherwise
181 olsrmain_load_config(char *file) {
184 if (stat(file, &statbuf) < 0) {
185 fprintf(stderr, "Could not find specified config file %s!\n%s\n\n",
186 file, strerror(errno));
190 if (olsrd_parse_cnf(file) < 0) {
191 fprintf(stderr, "Error while reading config file %s!\n", file);
201 int main(int argc, char *argv[]) {
202 struct if_config_options *default_ifcnf;
203 char conf_file_name[FILENAME_MAX];
204 struct ipaddr_str buf;
205 bool loadedConfig = false;
212 /* paranoia checks */
213 assert(sizeof(uint8_t) == 1);
214 assert(sizeof(uint16_t) == 2);
215 assert(sizeof(uint32_t) == 4);
216 assert(sizeof(int8_t) == 1);
217 assert(sizeof(int16_t) == 2);
218 assert(sizeof(int32_t) == 4);
220 debug_handle = stdout;
224 setbuf(stdout, NULL);
225 setbuf(stderr, NULL);
228 /* Check if user is root */
230 fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
234 DisableIcmpRedirects();
236 if (WSAStartup(0x0202, &WsaData)) {
237 fprintf(stderr, "Could not initialize WinSock.\n");
238 olsr_exit(__func__, EXIT_FAILURE);
243 olsr_openlog("olsrd");
245 printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n",
246 olsrd_version, build_date, build_host);
248 /* Using PID as random seed */
251 /* Init widely used statics */
252 memset(&all_zero, 0, sizeof(union olsr_ip_addr));
255 * Set configfile name and
256 * check if a configfile name was given as parameter
260 GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
262 conf_file_name[0] = 0;
265 len = strlen(conf_file_name);
267 if (len == 0 || conf_file_name[len - 1] != '\\')
268 conf_file_name[len++] = '\\';
270 strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
272 strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
275 olsr_cnf = olsrd_get_default_cnf();
276 for (i=1; i < argc-1;) {
277 if (strcmp(argv[i], "-f") == 0) {
280 if (olsrmain_load_config(argv[i+1]) < 0) {
285 memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1));
295 * set up configuration prior to processing commandline options
297 if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) {
302 olsrd_free_cnf(olsr_cnf);
303 olsr_cnf = olsrd_get_default_cnf();
306 default_ifcnf = get_default_if_config();
307 if (default_ifcnf == NULL) {
308 fprintf(stderr, "No default ifconfig found!\n");
312 /* Initialize timers */
316 * Process olsrd options.
318 if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) {
320 olsr_exit(__func__, EXIT_FAILURE);
324 * Set configuration for command-line specified interfaces
326 set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
328 /* free the default ifcnf */
331 /* Sanity check configuration */
332 if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
333 fprintf(stderr, "Bad configuration!\n");
334 olsr_exit(__func__, EXIT_FAILURE);
338 * Establish file lock to prevent multiple instances
340 if (olsr_cnf->lock_file) {
341 strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name));
344 #ifdef DEFAULT_LOCKFILE_PREFIX
345 strscpy(lock_file_name, DEFAULT_LOCKFILE_PREFIX, sizeof(lock_file_name));
347 strscpy(lock_file_name, conf_file_name, sizeof(lock_file_name));
349 l = strlen(lock_file_name);
350 snprintf(&lock_file_name[l], sizeof(lock_file_name) - l, "-ipv%d.lock",
351 olsr_cnf->ip_version == AF_INET ? 4 : 6);
355 * Print configuration
357 if (olsr_cnf->debug_level > 1) {
358 olsrd_print_cnf(olsr_cnf);
361 /* Disable redirects globally */
362 disable_redirects_global(olsr_cnf->ip_version);
366 * socket for ioctl calls
368 olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
369 if (olsr_cnf->ioctl_s < 0) {
371 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
373 olsr_exit(__func__, 0);
375 #if LINUX_POLICY_ROUTING
376 olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
377 if (olsr_cnf->rtnl_s < 0) {
378 olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
379 olsr_exit(__func__, 0);
381 fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
385 * create routing socket
387 #if defined __FreeBSD__ || __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
388 olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
389 if (olsr_cnf->rts < 0) {
390 olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
391 olsr_exit(__func__, 0);
396 /* initialize niit if index */
397 if (olsr_cnf->use_niit) {
402 /* Init empty TC timer */
403 set_empty_tc_timer(GET_TIMESTAMP(0));
406 *enable ip forwarding on host
408 enable_ip_forwarding(olsr_cnf->ip_version);
410 /* Initialize parser */
413 /* Initialize route-exporter */
414 olsr_init_export_route();
416 /* Initialize message sequencnumber */
419 /* Initialize dynamic willingness calculation */
420 olsr_init_willingness();
423 *Set up willingness/APM
425 if (olsr_cnf->willingness_auto) {
426 if (apm_init() < 0) {
427 OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
429 olsr_syslog(OLSR_LOG_ERR,
430 "Could not read APM info - setting default willingness(%d)\n",
433 olsr_cnf->willingness_auto = 0;
434 olsr_cnf->willingness = WILL_DEFAULT;
436 olsr_cnf->willingness = olsr_calculate_willingness();
438 OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, olsr_cnf->will_int);
445 /* Initializing networkinterfaces */
447 if (olsr_cnf->allow_no_interfaces) {
450 "No interfaces detected! This might be intentional, but it also might mean that your configuration is fubar.\nI will continue after 5 seconds...\n");
451 olsr_startup_sleep(5);
453 fprintf(stderr, "No interfaces detected!\nBailing out!\n");
454 olsr_exit(__func__, EXIT_FAILURE);
458 olsr_do_startup_sleep();
460 /* Print heartbeat to stdout */
463 if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
464 olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC,
465 &generate_stdout_pulse, NULL, 0);
469 /* Initialize the IPC socket */
471 if (olsr_cnf->ipc_connections > 0) {
474 /* Initialisation of different tables to be used. */
479 if (olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) {
480 printf("%s detaching from the current process...\n", olsrd_version);
481 if (daemon(0, 0) < 0) {
482 printf("daemon(3) failed: %s\n", strerror(errno));
489 * Create locking file for olsrd, will be cleared after olsrd exits
491 olsr_create_lock_file();
496 OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
498 /*deativate spoof on all, this is neede ddue to an change in kernel 2.6.31
499 * all and device-specific settings are now combined differently
500 * new max(all,device) old: all && device
501 * !!?? does this change only affect rp_filter or other aswell (e.g. icmp_redirect)*/
502 deactivate_spoof("all", &olsr_cnf->ipip_base_if, AF_INET );
504 #if LINUX_POLICY_ROUTING
505 /*create smart-gateway-tunnel policy rules*/
506 //!!?? disable smartgateway if not ipv4?, or better: do not start olsr
507 if (olsr_cnf->smart_gw_active) {
508 int r = olsr_if_setip(TUNL_BASE, &olsr_cnf->main_addr, 0);
509 printf("set interface up returned %i",r);
510 //take up tunl0 device or disable smartgateway
511 olsr_cnf->ipip_base_orig_down = (r == -1 ?true:false);
512 printf("old ipip_base_orig_down state: %i",olsr_cnf->ipip_base_orig_down);
513 olsr_cnf->smart_gw_active = (r != 0); //!!?? kernel 2.4 may need true to function as gateway, does it harm to do anyway
514 /*create an interface structure for the tunlbase to store procnet settings*/
515 /*hmmm integrate it into the olsr_interface list to ensure spoof setting clenaup at end!???*/
516 olsr_cnf->ipip_base_if.if_index = if_nametoindex(TUNL_BASE);
518 deactivate_spoof(TUNL_BASE, &olsr_cnf->ipip_base_if, AF_INET );//ipip is an ipv4 tunnel
520 if (!olsr_cnf->smart_gw_active)
522 printf("disabled smart Gateway! (ipip tunnels not useable for olsrd on this host)");
525 struct olsr_if *cfg_if;
527 //need sanity checks for routintg tables
529 //question: if rttable_default unconfigured, determine one?
531 //same with smartTable (113)
533 //further checks: tabledefault and smartgateway >0 < 253
534 //check if all tables are unique
535 //if not use other values for unconfigured Tables? or stop startup?
537 //future improvement: verify if no rule points to default and smartgateway table, with un unknown realm?
538 //nice as we can use realms to give traffic info about gateway tunnel, and ...
540 //question: do we set an defaulttable now, which persists if smartgateway is turned off, due to problems (or an rmmodding user) later?
541 //its easier to stick to tables and also better,
542 //as users will always find the default route on same place.
544 //question: make priority of rules configureable (if configured for rttable this might means we shall create this rule (instead the 65535 dummy)
545 //question olsr did never create rules for a custom table (beside the dummy)
546 //should we start now doing so anyways? (beter not, use only new RTTableRule priority)
548 //as above ist neither finalized nor done in parser, we use hardcoded values
549 olsr_cnf->ipip_if_index = false;
550 olsr_cnf->ipip_name=ipip_default_name;
551 olsr_cnf->rttable_default=112;
552 olsr_cnf->rttable_smartgw=113;
553 if (olsr_cnf->rttable_default_rule==0) olsr_cnf->rttable_default_rule=65532;
554 if (olsr_cnf->rttable_smartgw_rule==0) olsr_cnf->rttable_smartgw_rule=olsr_cnf->rttable_default_rule+1;
555 if (olsr_cnf->rttable_backup_rule==0) olsr_cnf->rttable_backup_rule=olsr_cnf->rttable_smartgw_rule+1;
558 olsr_cnf->rttable_rule=65531;
560 printf("\nMain Table is %i prio %i", olsr_cnf->rttable, olsr_cnf->rttable_rule);
562 /*table with default routes for olsr interfaces*/
563 for (cfg_if = olsr_cnf->interfaces; cfg_if; cfg_if = cfg_if->next) {
564 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable_default,
565 olsr_cnf->rttable_default_rule, cfg_if->name, true);
567 /*table with route into tunnel (for all interfaces)*/
568 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable_smartgw,
569 olsr_cnf->rttable_smartgw_rule, NULL, true);
570 /*backup rule to default route table (if tunnel table gets empty)*/
571 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable_default,
572 olsr_cnf->rttable_backup_rule, NULL, true);
576 /* Create rule for RtTable to resolve route insertion problems*/
577 if ((olsr_cnf->rttable < 253) & (olsr_cnf->rttable > 0)) {
578 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable, (olsr_cnf->rttable_rule>0?olsr_cnf->rttable_rule:65535), NULL, true);
581 /* Create rtnetlink socket to listen on interface change events RTMGRP_LINK and RTMGRP_IPV4_ROUTE */
582 //todo listen on tunl0 events aswell
584 #if LINUX_RTNETLINK_LISTEN
585 rtnetlink_register_socket(RTMGRP_LINK);
586 #endif /*LINUX_RTNETLINK_LISTEN*/
591 /* trigger gateway selection */
592 if (olsr_cnf->smart_gw_active) {
593 olsr_trigger_inetgw_startup();
596 /* trigger niit static route setup */
597 if (olsr_cnf->use_niit) {
598 olsr_setup_niit_routes();
602 /* Start syslog entry */
603 olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
609 /* ctrl-C and friends */
612 SetConsoleCtrlHandler(SignalHandler, true);
615 signal(SIGHUP, olsr_reconfigure);
616 signal(SIGINT, olsr_shutdown);
617 signal(SIGQUIT, olsr_shutdown);
618 signal(SIGILL, olsr_shutdown);
619 signal(SIGABRT, olsr_shutdown);
620 // signal(SIGSEGV, olsr_shutdown);
621 signal(SIGTERM, olsr_shutdown);
622 signal(SIGPIPE, SIG_IGN);
625 link_changes = false;
627 /* Starting scheduler */
630 /* Like we're ever going to reach this ;-) */
635 * Reconfigure olsrd. Currently kind of a hack...
637 *@param signal the signal that triggered this callback
640 void olsr_reconfigure(int signo __attribute__ ((unused))) {
641 /* if we are started with -nofork, we do not weant to go into the
642 * background here. So we can simply stop on -HUP
644 olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
645 if (!olsr_cnf->no_fork) {
652 sigaddset(&sigs, SIGHUP);
653 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
654 for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
657 printf("Restarting %s\n", olsr_argv[0]);
658 olsr_syslog(OLSR_LOG_INFO, "Restarting %s\n", olsr_argv[0]);
659 execv(olsr_argv[0], olsr_argv);
660 olsr_syslog(OLSR_LOG_ERR, "execv(%s) fails: %s!\n", olsr_argv[0],
663 olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING!\n");
670 static void olsr_shutdown_messages(void) {
671 struct interface *ifn;
674 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
675 /* clean output buffer */
678 /* send 'I'm gone' messages */
679 if (olsr_cnf->lq_level > 0) {
680 olsr_output_lq_tc(ifn);
681 olsr_output_lq_hello(ifn);
692 *Function called at shutdown. Signal handler
694 * @param signal the signal that triggered this call
698 SignalHandler(unsigned long signo)
700 static void olsr_shutdown(int signo __attribute__ ((unused)))
703 struct interface *ifn;
706 OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
709 OLSR_PRINTF(1, "Waiting for the scheduler to stop.\n");
711 olsr_win32_end_request = TRUE;
713 while (!olsr_win32_end_flag)
716 OLSR_PRINTF(1, "Scheduler stopped.\n");
719 /* clear all links and send empty hellos/tcs */
720 olsr_reset_all_links();
722 /* deactivate fisheye and immediate TCs */
723 olsr_cnf->lq_fish = 0;
724 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
725 ifn->immediate_send_tc = false;
727 increase_local_ansn();
729 /* send first shutdown message burst */
730 olsr_shutdown_messages();
732 /* delete all routes */
733 olsr_delete_all_kernel_routes();
736 /* trigger gateway selection */
737 if (olsr_cnf->smart_gw_active) {
738 // TODO: cleanup smart gateway routes
741 /* trigger niit static route cleanup */
742 if (olsr_cnf->use_niit) {
743 olsr_cleanup_niit_routes();
747 /* send second shutdown message burst */
748 olsr_shutdown_messages();
750 /* now try to cleanup the rest of the mess */
751 olsr_delete_all_tc_entries();
753 olsr_delete_all_mid_entries();
755 olsr_destroy_parser();
757 OLSR_PRINTF(1, "Closing sockets...\n");
759 /* front-end IPC socket */
760 if (olsr_cnf->ipc_connections > 0) {
765 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
766 close(ifn->olsr_socket);
767 close(ifn->send_socket);
770 /* Closing plug-ins */
771 olsr_close_plugins();
773 /* Reset network settings */
774 restore_settings(olsr_cnf->ip_version);
777 close(olsr_cnf->ioctl_s);
779 #if LINUX_POLICY_ROUTING
781 /*delete smartgw tunnel if it index is known*/
782 if (olsr_cnf->ipip_if_index) olsr_del_tunl();
784 /*!!?? we should take down the tunl0 interface*/
786 /*we shall delete all rules with an configured prio*/
787 if (olsr_cnf->rttable_default_rule>0) {
788 struct olsr_if * cfg_if;
789 for (cfg_if = olsr_cnf->interfaces; cfg_if; cfg_if = cfg_if->next) {
790 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable_default, olsr_cnf->rttable_default_rule, cfg_if->name, false);
793 if (olsr_cnf->rttable_smartgw_rule>0)
794 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable_smartgw, olsr_cnf->rttable_smartgw_rule, NULL, false);
795 if (olsr_cnf->rttable_backup_rule>0)
796 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable_default, olsr_cnf->rttable_backup_rule, NULL, false);
799 if (olsr_cnf->ipip_base_orig_down) {
800 printf("\ntakig down tunl0 again");
801 olsr_if_set_state(TUNL_BASE, false);
804 /* RtTable backup rule */
805 if ((olsr_cnf->rttable < 253) & (olsr_cnf->rttable > 0)) {
806 olsr_netlink_rule(olsr_cnf->ip_version, olsr_cnf->rttable, (olsr_cnf->rttable_rule?olsr_cnf->rttable_rule:65535), NULL, false);
809 close(olsr_cnf->rtnl_s);
812 if (olsr_cnf->ipip_base_if.if_index) printf("\nresetting of tunl0 rp_filter not implemented");//!!?? no function extists to reset a single interface
815 /*!!?? we need to reset rp_filter of conf/all aswell, so we really need a new rp_filter reset function*/
817 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
819 close(olsr_cnf->rts);
822 /* Free cookies and memory pools attached. */
823 OLSR_PRINTF(0, "Free all memory...\n");
824 olsr_delete_all_cookies();
826 olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
828 OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n", olsrd_version);
830 exit_value = olsr_cnf->exit_value;
831 olsrd_free_cnf(olsr_cnf);
837 * Print the command line usage
839 static void print_usage(void) {
843 "An error occured somwhere between your keyboard and your chair!\n"
844 "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n"
845 " [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n"
846 " [-lql <LQ level>] [-lqw <LQ winsize>] [-lqnt <nat threshold>]\n"
847 " [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n"
848 " [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
849 " [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
850 " [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>]\n" " [-lql <LQ level>] [-lqa <LQ aging factor>]\n");
854 * Sets the provided configuration on all unconfigured
857 * @param ifs a linked list of interfaces to check and possible update
858 * @param cnf the default configuration to set on unconfigured interfaces
860 int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
864 if (ifs->cnf == NULL) {
865 ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
866 "Set default config");
875 #define NEXT_ARG do { argv++;argc--; } while (0)
876 #define CHECK_ARGC do { if(!argc) { \
877 if((argc - 1) == 1){ \
878 fprintf(stderr, "Error parsing command line options!\n"); \
881 fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
883 olsr_exit(__func__, EXIT_FAILURE); \
887 * Process command line arguments passed to olsrd
890 static int olsr_process_arguments(int argc, char *argv[],
891 struct olsrd_config *cnf, struct if_config_options *ifcnf) {
898 if (strcmp(*argv, "-int") == 0) {
907 if (strcmp(*argv, "-f") == 0) {
908 fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
909 olsr_exit(__func__, EXIT_FAILURE);
915 if (strcmp(*argv, "-ipv6") == 0) {
916 cnf->ip_version = AF_INET6;
923 if (strcmp(*argv, "-bcast") == 0) {
928 if (inet_aton(*argv, &in) == 0) {
929 printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
932 memcpy(&ifcnf->ipv4_multicast.v4, &in.s_addr, sizeof(ifcnf->ipv4_multicast.v4));
939 if (strcmp(*argv, "-lql") == 0) {
944 /* Sanity checking is done later */
945 sscanf(*argv, "%d", &tmp_lq_level);
946 olsr_cnf->lq_level = tmp_lq_level;
953 if (strcmp(*argv, "-lqa") == 0) {
958 sscanf(*argv, "%f", &tmp_lq_aging);
960 if (tmp_lq_aging < MIN_LQ_AGING || tmp_lq_aging > MAX_LQ_AGING) {
961 printf("LQ aging factor %f not allowed. Range [%f-%f]\n", tmp_lq_aging,
962 MIN_LQ_AGING, MAX_LQ_AGING);
963 olsr_exit(__func__, EXIT_FAILURE);
965 olsr_cnf->lq_aging = tmp_lq_aging;
972 if (strcmp(*argv, "-lqnt") == 0) {
973 float tmp_lq_nat_thresh;
977 sscanf(*argv, "%f", &tmp_lq_nat_thresh);
979 if (tmp_lq_nat_thresh < 0.1 || tmp_lq_nat_thresh > 1.0) {
980 printf("NAT threshold %f not allowed. Range [%f-%f]\n",
981 tmp_lq_nat_thresh, 0.1, 1.0);
982 olsr_exit(__func__, EXIT_FAILURE);
984 olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
989 * Enable additional debugging information to be logged.
991 if (strcmp(*argv, "-d") == 0) {
995 sscanf(*argv, "%d", &cnf->debug_level);
1000 * Interfaces to be used by olsrd.
1002 if (strcmp(*argv, "-i") == 0) {
1006 if (*argv[0] == '-') {
1007 fprintf(stderr, "You must provide an interface label!\n");
1008 olsr_exit(__func__, EXIT_FAILURE);
1010 printf("Queuing if %s\n", *argv);
1011 queue_if(*argv, false);
1013 while ((argc - 1) && (argv[1][0] != '-')) {
1015 printf("Queuing if %s\n", *argv);
1016 queue_if(*argv, false);
1022 * Set the hello interval to be used by olsrd.
1025 if (strcmp(*argv, "-hint") == 0) {
1028 sscanf(*argv, "%f", &ifcnf->hello_params.emission_interval);
1029 ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval
1035 * Set the HNA interval to be used by olsrd.
1038 if (strcmp(*argv, "-hnaint") == 0) {
1041 sscanf(*argv, "%f", &ifcnf->hna_params.emission_interval);
1042 ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
1047 * Set the MID interval to be used by olsrd.
1050 if (strcmp(*argv, "-midint") == 0) {
1053 sscanf(*argv, "%f", &ifcnf->mid_params.emission_interval);
1054 ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
1059 * Set the tc interval to be used by olsrd.
1062 if (strcmp(*argv, "-tcint") == 0) {
1065 sscanf(*argv, "%f", &ifcnf->tc_params.emission_interval);
1066 ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
1071 * Set the polling interval to be used by olsrd.
1073 if (strcmp(*argv, "-T") == 0) {
1076 sscanf(*argv, "%f", &cnf->pollrate);
1081 * Should we display the contents of packages beeing sent?
1083 if (strcmp(*argv, "-dispin") == 0) {
1084 parser_set_disp_pack_in(true);
1089 * Should we display the contents of incoming packages?
1091 if (strcmp(*argv, "-dispout") == 0) {
1092 net_set_disp_pack_out(true);
1097 * Should we set up and send on a IPC socket for the front-end?
1099 if (strcmp(*argv, "-ipc") == 0) {
1100 cnf->ipc_connections = 1;
1105 * IPv6 multicast addr
1107 if (strcmp(*argv, "-multi") == 0) {
1108 struct in6_addr in6;
1111 if (inet_pton(AF_INET6, *argv, &in6) <= 0) {
1112 fprintf(stderr, "Failed converting IP address %s\n", *argv);
1116 memcpy(&ifcnf->ipv6_multicast, &in6, sizeof(struct in6_addr));
1124 if (strcmp(*argv, "-hemu") == 0) {
1126 struct olsr_if *ifa;
1130 if (inet_pton(AF_INET, *argv, &in) <= 0) {
1131 fprintf(stderr, "Failed converting IP address %s\n", *argv);
1134 /* Add hemu interface */
1136 ifa = queue_if("hcif01", true);
1141 ifa->cnf = get_default_if_config();
1142 ifa->host_emul = true;
1143 memcpy(&ifa->hemu_ip, &in, sizeof(union olsr_ip_addr));
1144 cnf->host_emul = true;
1150 * Delete possible default GWs
1152 if (strcmp(*argv, "-delgw") == 0) {
1153 olsr_cnf->del_gws = true;
1157 if (strcmp(*argv, "-nofork") == 0) {
1158 cnf->no_fork = true;
1170 * indent-tabs-mode: nil