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.15 2004/10/19 19:23:00 kattemat Exp $
28 #include "interfaces.h"
29 #include "configfile.h"
31 #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 #include "linux/tunnel.h"
45 #define close(x) closesocket(x)
46 #include "win32/tunnel.h"
47 int __stdcall SignalHandler(unsigned long signal);
48 void ListInterfaces(void);
50 # error "Unsupported system"
54 * Begin: Local function prototypes
61 set_default_values(void);
65 * End: Local function prototypes
73 main(int argc, char *argv[])
76 /* The thread for the scheduler */
79 struct if_config_options *default_ifcnf;
82 char conf_file_name[FILENAME_MAX];
92 /* Initialize socket list */
93 olsr_socket_entries = NULL;
96 /* Check if user is root */
97 if(getuid() || getgid())
99 fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
103 if (WSAStartup(0x0202, &WsaData))
105 fprintf(stderr, "Could not initialize WinSock.\n");
106 olsr_exit(__func__, EXIT_FAILURE);
111 olsr_openlog("olsrd");
116 olsr_syslog(OLSR_LOG_INFO, "%s started", SOFTWARE_VERSION);
118 /* Set default values */
119 set_default_values();
121 /* Initialize network functions */
124 /* Initialize plugin loader */
125 olsr_init_plugin_loader();
127 /* Get initial timestep */
129 while (nowtm == NULL)
131 nowtm = gmtime(&now.tv_sec);
134 /* The port to use for OLSR traffic */
135 olsr_udp_port = htons(OLSRPORT);
137 printf("\n *** %s ***\n Build date: %s\n http://www.olsr.org\n\n",
141 /* Using PID as random seed */
146 * Set configfile name and
147 * check if a configfile name was given as parameter
150 GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
152 len = strlen(conf_file_name);
154 if (conf_file_name[len - 1] != '\\')
155 conf_file_name[len++] = '\\';
157 strcpy(conf_file_name + len, "olsrd.conf");
159 strncpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, FILENAME_MAX);
162 if ((argc > 1) && (strcmp(argv[1], "-f") == 0))
167 fprintf(stderr, "You must provide a filename when using the -f switch!\n");
168 olsr_exit(__func__, EXIT_FAILURE);
171 if (stat(argv[1], &statbuf) < 0)
173 fprintf(stderr, "Could not find specified config file %s!\n%s\n\n", argv[1], strerror(errno));
174 olsr_exit(__func__, EXIT_FAILURE);
177 strncpy(conf_file_name, argv[1], FILENAME_MAX);
183 * Reading configfile options prior to processing commandline options
186 if(read_config_file(conf_file_name) < 0)
188 fprintf(stderr, "Error parsing configig file %s!\n", conf_file_name);
192 default_ifcnf = get_default_ifcnf(olsr_cnf);
194 if(default_ifcnf == NULL)
196 fprintf(stderr, "No default ifconfig found!\n");
201 * Process olsrd options.
205 while (argc > 0 && **argv == '-')
211 if (strcmp(*argv, "-int") == 0)
221 if (strcmp(*argv, "-f") == 0)
223 fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
224 olsr_exit(__func__, EXIT_FAILURE);
230 if (strcmp(*argv, "-ipv6") == 0)
232 olsr_cnf->ip_version = AF_INET6;
241 if (strcmp(*argv, "-bcast") == 0)
246 fprintf(stderr, "You must provide a broadcastaddr when using the -bcast switch!\n");
247 olsr_exit(__func__, EXIT_FAILURE);
250 if (inet_aton(*argv, &in) == 0)
252 printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
256 memcpy(&bcastaddr.sin_addr, &in.s_addr, sizeof(olsr_u32_t));
264 * Enable additional debugging information to be logged.
266 if (strcmp(*argv, "-d") == 0)
269 sscanf(*argv,"%d", &olsr_cnf->debug_level);
278 * Interfaces to be used by olsrd.
280 if (strcmp(*argv, "-i") == 0)
286 while((argc) && (**argv != '-'))
295 * Set the hello interval to be used by olsrd.
298 if (strcmp(*argv, "-hint") == 0)
301 sscanf(*argv,"%f", &default_ifcnf->hello_params.emission_interval);
302 default_ifcnf->hello_params.validity_time = default_ifcnf->hello_params.emission_interval * 3;
308 * Set the HNA interval to be used by olsrd.
311 if (strcmp(*argv, "-hnaint") == 0)
314 sscanf(*argv,"%f", &default_ifcnf->hna_params.emission_interval);
315 default_ifcnf->hna_params.validity_time = default_ifcnf->hna_params.emission_interval * 3;
321 * Set the MID interval to be used by olsrd.
324 if (strcmp(*argv, "-midint") == 0)
327 sscanf(*argv,"%f", &default_ifcnf->mid_params.emission_interval);
328 default_ifcnf->mid_params.validity_time = default_ifcnf->mid_params.emission_interval * 3;
334 * Set the tc interval to be used by olsrd.
337 if (strcmp(*argv, "-tcint") == 0)
340 sscanf(*argv,"%f", &default_ifcnf->tc_params.emission_interval);
341 default_ifcnf->tc_params.validity_time = default_ifcnf->tc_params.emission_interval * 3;
347 * Set the tos bits to be used by olsrd.
350 if (strcmp(*argv, "-tos") == 0)
353 sscanf(*argv,"%d",(int *)&olsr_cnf->tos);
360 * Set the polling interval to be used by olsrd.
362 if (strcmp(*argv, "-T") == 0)
365 sscanf(*argv,"%f",&olsr_cnf->pollrate);
372 * Should we display the contents of packages beeing sent?
374 if (strcmp(*argv, "-dispin") == 0)
382 * Should we display the contents of incoming packages?
384 if (strcmp(*argv, "-dispout") == 0)
393 * Should we set up and send on a IPC socket for the front-end?
395 if (strcmp(*argv, "-ipc") == 0)
398 olsr_cnf->open_ipc = 1;
404 * Display link-layer info(experimental)
406 if (strcmp(*argv, "-llinfo") == 0)
414 * Use Internet gateway tunneling?
416 if (strcmp(*argv, "-tnl") == 0)
426 * IPv6 multicast addr
428 if (strcmp(*argv, "-multi") == 0)
431 strncpy(ipv6_mult, *argv, 50);
440 * Should we display the contents of packages beeing sent?
442 if (strcmp(*argv, "-delgw") == 0)
451 olsr_exit(__func__, EXIT_FAILURE);
456 *Interfaces need to be specified
458 if(olsr_cnf->interfaces == NULL)
460 fprintf(stderr, "OLSRD: no interfaces specified!\nuse the -i switch to specify interface(s)\nor set interface(s) in the configuration file!\n");
462 olsr_exit(__func__, EXIT_FAILURE);
466 *socket for icotl calls
468 if ((ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0)) < 0)
470 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
472 olsr_exit(__func__, 0);
476 /* Type of service */
477 precedence = IPTOS_PREC(olsr_cnf->tos);
478 tos_bits = IPTOS_TOS(olsr_cnf->tos);
482 *enable ip forwarding on host
484 enable_ip_forwarding(olsr_cnf->ip_version);
486 /* Initialize scheduler MUST HAPPEN BEFORE REGISTERING ANY FUNCTIONS! */
487 init_scheduler(olsr_cnf->pollrate);
489 /* Initialize parser */
492 /* Initialize message sequencnumber */
495 /* Initialize dynamic willingness calculation */
496 olsr_init_willingness();
498 /* printout settings */
499 olsr_printf(1, "\npolling interval = %0.2f \ntos setting = %d \ntc_redunadancy = %d\nmpr coverage = %d\n", olsr_cnf->pollrate, olsr_cnf->tos, olsr_cnf->tc_redundancy, olsr_cnf->mpr_coverage);
501 if(olsr_cnf->use_hysteresis)
503 olsr_printf(1, "hysteresis scaling factor = %0.2f\nhysteresis threshold high = %0.2f\nhysteresis threshold low = %0.2f\n\n",
504 olsr_cnf->hysteresis_param.scaling,
505 olsr_cnf->hysteresis_param.thr_high,
506 olsr_cnf->hysteresis_param.thr_low);
508 if(olsr_cnf->hysteresis_param.thr_high <= olsr_cnf->hysteresis_param.thr_low)
510 printf("Hysteresis threshold high lower than threshold low!!\nEdit the configuration file to fix this!\n\n");
511 olsr_exit(__func__, EXIT_FAILURE);
516 *Set up willingness/APM
518 if(olsr_cnf->willingness_auto)
522 olsr_printf(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
524 olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
526 olsr_cnf->willingness_auto = 0;
527 olsr_cnf->willingness = WILL_DEFAULT;
531 olsr_cnf->willingness = olsr_calculate_willingness();
533 olsr_printf(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, will_int);
538 *Set ipsize and minimum packetsize
540 if(olsr_cnf->ip_version == AF_INET6)
542 olsr_printf(1, "Using IP version 6\n");
543 ipsize = sizeof(struct in6_addr);
545 minsize = (int)sizeof(olsr_u8_t) * 7; /* Minimum packetsize IPv6 */
549 olsr_printf(1, "Using IP version 4\n");
550 ipsize = sizeof(olsr_u32_t);
552 minsize = (int)sizeof(olsr_u8_t) * 4; /* Minimum packetsize IPv4 */
556 /* Initializing networkinterfaces */
560 if(olsr_cnf->allow_no_interfaces)
562 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");
567 fprintf(stderr, "No interfaces detected!\nBailing out!\n");
568 olsr_exit(__func__, EXIT_FAILURE);
573 /* Initialize values for emission data
574 * This also initiates message generation
577 olsr_set_hello_interval(hello_int);
578 olsr_set_hello_nw_interval(hello_int_nw);
579 olsr_set_tc_interval(tc_int);
580 olsr_set_mid_interval(mid_int);
581 olsr_set_hna_interval(hna_int);
583 /* Print tables to stdout */
584 if(olsr_cnf->debug_level > 0)
585 olsr_register_scheduler_event(&generate_tabledisplay, NULL, HELLO_INTERVAL, 0, NULL);
588 gettimeofday(&now, NULL);
591 /* Initialize the IPC socket */
593 if(olsr_cnf->open_ipc)
597 /* Initialize link-layer notifications */
599 init_link_layer_notification();
602 /* Initialisation of different tables to be used.*/
608 /* Set up recieving tunnel if Inet gw */
609 if(use_tunnel && check_inet_gw())
610 set_up_gw_tunnel(&main_addr);
612 olsr_printf(1, "Main address: %s\n\n", olsr_ip_to_string(&main_addr));
614 olsr_printf(1, "NEIGHBORS: l=linkstate, m=MPR, w=willingness\n\n");
619 if (olsr_cnf->debug_level == 0)
621 printf("%s detattching from the current process...\n", SOFTWARE_VERSION);
629 /* Starting scheduler */
630 start_scheduler(&thread);
636 /* ctrl-C and friends */
638 SetConsoleCtrlHandler(SignalHandler, TRUE);
640 signal(SIGINT, olsr_shutdown);
641 signal(SIGTERM, olsr_shutdown);
644 /* Go into listenloop */
647 /* Like we're ever going to reach this ;-) */
658 *Function called at shutdown
663 SignalHandler(unsigned long signal)
666 olsr_shutdown(int signal)
669 struct interface *ifn;
671 if(main_thread != pthread_self())
677 olsr_printf(1, "Received signal %d - shutting down\n", signal);
679 olsr_delete_all_kernel_routes();
681 olsr_printf(1, "Closing sockets...\n");
683 /* front-end IPC socket */
684 if(olsr_cnf->open_ipc)
688 for (ifn = ifnet; ifn; ifn = ifn->int_next)
689 close(ifn->olsr_socket);
691 /* Closing plug-ins */
692 olsr_close_plugins();
694 /* Reset network settings */
695 restore_settings(olsr_cnf->ip_version);
700 olsr_syslog(OLSR_LOG_INFO, "%s stopped", SOFTWARE_VERSION);
702 olsr_printf(1, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n", SOFTWARE_VERSION);
712 *Sets the default values of variables at startup
717 memset(&main_addr, 0, sizeof(union olsr_ip_addr));
718 memset(&null_addr6, 0, sizeof (union olsr_ip_addr));
720 exit_value = EXIT_SUCCESS;
721 /* If the application exits by signal it is concidered success,
722 * if not, exit_value is set by the function calling olsr_exit.
727 dup_hold_time = DUP_HOLD_TIME;
731 will_int = 10 * HELLO_INTERVAL; /* Willingness update interval */
737 /* Get main thread ID */
738 main_thread = pthread_self();
741 /* Gateway tunneling */
746 /* Display packet content */
758 fprintf(stderr, "An error occured somwhere between your keyboard and your chair!\n");
759 fprintf(stderr, "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n");
760 fprintf(stderr, " [-d <debug_level>] [-ipv6] [-tnl] [-multi <IPv6 multicast address>]\n");
761 fprintf(stderr, " [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n");
762 fprintf(stderr, " [-midint <mid interval value (secs)>] [-hnaint <hna interval value (secs)>]\n");
763 fprintf(stderr, " [-hint <hello interval value (secs)>] [-tcint <tc interval value (secs)>]\n");
764 fprintf(stderr, " [-tos value (int)] [-T <Polling Rate (secs)>]\n");