use inet_pton instead of inet_aton
[olsrd.git] / src / main.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
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
15  *   distribution.
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.
19  *
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.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
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.
38  *
39  */
40
41 #include <arpa/inet.h>
42 #include <unistd.h>
43 #include <signal.h>
44 #include <sys/stat.h>
45 #include <assert.h>
46 #include <fcntl.h>
47
48 #include "ipcalc.h"
49 #include "defs.h"
50 #include "builddata.h"
51 #include "olsr.h"
52 #include "log.h"
53 #include "scheduler.h"
54 #include "parser.h"
55 #include "generate_msg.h"
56 #include "plugin_loader.h"
57 #include "apm.h"
58 #include "net_os.h"
59 #include "build_msg.h"
60 #include "net_olsr.h"
61 #include "mid_set.h"
62 #include "mpr_selector_set.h"
63 #include "gateway.h"
64 #include "olsr_niit.h"
65
66 #ifdef __linux__
67 #include <linux/types.h>
68 #include <linux/rtnetlink.h>
69 #include "kernel_routes.h"
70
71 #endif /* __linux__ */
72
73 #ifdef _WIN32
74 #include <process.h>
75 #include <winbase.h>
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;
83 #else /* _WIN32 */
84 static void olsr_shutdown(int) __attribute__ ((noreturn));
85 #endif /* _WIN32 */
86
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"
91 #elif defined _WIN32
92 #define DEFAULT_LOCKFILE_PREFIX "C:\\olsrd"
93 #else /* defined _WIN32 */
94 #define DEFAULT_LOCKFILE_PREFIX "olsrd"
95 #endif /* defined _WIN32 */
96
97 /*
98  * Local function prototypes
99  */
100 void olsr_reconfigure(int signo) __attribute__ ((noreturn));
101
102 static void print_usage(bool error);
103
104 static int set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
105
106 static int olsr_process_arguments(int, char *[], struct olsrd_config *,
107     struct if_config_options *);
108
109 #ifndef _WIN32
110 static char **olsr_argv;
111 #endif /* _WIN32 */
112
113 static char
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.";
116
117 /* Data for OLSR locking */
118 #ifndef _WIN32
119 static int lock_fd = 0;
120 #endif /* _WIN32 */
121 static char lock_file_name[FILENAME_MAX];
122 struct olsr_cookie_info *def_timer_ci = NULL;
123
124 /*
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.
129  *
130  * Additionally the lock can be killed by removing the
131  * locking file.
132  */
133 static int olsr_create_lock_file(bool noExitOnFail) {
134 #ifdef _WIN32
135     bool success;
136     HANDLE lck;
137
138     lck = CreateFile(lock_file_name,
139             GENERIC_READ | GENERIC_WRITE,
140             FILE_SHARE_READ | FILE_SHARE_WRITE,
141             NULL,
142             OPEN_ALWAYS,
143             FILE_ATTRIBUTE_NORMAL |
144             FILE_FLAG_DELETE_ON_CLOSE,
145             NULL);
146   CreateEvent(NULL, TRUE, FALSE, lock_file_name);
147   if (INVALID_HANDLE_VALUE == lck || ERROR_ALREADY_EXISTS == GetLastError()) {
148     if (noExitOnFail) {
149       return -1;
150     }
151     if (NULL == lck) {
152       fprintf(stderr,
153           "Error, cannot create OLSR lock '%s'.\n",
154           lock_file_name);
155     } else {
156       CloseHandle(lck);
157       fprintf(stderr,
158           "Error, cannot aquire OLSR lock '%s'.\n"
159           "Another OLSR instance might be running.\n",
160           lock_file_name);
161     }
162     olsr_exit("", EXIT_FAILURE);
163   }
164
165   success = LockFile( lck, 0, 0, 0, 0);
166
167   if (!success) {
168       CloseHandle(lck);
169       if (noExitOnFail) {
170           return -1;
171       }
172       fprintf(stderr,
173           "Error, cannot aquire OLSR lock '%s'.\n"
174           "Another OLSR instance might be running.\n",
175           lock_file_name);
176     olsr_exit("", EXIT_FAILURE);
177   }
178       
179 #else /* _WIN32 */
180   struct flock lck;
181
182   /* create file for lock */
183   lock_fd = open(lock_file_name, O_WRONLY | O_CREAT, S_IRWXU);
184   if (lock_fd < 0) {
185     if (noExitOnFail) {
186       return -1;
187     }
188     fprintf(stderr,
189         "Error, cannot create OLSR lock '%s'.\n",
190         lock_file_name);
191     olsr_exit("", EXIT_FAILURE);
192   }
193
194   /* create exclusive lock for the whole file */
195   lck.l_type = F_WRLCK;
196   lck.l_whence = SEEK_SET;
197   lck.l_start = 0;
198   lck.l_len = 0;
199   lck.l_pid = 0;
200
201   if (fcntl(lock_fd, F_SETLK, &lck) == -1) {
202     close(lock_fd);
203     if (noExitOnFail) {
204       return -1;
205     }
206     fprintf(stderr,
207         "Error, cannot aquire OLSR lock '%s'.\n"
208         "Another OLSR instance might be running.\n",
209         lock_file_name);
210     olsr_exit("", EXIT_FAILURE);
211   }
212 #endif /* _WIN32 */
213   return 0;
214 }
215
216 /**
217  * Write the current PID to the configured PID file (if one is configured)
218  */
219 static void writePidFile(void) {
220   if (olsr_cnf->pidfile) {
221     char buf[PATH_MAX + 256];
222
223     /* create / open the PID file */
224 #ifdef __WIN32
225     mode_t mode = S_IRUSR | S_IWUSR;
226 #else
227     mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
228 #endif
229     int fd = open(olsr_cnf->pidfile, O_CREAT | O_WRONLY, mode);
230     if (fd < 0) {
231       snprintf(buf, sizeof(buf), "Could not open PID file %s", olsr_cnf->pidfile);
232       perror(buf);
233       olsr_shutdown(0);
234     }
235
236     /* write the PID */
237     {
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) {
242         close(fd);
243         snprintf(buf, sizeof(buf), "Could not write the PID %d to the PID file %s", (int)pid, olsr_cnf->pidfile);
244         perror(buf);
245         if (remove(olsr_cnf->pidfile) < 0) {
246           snprintf(buf, sizeof(buf), "Could not remove the PID file %s", olsr_cnf->pidfile);
247           perror(buf);
248         }
249         olsr_shutdown(0);
250       }
251     }
252
253     if (close(fd) < 0) {
254       snprintf(buf, sizeof(buf), "Could not close PID file %s", olsr_cnf->pidfile);
255       perror(buf);
256       if (remove(olsr_cnf->pidfile) < 0) {
257         snprintf(buf, sizeof(buf), "Could not remove the PID file %s", olsr_cnf->pidfile);
258         perror(buf);
259       }
260       olsr_shutdown(0);
261     }
262   }
263 }
264
265 /**
266  * loads a config file
267  * @return <0 if load failed, 0 otherwise
268  */
269 static int
270 olsrmain_load_config(char *file) {
271   struct stat statbuf;
272
273   if (stat(file, &statbuf) < 0) {
274     fprintf(stderr, "Could not find specified config file %s!\n%s\n\n",
275         file, strerror(errno));
276     return -1;
277   }
278
279   if (olsrd_parse_cnf(file) < 0) {
280     fprintf(stderr, "Error while reading config file %s!\n", file);
281     return -1;
282   }
283   return 0;
284 }
285
286 static void initRandom(void) {
287   unsigned int seed = (unsigned int)time(NULL);
288
289 #ifndef _WIN32
290   int randomFile;
291
292   randomFile = open("/dev/urandom", O_RDONLY);
293   if (randomFile == -1) {
294     randomFile = open("/dev/random", O_RDONLY);
295   }
296
297   if (randomFile != -1) {
298     if (read(randomFile, &seed, sizeof(seed)) != sizeof(seed)) {
299       ; /* to fix an 'unused result' compiler warning */
300     }
301     close(randomFile);
302   }
303 #endif /* _WIN32 */
304
305   srandom(seed);
306 }
307
308 /**
309  * Main entrypoint
310  */
311
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;
317   int i;
318
319 #ifdef __linux__
320   struct interface *ifn;
321 #endif /* __linux__ */
322
323 #ifdef _WIN32
324   WSADATA WsaData;
325   size_t len;
326 #endif /* __linux__ */
327
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);
335
336   printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n",
337       olsrd_version, build_date, build_host);
338
339   if (argc == 2) {
340     if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "/?") == 0)) {
341       print_usage(false);
342       exit(0);
343     }
344     if (strcmp(argv[1], "-v") == 0) {
345       exit(0);
346     }
347   }
348
349   debug_handle = stdout;
350 #ifndef _WIN32
351   olsr_argv = argv;
352 #endif /* _WIN32 */
353   setbuf(stdout, NULL);
354   setbuf(stderr, NULL);
355
356 #ifndef _WIN32
357   /* Check if user is root */
358   if (geteuid()) {
359     fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
360     exit(EXIT_FAILURE);
361   }
362 #else /* _WIN32 */
363   DisableIcmpRedirects();
364
365   if (WSAStartup(0x0202, &WsaData)) {
366     fprintf(stderr, "Could not initialize WinSock.\n");
367     olsr_exit(__func__, EXIT_FAILURE);
368   }
369 #endif /* _WIN32 */
370
371   /* Open syslog */
372   olsr_openlog("olsrd");
373
374   /* setup random seed */
375   initRandom();
376
377   /* Init widely used statics */
378   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
379
380   /*
381    * Set configfile name and
382    * check if a configfile name was given as parameter
383    */
384 #ifdef _WIN32
385 #ifndef WINCE
386   GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
387 #else /* WINCE */
388   conf_file_name[0] = 0;
389 #endif /* WINCE */
390
391   len = strlen(conf_file_name);
392
393   if (len == 0 || conf_file_name[len - 1] != '\\')
394   conf_file_name[len++] = '\\';
395
396   strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
397 #else /* _WIN32 */
398   strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
399 #endif /* _WIN32 */
400
401   olsr_cnf = olsrd_get_default_cnf();
402   for (i=1; i < argc-1;) {
403     if (strcmp(argv[i], "-f") == 0) {
404       loadedConfig = true;
405
406       if (olsrmain_load_config(argv[i+1]) < 0) {
407         exit(EXIT_FAILURE);
408       }
409
410       if (i+2 < argc) {
411         memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1));
412       }
413       argc -= 2;
414     }
415     else {
416       i++;
417     }
418   }
419
420   /*
421    * set up configuration prior to processing commandline options
422    */
423   if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) {
424     loadedConfig = true;
425   }
426
427   if (!loadedConfig) {
428     olsrd_free_cnf(olsr_cnf);
429     olsr_cnf = olsrd_get_default_cnf();
430   }
431
432   default_ifcnf = get_default_if_config();
433   if (default_ifcnf == NULL) {
434     fprintf(stderr, "No default ifconfig found!\n");
435     exit(EXIT_FAILURE);
436   }
437
438   /* Initialize timers */
439   olsr_init_timers();
440
441   /*
442    * Process olsrd options.
443    */
444   if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) {
445     print_usage(true);
446     olsr_exit(__func__, EXIT_FAILURE);
447   }
448
449   /*
450    * Set configuration for command-line specified interfaces
451    */
452   set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
453
454   /* free the default ifcnf */
455   free(default_ifcnf);
456
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);
461   }
462
463   /*
464    * Establish file lock to prevent multiple instances
465    */
466   if (olsr_cnf->lock_file) {
467     strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name));
468   } else {
469     size_t l;
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);
478   }
479
480   /*
481    * Print configuration
482    */
483   if (olsr_cnf->debug_level > 1) {
484     olsrd_print_cnf(olsr_cnf);
485   }
486
487   def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);
488
489   /*
490    * socket for ioctl calls
491    */
492   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
493   if (olsr_cnf->ioctl_s < 0) {
494 #ifndef _WIN32
495     olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
496 #endif /* _WIN32 */
497     olsr_exit(__func__, 0);
498   }
499 #ifdef __linux__
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);
504   }
505
506   if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
507     olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
508   }
509
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);
513   }
514 #endif /* __linux__ */
515
516   /*
517    * create routing socket
518    */
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);
524   }
525 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
526
527 #ifdef __linux__
528   /* initialize gateway system */
529   if (olsr_cnf->smart_gw_active) {
530     if (olsr_init_gateways()) {
531       olsr_exit("Cannot initialize gateway tunnels", 1);
532     }
533   }
534
535   /* initialize niit if index */
536   if (olsr_cnf->use_niit) {
537     olsr_init_niit();
538   }
539 #endif /* __linux__ */
540
541   /* Init empty TC timer */
542   set_empty_tc_timer(GET_TIMESTAMP(0));
543
544   /* enable ip forwarding on host */
545   /* Disable redirects globally (not for WIN32) */
546   net_os_set_global_ifoptions();
547
548   /* Initialize parser */
549   olsr_init_parser();
550
551   /* Initialize route-exporter */
552   olsr_init_export_route();
553
554   /* Initialize message sequencnumber */
555   init_msg_seqno();
556
557   /* Initialize dynamic willingness calculation */
558   olsr_init_willingness();
559
560   /*
561    *Set up willingness/APM
562    */
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);
566
567       olsr_syslog(OLSR_LOG_ERR,
568           "Could not read APM info - setting default willingness(%d)\n",
569           WILL_DEFAULT);
570
571       olsr_cnf->willingness_auto = 0;
572       olsr_cnf->willingness = WILL_DEFAULT;
573     } else {
574       olsr_cnf->willingness = olsr_calculate_willingness();
575
576       OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double)olsr_cnf->will_int);
577     }
578   }
579
580   /* Initialize net */
581   init_net();
582
583   /* Initializing networkinterfaces */
584   if (!olsr_init_interfacedb()) {
585     if (olsr_cnf->allow_no_interfaces) {
586       fprintf(
587           stderr,
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);
590     } else {
591       fprintf(stderr, "No interfaces detected!\nBailing out!\n");
592       olsr_exit(__func__, EXIT_FAILURE);
593     }
594   }
595
596 #ifdef __linux__
597   /* startup gateway system */
598   if (olsr_cnf->smart_gw_active) {
599     if (olsr_startup_gateways()) {
600       olsr_exit("Cannot startup gateway tunnels", 1);
601     }
602   }
603 #endif /* __linux__ */
604
605   olsr_do_startup_sleep();
606
607   /* Print heartbeat to stdout */
608
609 #if !defined WINCE
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);
613   }
614 #endif /* !defined WINCE */
615
616   /* Initialize the IPC socket */
617
618   if (olsr_cnf->ipc_connections > 0) {
619     if (ipc_init()) {
620       olsr_exit("ipc_init failure", 1);
621     }
622   }
623   /* Initialisation of different tables to be used. */
624   olsr_init_tables();
625
626   /* daemon mode */
627 #ifndef _WIN32
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));
632       exit(EXIT_FAILURE);
633     }
634   }
635 #endif /* _WIN32 */
636
637   writePidFile();
638
639   /*
640    * Create locking file for olsrd, will be cleared after olsrd exits
641    */
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 */
646       break;
647     }
648     sleep (1);
649   }
650
651   /* Load plugins */
652   olsr_load_plugins();
653
654   OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
655
656 #ifdef __linux__
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);
661   }
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);
665   }
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);
669   }
670
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);
676     }
677   }
678
679   /* trigger gateway selection */
680   if (olsr_cnf->smart_gw_active) {
681     olsr_trigger_inetgw_startup();
682   }
683
684   /* trigger niit static route setup */
685   if (olsr_cnf->use_niit) {
686     olsr_setup_niit_routes();
687   }
688
689   /* create lo:olsr interface */
690   if (olsr_cnf->use_src_ip_routes) {
691     olsr_os_localhost_if(&olsr_cnf->main_addr, true);
692   }
693 #endif /* __linux__ */
694
695   /* Start syslog entry */
696   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
697
698   /*
699    *signal-handlers
700    */
701
702   /* ctrl-C and friends */
703 #ifdef _WIN32
704 #ifndef WINCE
705   SetConsoleCtrlHandler(SignalHandler, true);
706 #endif /* WINCE */
707 #else /* _WIN32 */
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);
719 #endif /* _WIN32 */
720
721   link_changes = false;
722
723   /* Starting scheduler */
724   olsr_scheduler();
725
726   /* Like we're ever going to reach this ;-) */
727   return 1;
728 } /* main */
729
730 #ifndef _WIN32
731 /**
732  * Reconfigure olsrd. Currently kind of a hack...
733  *
734  *@param signo the signal that triggered this callback
735  */
736 void olsr_reconfigure(int signo __attribute__ ((unused))) {
737 #ifndef _WIN32
738   int errNr = errno;
739 #endif
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
742    */
743   olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
744   if (!olsr_cnf->no_fork) {
745     if (!fork()) {
746       int i;
747       sigset_t sigs;
748       /* New process */
749       sleep(3);
750       sigemptyset(&sigs);
751       sigaddset(&sigs, SIGHUP);
752       sigprocmask(SIG_UNBLOCK, &sigs, NULL);
753       for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
754         close(i);
755       }
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],
760           strerror(errno));
761     } else {
762       olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING!\n");
763     }
764   }
765 #ifndef _WIN32
766   errno = errNr;
767 #endif
768   olsr_shutdown(0);
769 }
770 #endif /* _WIN32 */
771
772 static void olsr_shutdown_messages(void) {
773   struct interface *ifn;
774
775   /* send TC reset */
776   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
777     /* clean output buffer */
778     net_output(ifn);
779
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);
784     }
785     else {
786       generate_tc(ifn);
787       generate_hello(ifn);
788     }
789     net_output(ifn);
790   }
791 }
792
793 /**
794  *Function called at shutdown. Signal handler
795  *
796  * @param signo the signal that triggered this call
797  */
798 #ifdef _WIN32
799 int __stdcall
800 SignalHandler(unsigned long signo)
801 #else /* _WIN32 */
802 static void olsr_shutdown(int signo __attribute__ ((unused)))
803 #endif /* _WIN32 */
804 {
805 #ifndef _WIN32
806   int errNr = errno;
807 #endif
808   struct interface *ifn;
809   int exit_value;
810
811   OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
812
813 #ifdef _WIN32
814   OLSR_PRINTF(1, "Waiting for the scheduler to stop.\n");
815
816   olsr_win32_end_request = TRUE;
817
818   while (!olsr_win32_end_flag)
819   sleep(1);
820
821   OLSR_PRINTF(1, "Scheduler stopped.\n");
822 #endif /* _WIN32 */
823
824   /* clear all links and send empty hellos/tcs */
825   olsr_reset_all_links();
826
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;
831   }
832   increase_local_ansn();
833
834   /* send first shutdown message burst */
835   olsr_shutdown_messages();
836
837   /* delete all routes */
838   olsr_delete_all_kernel_routes();
839
840   /* send second shutdown message burst */
841   olsr_shutdown_messages();
842
843   /* now try to cleanup the rest of the mess */
844   olsr_delete_all_tc_entries();
845
846   olsr_delete_all_mid_entries();
847
848 #ifdef __linux__
849   /* trigger gateway selection */
850   if (olsr_cnf->smart_gw_active) {
851     olsr_shutdown_gateways();
852     olsr_cleanup_gateways();
853   }
854
855   /* trigger niit static route cleanup */
856   if (olsr_cnf->use_niit) {
857     olsr_cleanup_niit_routes();
858   }
859
860   /* cleanup lo:olsr interface */
861   if (olsr_cnf->use_src_ip_routes) {
862     olsr_os_localhost_if(&olsr_cnf->main_addr, false);
863   }
864 #endif /* __linux__ */
865
866   olsr_destroy_parser();
867
868   OLSR_PRINTF(1, "Closing sockets...\n");
869
870   /* front-end IPC socket */
871   if (olsr_cnf->ipc_connections > 0) {
872     shutdown_ipc();
873   }
874
875   /* OLSR sockets */
876   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
877     close(ifn->olsr_socket);
878     close(ifn->send_socket);
879
880 #ifdef __linux__
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);
884     }
885 #endif /* __linux__ */
886   }
887
888   /* Closing plug-ins */
889   olsr_close_plugins();
890
891   /* Reset network settings */
892   net_os_restore_ifoptions();
893
894   /* ioctl socket */
895   close(olsr_cnf->ioctl_s);
896
897 #ifdef __linux__
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);
901   }
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);
905   }
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);
909   }
910   close(olsr_cnf->rtnl_s);
911   close (olsr_cnf->rt_monitor_socket);
912 #endif /* __linux__ */
913
914 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
915   /* routing socket */
916   close(olsr_cnf->rts);
917 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
918
919   /* Free cookies and memory pools attached. */
920   OLSR_PRINTF(0, "Free all memory...\n");
921   olsr_delete_all_cookies();
922
923   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
924
925   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
926
927   exit_value = olsr_cnf->exit_value;
928   olsrd_free_cnf(olsr_cnf);
929
930 #ifndef _WIN32
931   errno = errNr;
932 #endif
933   exit(exit_value);
934 }
935
936 /**
937  * Print the command line usage
938  */
939 static void print_usage(bool error) {
940   fprintf(
941       stderr,
942         "%s"
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" : "");
953 }
954
955 /**
956  * Sets the provided configuration on all unconfigured
957  * interfaces
958  *
959  * @param ifs a linked list of interfaces to check and possible update
960  * @param cnf the default configuration to set on unconfigured interfaces
961  */
962 int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
963   int changes = 0;
964
965   while (ifs) {
966     if (ifs->cnf == NULL) {
967       ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
968           "Set default config");
969       *ifs->cnf = *cnf;
970       changes++;
971     }
972     ifs = ifs->next;
973   }
974   return changes;
975 }
976
977 #define NEXT_ARG do { argv++;argc--; } while (0)
978 #define CHECK_ARGC do { if(!argc) { \
979      argv--; \
980      fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
981      olsr_exit(__func__, EXIT_FAILURE); \
982      } } while (0)
983
984 /**
985  * Process command line arguments passed to olsrd
986  *
987  */
988 static int olsr_process_arguments(int argc, char *argv[],
989     struct olsrd_config *cnf, struct if_config_options *ifcnf) {
990   while (argc > 1) {
991     NEXT_ARG;
992 #ifdef _WIN32
993     /*
994      *Interface list
995      */
996     if (strcmp(*argv, "-int") == 0) {
997       ListInterfaces();
998       exit(0);
999     }
1000 #endif /* _WIN32 */
1001
1002     /*
1003      *Configfilename
1004      */
1005     if (strcmp(*argv, "-f") == 0) {
1006       fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
1007       olsr_exit(__func__, EXIT_FAILURE);
1008     }
1009
1010     /*
1011      *Use IP version 6
1012      */
1013     if (strcmp(*argv, "-ipv6") == 0) {
1014       cnf->ip_version = AF_INET6;
1015       continue;
1016     }
1017
1018     /*
1019      *Broadcast address
1020      */
1021     if (strcmp(*argv, "-bcast") == 0) {
1022       struct in_addr in;
1023       NEXT_ARG;
1024       CHECK_ARGC;
1025
1026       if (inet_pton(AF_INET, *argv, &in) == 0) {
1027         printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
1028         continue;
1029       }
1030       memcpy(&ifcnf->ipv4_multicast.v4, &in.s_addr, sizeof(ifcnf->ipv4_multicast.v4));
1031       continue;
1032     }
1033
1034     /*
1035      * Set LQ level
1036      */
1037     if (strcmp(*argv, "-lql") == 0) {
1038       int tmp_lq_level;
1039       NEXT_ARG;
1040       CHECK_ARGC;
1041
1042       /* Sanity checking is done later */
1043       sscanf(*argv, "%d", &tmp_lq_level);
1044       olsr_cnf->lq_level = tmp_lq_level;
1045       continue;
1046     }
1047
1048     /*
1049      * Set LQ winsize
1050      */
1051     if (strcmp(*argv, "-lqa") == 0) {
1052       float tmp_lq_aging;
1053       NEXT_ARG;
1054       CHECK_ARGC;
1055
1056       sscanf(*argv, "%f", &tmp_lq_aging);
1057
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);
1062       }
1063       olsr_cnf->lq_aging = tmp_lq_aging;
1064       continue;
1065     }
1066
1067     /*
1068      * Set NAT threshold
1069      */
1070     if (strcmp(*argv, "-lqnt") == 0) {
1071       float tmp_lq_nat_thresh;
1072       NEXT_ARG;
1073       CHECK_ARGC;
1074
1075       sscanf(*argv, "%f", &tmp_lq_nat_thresh);
1076
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);
1081       }
1082       olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
1083       continue;
1084     }
1085
1086     /*
1087      * Enable additional debugging information to be logged.
1088      */
1089     if (strcmp(*argv, "-d") == 0) {
1090       NEXT_ARG;
1091       CHECK_ARGC;
1092
1093       sscanf(*argv, "%d", &cnf->debug_level);
1094       continue;
1095     }
1096
1097     /*
1098      * Interfaces to be used by olsrd.
1099      */
1100     if (strcmp(*argv, "-i") == 0) {
1101       NEXT_ARG;
1102       CHECK_ARGC;
1103
1104       if (*argv[0] == '-') {
1105         fprintf(stderr, "You must provide an interface label!\n");
1106         olsr_exit(__func__, EXIT_FAILURE);
1107       }
1108       printf("Queuing if %s\n", *argv);
1109       olsr_create_olsrif(*argv, false);
1110
1111       while ((argc - 1) && (argv[1][0] != '-')) {
1112         NEXT_ARG;
1113         printf("Queuing if %s\n", *argv);
1114         olsr_create_olsrif(*argv, false);
1115       }
1116
1117       continue;
1118     }
1119     /*
1120      * Set the hello interval to be used by olsrd.
1121      *
1122      */
1123     if (strcmp(*argv, "-hint") == 0) {
1124       NEXT_ARG;
1125       CHECK_ARGC;
1126       sscanf(*argv, "%f", &ifcnf->hello_params.emission_interval);
1127       ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval
1128           * 3;
1129       continue;
1130     }
1131
1132     /*
1133      * Set the HNA interval to be used by olsrd.
1134      *
1135      */
1136     if (strcmp(*argv, "-hnaint") == 0) {
1137       NEXT_ARG;
1138       CHECK_ARGC;
1139       sscanf(*argv, "%f", &ifcnf->hna_params.emission_interval);
1140       ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
1141       continue;
1142     }
1143
1144     /*
1145      * Set the MID interval to be used by olsrd.
1146      *
1147      */
1148     if (strcmp(*argv, "-midint") == 0) {
1149       NEXT_ARG;
1150       CHECK_ARGC;
1151       sscanf(*argv, "%f", &ifcnf->mid_params.emission_interval);
1152       ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
1153       continue;
1154     }
1155
1156     /*
1157      * Set the tc interval to be used by olsrd.
1158      *
1159      */
1160     if (strcmp(*argv, "-tcint") == 0) {
1161       NEXT_ARG;
1162       CHECK_ARGC;
1163       sscanf(*argv, "%f", &ifcnf->tc_params.emission_interval);
1164       ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
1165       continue;
1166     }
1167
1168     /*
1169      * Set the polling interval to be used by olsrd.
1170      */
1171     if (strcmp(*argv, "-T") == 0) {
1172       NEXT_ARG;
1173       CHECK_ARGC;
1174       sscanf(*argv, "%f", &cnf->pollrate);
1175       continue;
1176     }
1177
1178     /*
1179      * Should we set up and send on a IPC socket for the front-end?
1180      */
1181     if (strcmp(*argv, "-ipc") == 0) {
1182       cnf->ipc_connections = 1;
1183       continue;
1184     }
1185
1186     /*
1187      * IPv6 multicast addr
1188      */
1189     if (strcmp(*argv, "-multi") == 0) {
1190       struct in6_addr in6;
1191       NEXT_ARG;
1192       CHECK_ARGC;
1193       if (inet_pton(AF_INET6, *argv, &in6) <= 0) {
1194         fprintf(stderr, "Failed converting IP address %s\n", *argv);
1195         exit(EXIT_FAILURE);
1196       }
1197
1198       memcpy(&ifcnf->ipv6_multicast, &in6, sizeof(struct in6_addr));
1199
1200       continue;
1201     }
1202
1203     /*
1204      * Host emulation
1205      */
1206     if (strcmp(*argv, "-hemu") == 0) {
1207       struct in_addr in;
1208       struct olsr_if *ifa;
1209
1210       NEXT_ARG;
1211       CHECK_ARGC;
1212       if (inet_pton(AF_INET, *argv, &in) <= 0) {
1213         fprintf(stderr, "Failed converting IP address %s\n", *argv);
1214         exit(EXIT_FAILURE);
1215       }
1216       /* Add hemu interface */
1217
1218       ifa = olsr_create_olsrif("hcif01", true);
1219
1220       if (!ifa)
1221         continue;
1222
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;
1228
1229       continue;
1230     }
1231
1232     /*
1233      * Delete possible default GWs
1234      */
1235     if (strcmp(*argv, "-delgw") == 0) {
1236       olsr_cnf->del_gws = true;
1237       continue;
1238     }
1239
1240     if (strcmp(*argv, "-nofork") == 0) {
1241       cnf->no_fork = true;
1242       continue;
1243     }
1244
1245     if (strcmp(*argv, "-pidfile") == 0) {
1246       NEXT_ARG;
1247       CHECK_ARGC;
1248
1249       cnf->pidfile = *argv;
1250       continue;
1251     }
1252
1253     return -1;
1254   }
1255   return 0;
1256 }
1257
1258 /*
1259  * Local Variables:
1260  * c-basic-offset: 2
1261  * indent-tabs-mode: nil
1262  * End:
1263  */