2 * OLSR ad-hoc routing table management protocol
3 * Copyright (C) 2004 Andreas Tønnesen (andreto@ifi.uio.no)
5 * This file is part of the olsr.org OLSR daemon.
7 * olsr.org is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * olsr.org is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with olsr.org; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * $Id: main.c,v 1.43 2004/11/20 23:27:24 kattemat Exp $
31 #include "interfaces.h"
32 #include "local_hna_set.h"
33 #include "scheduler.h"
35 #include "generate_msg.h"
36 #include "plugin_loader.h"
37 #include "socket_parser.h"
39 #include "link_layer.h"
43 #define close(x) closesocket(x)
44 int __stdcall SignalHandler(unsigned long signal);
45 void ListInterfaces(void);
46 void DisableIcmpRedirects(void);
53 * Local function prototypes
56 olsr_reconfigure(int);
62 set_default_values(void);
65 set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
67 static char **olsr_argv;
74 main(int argc, char *argv[])
76 /* For address convertions */
80 struct if_config_options *default_ifcnf;
83 char conf_file_name[FILENAME_MAX];
95 /* Initialize socket list */
96 olsr_socket_entries = NULL;
99 /* Check if user is root */
100 if(getuid() || getgid())
102 fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
106 DisableIcmpRedirects();
108 if (WSAStartup(0x0202, &WsaData))
110 fprintf(stderr, "Could not initialize WinSock.\n");
111 olsr_exit(__func__, EXIT_FAILURE);
116 olsr_openlog("olsrd");
118 /* Set default values */
119 set_default_values();
121 /* Initialize network functions */
124 /* Get initial timestep */
126 while (nowtm == NULL)
128 nowtm = gmtime((time_t *)&now.tv_sec);
131 /* The port to use for OLSR traffic */
132 olsr_udp_port = htons(OLSRPORT);
134 printf("\n *** %s ***\n Build date: %s\n http://www.olsr.org\n\n",
138 /* Using PID as random seed */
143 * Set configfile name and
144 * check if a configfile name was given as parameter
147 GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
149 len = strlen(conf_file_name);
151 if (conf_file_name[len - 1] != '\\')
152 conf_file_name[len++] = '\\';
154 strcpy(conf_file_name + len, "olsrd.conf");
156 strncpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, FILENAME_MAX);
159 if ((argc > 1) && (strcmp(argv[1], "-f") == 0))
164 fprintf(stderr, "You must provide a filename when using the -f switch!\n");
168 if (stat(argv[1], &statbuf) < 0)
170 fprintf(stderr, "Could not find specified config file %s!\n%s\n\n", argv[1], strerror(errno));
174 strncpy(conf_file_name, argv[1], FILENAME_MAX);
180 * set up configuration prior to processing commandline options
182 if((olsr_cnf = olsrd_parse_cnf(conf_file_name)) == NULL)
184 printf("Using default config values(no configfile)\n");
185 olsr_cnf = olsrd_get_default_cnf();
187 if((default_ifcnf = get_default_if_config()) == NULL)
189 fprintf(stderr, "No default ifconfig found!\n");
194 * Process olsrd options.
198 while (argc > 0 && **argv == '-')
204 if (strcmp(*argv, "-int") == 0)
214 if(strcmp(*argv, "-f") == 0)
216 fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
217 olsr_exit(__func__, EXIT_FAILURE);
223 if(strcmp(*argv, "-ipv6") == 0)
225 olsr_cnf->ip_version = AF_INET6;
233 if(strcmp(*argv, "-bcast") == 0)
238 fprintf(stderr, "You must provide a broadcastaddr when using the -bcast switch!\n");
239 olsr_exit(__func__, EXIT_FAILURE);
241 if (inet_aton(*argv, &in) == 0)
243 printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
246 memcpy(&default_ifcnf->ipv4_broadcast.v4, &in.s_addr, sizeof(olsr_u32_t));
251 * Enable additional debugging information to be logged.
253 if (strcmp(*argv, "-d") == 0)
256 sscanf(*argv,"%d", &olsr_cnf->debug_level);
263 * Interfaces to be used by olsrd.
265 if (strcmp(*argv, "-i") == 0)
268 if(!argc || (*argv[0] == '-'))
270 fprintf(stderr, "You must provide an interface label!\n");
271 olsr_exit(__func__, EXIT_FAILURE);
277 while((argc) && (**argv != '-'))
286 * Set the hello interval to be used by olsrd.
289 if (strcmp(*argv, "-hint") == 0)
292 sscanf(*argv,"%f", &default_ifcnf->hello_params.emission_interval);
293 default_ifcnf->hello_params.validity_time = default_ifcnf->hello_params.emission_interval * 3;
299 * Set the HNA interval to be used by olsrd.
302 if (strcmp(*argv, "-hnaint") == 0)
305 sscanf(*argv,"%f", &default_ifcnf->hna_params.emission_interval);
306 default_ifcnf->hna_params.validity_time = default_ifcnf->hna_params.emission_interval * 3;
312 * Set the MID interval to be used by olsrd.
315 if (strcmp(*argv, "-midint") == 0)
318 sscanf(*argv,"%f", &default_ifcnf->mid_params.emission_interval);
319 default_ifcnf->mid_params.validity_time = default_ifcnf->mid_params.emission_interval * 3;
325 * Set the tc interval to be used by olsrd.
328 if (strcmp(*argv, "-tcint") == 0)
331 sscanf(*argv,"%f", &default_ifcnf->tc_params.emission_interval);
332 default_ifcnf->tc_params.validity_time = default_ifcnf->tc_params.emission_interval * 3;
338 * Set the tos bits to be used by olsrd.
341 if (strcmp(*argv, "-tos") == 0)
344 sscanf(*argv,"%d",(int *)&olsr_cnf->tos);
351 * Set the polling interval to be used by olsrd.
353 if (strcmp(*argv, "-T") == 0)
356 sscanf(*argv,"%f",&olsr_cnf->pollrate);
363 * Should we display the contents of packages beeing sent?
365 if (strcmp(*argv, "-dispin") == 0)
368 disp_pack_in = OLSR_TRUE;
373 * Should we display the contents of incoming packages?
375 if (strcmp(*argv, "-dispout") == 0)
378 disp_pack_out = OLSR_TRUE;
384 * Should we set up and send on a IPC socket for the front-end?
386 if (strcmp(*argv, "-ipc") == 0)
389 olsr_cnf->ipc_connections = 1;
390 olsr_cnf->open_ipc = OLSR_TRUE;
396 * Display link-layer info(experimental)
398 if (strcmp(*argv, "-llinfo") == 0)
406 * IPv6 multicast addr
408 if (strcmp(*argv, "-multi") == 0)
411 if(inet_pton(AF_INET6, *argv, &in6) < 0)
413 fprintf(stderr, "Failed converting IP address %s\n", *argv);
417 memcpy(&default_ifcnf->ipv6_multi_glbl, &in6, sizeof(struct in6_addr));
426 * Should we display the contents of packages beeing sent?
428 if (strcmp(*argv, "-delgw") == 0)
437 olsr_exit(__func__, EXIT_FAILURE);
441 /* Sanity check configuration */
442 if(olsrd_sanity_check_cnf(olsr_cnf) < 0)
445 fprintf(stderr, "Bad configuration!\n");
446 olsr_exit(__func__, EXIT_FAILURE);
450 * Set configuration for command-line specified interfaces
452 set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
455 * Print configuration
457 olsrd_print_cnf(olsr_cnf);
460 *socket for icotl calls
462 if ((ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0)) < 0)
465 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
466 olsr_exit(__func__, 0);
469 #if defined __FreeBSD__ || defined __MacOSX__
470 if ((rts = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
472 olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
473 olsr_exit(__func__, 0);
478 *enable ip forwarding on host
480 enable_ip_forwarding(olsr_cnf->ip_version);
482 /* Initialize parser */
485 /* Initialize message sequencnumber */
488 /* Initialize dynamic willingness calculation */
489 olsr_init_willingness();
492 *Set up willingness/APM
494 if(olsr_cnf->willingness_auto)
498 olsr_printf(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
500 olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
502 olsr_cnf->willingness_auto = 0;
503 olsr_cnf->willingness = WILL_DEFAULT;
507 olsr_cnf->willingness = olsr_calculate_willingness();
509 olsr_printf(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, will_int);
514 *Set ipsize and minimum packetsize
516 if(olsr_cnf->ip_version == AF_INET6)
518 olsr_printf(1, "Using IP version 6\n");
519 ipsize = sizeof(struct in6_addr);
521 minsize = (int)sizeof(olsr_u8_t) * 7; /* Minimum packetsize IPv6 */
525 olsr_printf(1, "Using IP version 4\n");
526 ipsize = sizeof(olsr_u32_t);
528 minsize = (int)sizeof(olsr_u8_t) * 4; /* Minimum packetsize IPv4 */
532 /* Initializing networkinterfaces */
536 if(olsr_cnf->allow_no_interfaces)
538 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");
543 fprintf(stderr, "No interfaces detected!\nBailing out!\n");
544 olsr_exit(__func__, EXIT_FAILURE);
548 /* Print heartbeat to stdout */
550 if(olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO))
551 olsr_register_scheduler_event(&generate_stdout_pulse, NULL, STDOUT_PULSE_INT, 0, NULL);
553 gettimeofday(&now, NULL);
556 /* Initialize the IPC socket */
558 if(olsr_cnf->open_ipc)
562 /* Initialize link-layer notifications */
564 init_link_layer_notification();
567 /* Initialisation of different tables to be used.*/
573 olsr_printf(1, "Main address: %s\n\n", olsr_ip_to_string(&main_addr));
577 if (olsr_cnf->debug_level == 0)
579 printf("%s detattching from the current process...\n", SOFTWARE_VERSION);
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 /* Like we're ever going to reach this ;-) */
620 * Reconfigure olsrd. Currently kind of a hack...
625 olsr_reconfigure(int signal)
631 printf("Restarting %s\n", olsr_argv[0]);
632 execv(olsr_argv[0], olsr_argv);
636 printf("RECONFIGURING!\n");
642 *Function called at shutdown
647 SignalHandler(unsigned long signal)
650 olsr_shutdown(int signal)
653 struct interface *ifn;
655 olsr_printf(1, "Received signal %d - shutting down\n", signal);
657 olsr_delete_all_kernel_routes();
659 olsr_printf(1, "Closing sockets...\n");
661 /* front-end IPC socket */
662 if(olsr_cnf->open_ipc)
666 for (ifn = ifnet; ifn; ifn = ifn->int_next)
667 close(ifn->olsr_socket);
669 /* Closing plug-ins */
670 olsr_close_plugins();
672 /* Reset network settings */
673 restore_settings(olsr_cnf->ip_version);
678 #if defined __FreeBSD__ || defined __MacOSX__
683 olsr_syslog(OLSR_LOG_INFO, "%s stopped", SOFTWARE_VERSION);
685 olsr_printf(1, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n", SOFTWARE_VERSION);
695 *Sets the default values of variables at startup
700 memset(&main_addr, 0, sizeof(union olsr_ip_addr));
701 memset(&null_addr6, 0, sizeof (union olsr_ip_addr));
703 exit_value = EXIT_SUCCESS;
704 /* If the application exits by signal it is concidered success,
705 * if not, exit_value is set by the function calling olsr_exit.
710 dup_hold_time = DUP_HOLD_TIME;
712 will_int = 10 * HELLO_INTERVAL; /* Willingness update interval */
715 del_gws = OLSR_FALSE;
717 /* Display packet content */
718 disp_pack_in = OLSR_FALSE;
719 disp_pack_out = OLSR_FALSE;
729 fprintf(stderr, "An error occured somwhere between your keyboard and your chair!\n");
730 fprintf(stderr, "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n");
731 fprintf(stderr, " [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n");
732 fprintf(stderr, " [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n");
733 fprintf(stderr, " [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n");
734 fprintf(stderr, " [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n");
735 fprintf(stderr, " [-tos value (int)] [-T <Polling Rate (secs)>]\n");
741 * Sets the provided configuration on all unconfigured
745 set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf)
753 ifs->cnf = olsr_malloc(sizeof(struct if_config_options), "Set default config");