3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
40 * $Id: main.c,v 1.58 2005/01/29 23:42:39 kattemat Exp $
48 #include "interfaces.h"
49 #include "local_hna_set.h"
50 #include "scheduler.h"
52 #include "generate_msg.h"
53 #include "plugin_loader.h"
54 #include "socket_parser.h"
56 #include "link_layer.h"
60 #define close(x) closesocket(x)
61 int __stdcall SignalHandler(unsigned long signal);
62 void ListInterfaces(void);
63 void DisableIcmpRedirects(void);
70 * Local function prototypes
73 olsr_reconfigure(int);
79 set_default_values(void);
82 set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
84 static char **olsr_argv;
86 static char copyright_string[] = "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org) All rights reserved.";
93 main(int argc, char *argv[])
95 struct if_config_options *default_ifcnf;
96 char conf_file_name[FILENAME_MAX];
105 setbuf(stdout, NULL);
106 setbuf(stderr, NULL);
109 /* Initialize tick resolution */
110 system_tick_divider = 1000/sysconf(_SC_CLK_TCK);
112 /* Check if user is root */
113 if(getuid() || getgid())
115 fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
119 system_tick_divider = 1;
121 DisableIcmpRedirects();
123 if (WSAStartup(0x0202, &WsaData))
125 fprintf(stderr, "Could not initialize WinSock.\n");
126 olsr_exit(__func__, EXIT_FAILURE);
131 olsr_openlog("olsrd");
133 /* Set default values */
134 set_default_values();
136 /* Get initial timestep */
138 while (nowtm == NULL)
140 nowtm = gmtime((time_t *)&now.tv_sec);
143 /* The port to use for OLSR traffic */
144 olsr_udp_port = htons(OLSRPORT);
146 printf("\n *** %s ***\n Build date: %s\n http://www.olsr.org\n\n",
150 /* Using PID as random seed */
155 * Set configfile name and
156 * check if a configfile name was given as parameter
159 GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
161 len = strlen(conf_file_name);
163 if (conf_file_name[len - 1] != '\\')
164 conf_file_name[len++] = '\\';
166 strcpy(conf_file_name + len, "olsrd.conf");
168 strncpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, FILENAME_MAX);
171 if ((argc > 1) && (strcmp(argv[1], "-f") == 0))
178 fprintf(stderr, "You must provide a filename when using the -f switch!\n");
182 if (stat(argv[1], &statbuf) < 0)
184 fprintf(stderr, "Could not find specified config file %s!\n%s\n\n", argv[1], strerror(errno));
188 strncpy(conf_file_name, argv[1], FILENAME_MAX);
194 * set up configuration prior to processing commandline options
196 if((olsr_cnf = olsrd_parse_cnf(conf_file_name)) == NULL)
198 printf("Using default config values(no configfile)\n");
199 olsr_cnf = olsrd_get_default_cnf();
201 if((default_ifcnf = get_default_if_config()) == NULL)
203 fprintf(stderr, "No default ifconfig found!\n");
208 * Process olsrd options.
212 while (argc > 0 && **argv == '-')
218 if (strcmp(*argv, "-int") == 0)
228 if(strcmp(*argv, "-f") == 0)
230 fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
231 olsr_exit(__func__, EXIT_FAILURE);
237 if(strcmp(*argv, "-ipv6") == 0)
239 olsr_cnf->ip_version = AF_INET6;
247 if(strcmp(*argv, "-bcast") == 0)
254 fprintf(stderr, "You must provide a broadcastaddr when using the -bcast switch!\n");
255 olsr_exit(__func__, EXIT_FAILURE);
257 if (inet_aton(*argv, &in) == 0)
259 printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
262 memcpy(&default_ifcnf->ipv4_broadcast.v4, &in.s_addr, sizeof(olsr_u32_t));
267 * Enable additional debugging information to be logged.
269 if (strcmp(*argv, "-d") == 0)
272 sscanf(*argv,"%d", &olsr_cnf->debug_level);
279 * Interfaces to be used by olsrd.
281 if (strcmp(*argv, "-i") == 0)
284 if(!argc || (*argv[0] == '-'))
286 fprintf(stderr, "You must provide an interface label!\n");
287 olsr_exit(__func__, EXIT_FAILURE);
293 while((argc) && (**argv != '-'))
302 * Set the hello interval to be used by olsrd.
305 if (strcmp(*argv, "-hint") == 0)
308 sscanf(*argv,"%f", &default_ifcnf->hello_params.emission_interval);
309 default_ifcnf->hello_params.validity_time = default_ifcnf->hello_params.emission_interval * 3;
315 * Set the HNA interval to be used by olsrd.
318 if (strcmp(*argv, "-hnaint") == 0)
321 sscanf(*argv,"%f", &default_ifcnf->hna_params.emission_interval);
322 default_ifcnf->hna_params.validity_time = default_ifcnf->hna_params.emission_interval * 3;
328 * Set the MID interval to be used by olsrd.
331 if (strcmp(*argv, "-midint") == 0)
334 sscanf(*argv,"%f", &default_ifcnf->mid_params.emission_interval);
335 default_ifcnf->mid_params.validity_time = default_ifcnf->mid_params.emission_interval * 3;
341 * Set the tc interval to be used by olsrd.
344 if (strcmp(*argv, "-tcint") == 0)
347 sscanf(*argv,"%f", &default_ifcnf->tc_params.emission_interval);
348 default_ifcnf->tc_params.validity_time = default_ifcnf->tc_params.emission_interval * 3;
354 * Set the polling interval to be used by olsrd.
356 if (strcmp(*argv, "-T") == 0)
359 sscanf(*argv,"%f",&olsr_cnf->pollrate);
366 * Should we display the contents of packages beeing sent?
368 if (strcmp(*argv, "-dispin") == 0)
371 disp_pack_in = OLSR_TRUE;
376 * Should we display the contents of incoming packages?
378 if (strcmp(*argv, "-dispout") == 0)
381 disp_pack_out = OLSR_TRUE;
387 * Should we set up and send on a IPC socket for the front-end?
389 if (strcmp(*argv, "-ipc") == 0)
392 olsr_cnf->ipc_connections = 1;
393 olsr_cnf->open_ipc = OLSR_TRUE;
399 * Display link-layer info(experimental)
401 if (strcmp(*argv, "-llinfo") == 0)
409 * IPv6 multicast addr
411 if (strcmp(*argv, "-multi") == 0)
416 if(inet_pton(AF_INET6, *argv, &in6) < 0)
418 fprintf(stderr, "Failed converting IP address %s\n", *argv);
422 memcpy(&default_ifcnf->ipv6_multi_glbl, &in6, sizeof(struct in6_addr));
431 * Delete possible default GWs
433 if (strcmp(*argv, "-delgw") == 0)
442 olsr_exit(__func__, EXIT_FAILURE);
446 * Set configuration for command-line specified interfaces
448 set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
450 /* Sanity check configuration */
451 if(olsrd_sanity_check_cnf(olsr_cnf) < 0)
453 fprintf(stderr, "Bad configuration!\n");
454 olsr_exit(__func__, EXIT_FAILURE);
458 * Print configuration
460 olsrd_print_cnf(olsr_cnf);
463 *socket for icotl calls
465 if ((ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0)) < 0)
468 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
469 olsr_exit(__func__, 0);
472 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__
473 if ((rts = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
475 olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
476 olsr_exit(__func__, 0);
481 *enable ip forwarding on host
483 enable_ip_forwarding(olsr_cnf->ip_version);
485 /* Initialize parser */
488 /* Initialize message sequencnumber */
491 /* Initialize dynamic willingness calculation */
492 olsr_init_willingness();
495 *Set up willingness/APM
497 if(olsr_cnf->willingness_auto)
501 olsr_printf(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
503 olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
505 olsr_cnf->willingness_auto = 0;
506 olsr_cnf->willingness = WILL_DEFAULT;
510 olsr_cnf->willingness = olsr_calculate_willingness();
512 olsr_printf(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, will_int);
516 /* Set ipsize and minimum packetsize */
517 if(olsr_cnf->ip_version == AF_INET6)
519 olsr_printf(1, "Using IP version 6\n");
520 ipsize = sizeof(struct in6_addr);
522 minsize = (int)sizeof(olsr_u8_t) * 7; /* Minimum packetsize IPv6 */
526 olsr_printf(1, "Using IP version 4\n");
527 ipsize = sizeof(olsr_u32_t);
529 minsize = (int)sizeof(olsr_u8_t) * 4; /* Minimum packetsize IPv4 */
533 /* Initializing networkinterfaces */
537 if(olsr_cnf->allow_no_interfaces)
539 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");
544 fprintf(stderr, "No interfaces detected!\nBailing out!\n");
545 olsr_exit(__func__, EXIT_FAILURE);
549 /* Print heartbeat to stdout */
551 if(olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO))
552 olsr_register_scheduler_event(&generate_stdout_pulse, NULL, STDOUT_PULSE_INT, 0, NULL);
554 gettimeofday(&now, NULL);
557 /* Initialize the IPC socket */
559 if(olsr_cnf->open_ipc)
563 /* Initialize link-layer notifications */
565 init_link_layer_notification();
568 /* Initialisation of different tables to be used.*/
573 if (olsr_cnf->debug_level == 0)
575 printf("%s detattching from the current process...\n", SOFTWARE_VERSION);
587 olsr_printf(1, "Main address: %s\n\n", olsr_ip_to_string(&main_addr));
590 /* Start syslog entry */
591 olsr_syslog(OLSR_LOG_INFO, "%s successfully started", SOFTWARE_VERSION);
597 /* ctrl-C and friends */
599 SetConsoleCtrlHandler(SignalHandler, OLSR_TRUE);
601 signal(SIGHUP, olsr_reconfigure);
602 signal(SIGINT, olsr_shutdown);
603 signal(SIGTERM, olsr_shutdown);
606 /* Register socket poll event */
607 olsr_register_timeout_function(&poll_sockets);
609 /* Starting scheduler */
612 /* Stop the compiler from complaining */
613 strlen(copyright_string);
615 /* Like we're ever going to reach this ;-) */
623 * Reconfigure olsrd. Currently kind of a hack...
625 *@param signal the signal that triggered this callback
629 olsr_reconfigure(int signal)
635 printf("Restarting %s\n", olsr_argv[0]);
636 execv(olsr_argv[0], olsr_argv);
640 printf("RECONFIGURING!\n");
646 *Function called at shutdown. Signal handler
648 * @param signal the signal that triggered this call
652 SignalHandler(unsigned long signal)
655 olsr_shutdown(int signal)
658 struct interface *ifn;
660 olsr_printf(1, "Received signal %d - shutting down\n", signal);
662 olsr_delete_all_kernel_routes();
664 olsr_printf(1, "Closing sockets...\n");
666 /* front-end IPC socket */
667 if(olsr_cnf->open_ipc)
671 for (ifn = ifnet; ifn; ifn = ifn->int_next)
672 close(ifn->olsr_socket);
674 /* Closing plug-ins */
675 olsr_close_plugins();
677 /* Reset network settings */
678 restore_settings(olsr_cnf->ip_version);
683 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__
688 olsr_syslog(OLSR_LOG_INFO, "%s stopped", SOFTWARE_VERSION);
690 olsr_printf(1, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n", SOFTWARE_VERSION);
700 *Sets the default values of variables at startup
706 static struct tms tms_buf;
708 memset(&main_addr, 0, sizeof(union olsr_ip_addr));
709 memset(&null_addr6, 0, sizeof (union olsr_ip_addr));
711 exit_value = EXIT_SUCCESS;
712 /* If the application exits by signal it is concidered success,
713 * if not, exit_value is set by the function calling olsr_exit.
718 dup_hold_time = DUP_HOLD_TIME;
720 will_int = 10 * HELLO_INTERVAL; /* Willingness update interval */
723 del_gws = OLSR_FALSE;
725 /* Display packet content */
726 disp_pack_in = OLSR_FALSE;
727 disp_pack_out = OLSR_FALSE;
729 /* Initialize empty TC timer */
730 send_empty_tc = now_times = times(&tms_buf);
736 * Print the command line usage
742 fprintf(stderr, "An error occured somwhere between your keyboard and your chair!\n");
743 fprintf(stderr, "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n");
744 fprintf(stderr, " [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n");
745 fprintf(stderr, " [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n");
746 fprintf(stderr, " [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n");
747 fprintf(stderr, " [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n");
748 fprintf(stderr, " [-T <Polling Rate (secs)>]\n");
754 * Sets the provided configuration on all unconfigured
757 * @param ifs a linked list of interfaces to check and possible update
758 * @param cnf the default configuration to set on unconfigured interfaces
761 set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf)
769 ifs->cnf = olsr_malloc(sizeof(struct if_config_options), "Set default config");