5f6ef6d977a18351e6d9acf647d8878c8b7ecaa1
[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 <unistd.h>
42 #include <signal.h>
43 #include <sys/stat.h>
44 #include <assert.h>
45 #include <fcntl.h>
46
47 #include "ipcalc.h"
48 #include "defs.h"
49 #include "olsr.h"
50 #include "log.h"
51 #include "scheduler.h"
52 #include "parser.h"
53 #include "generate_msg.h"
54 #include "plugin_loader.h"
55 #include "socket_parser.h"
56 #include "apm.h"
57 #include "net_os.h"
58 #include "build_msg.h"
59 #include "net_olsr.h"
60 #include "mid_set.h"
61 #include "mpr_selector_set.h"
62 #include "gateway.h"
63 #include "olsr_niit.h"
64
65 #if LINUX_POLICY_ROUTING
66 #include <linux/types.h>
67 #include <linux/rtnetlink.h>
68 #include "kernel_routes.h"
69
70 #endif
71
72 #ifdef WIN32
73 #include <winbase.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;
80 #else
81 static void olsr_shutdown(int) __attribute__ ((noreturn));
82 #endif
83
84 #if defined linux || __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
85 #define DEFAULT_LOCKFILE_PREFIX "/var/run/olsrd"
86 #endif
87
88 /*
89  * Local function prototypes
90  */
91 void olsr_reconfigure(int) __attribute__ ((noreturn));
92
93 static void print_usage(void);
94
95 #ifdef linux
96 static const char* ipip_default_name = "olsr_tunnel";
97 #endif
98
99 static int set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
100
101 static int olsr_process_arguments(int, char *[], struct olsrd_config *,
102     struct if_config_options *);
103
104 #ifndef WIN32
105 static char **olsr_argv;
106 #endif
107
108 static char
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.";
111
112 /* Data for OLSR locking */
113 #ifndef WIN32
114 static int lock_fd = 0;
115 #endif
116 static char lock_file_name[FILENAME_MAX];
117
118 /*
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.
123  *
124  * Additionally the lock can be killed by removing the
125  * locking file.
126  */
127 static void olsr_create_lock_file(void) {
128 #ifdef WIN32
129   HANDLE lck = CreateEvent(NULL, TRUE, FALSE, lock_file_name);
130   if (NULL == lck || ERROR_ALREADY_EXISTS == GetLastError()) {
131     if (NULL == lck) {
132       fprintf(stderr,
133           "Error, cannot create OLSR lock '%s'.\n",
134           lock_file_name);
135     } else {
136       CloseHandle(lck);
137       fprintf(stderr,
138           "Error, cannot aquire OLSR lock '%s'.\n"
139           "Another OLSR instance might be running.\n",
140           lock_file_name);
141     }
142     olsr_exit("", EXIT_FAILURE);
143   }
144 #else
145   struct flock lck;
146
147   /* create file for lock */
148   lock_fd = open(lock_file_name, O_WRONLY | O_CREAT, S_IRWXU);
149   if (lock_fd == 0) {
150     close(lock_fd);
151     fprintf(stderr,
152         "Error, cannot create OLSR lock '%s'.\n",
153         lock_file_name);
154     olsr_exit("", EXIT_FAILURE);
155   }
156
157   /* create exclusive lock for the whole file */
158   lck.l_type = F_WRLCK;
159   lck.l_whence = SEEK_SET;
160   lck.l_start = 0;
161   lck.l_len = 0;
162   lck.l_pid = 0;
163
164   if (fcntl(lock_fd, F_SETLK, &lck) == -1) {
165     close(lock_fd);
166     fprintf(stderr,
167         "Error, cannot aquire OLSR lock '%s'.\n"
168         "Another OLSR instance might be running.\n",
169         lock_file_name);
170     olsr_exit("", EXIT_FAILURE);
171   }
172 #endif
173   return;
174 }
175
176 /**
177  * loads a config file
178  * @return <0 if load failed, 0 otherwise
179  */
180 static int
181 olsrmain_load_config(char *file) {
182   struct stat statbuf;
183
184   if (stat(file, &statbuf) < 0) {
185     fprintf(stderr, "Could not find specified config file %s!\n%s\n\n",
186         file, strerror(errno));
187     return -1;
188   }
189
190   if (olsrd_parse_cnf(file) < 0) {
191     fprintf(stderr, "Error while reading config file %s!\n", file);
192     return -1;
193   }
194   return 0;
195 }
196
197 /**
198  * Main entrypoint
199  */
200
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;
206   int i;
207 #ifdef WIN32
208   WSADATA WsaData;
209   size_t len;
210 #endif
211
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);
219
220   debug_handle = stdout;
221 #ifndef WIN32
222   olsr_argv = argv;
223 #endif
224   setbuf(stdout, NULL);
225   setbuf(stderr, NULL);
226
227 #ifndef WIN32
228   /* Check if user is root */
229   if (geteuid()) {
230     fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
231     exit(EXIT_FAILURE);
232   }
233 #else
234   DisableIcmpRedirects();
235
236   if (WSAStartup(0x0202, &WsaData)) {
237     fprintf(stderr, "Could not initialize WinSock.\n");
238     olsr_exit(__func__, EXIT_FAILURE);
239   }
240 #endif
241
242   /* Open syslog */
243   olsr_openlog("olsrd");
244
245   printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n",
246       olsrd_version, build_date, build_host);
247
248   /* Using PID as random seed */
249   srandom(getpid());
250
251   /* Init widely used statics */
252   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
253
254   /*
255    * Set configfile name and
256    * check if a configfile name was given as parameter
257    */
258 #ifdef WIN32
259 #ifndef WINCE
260   GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
261 #else
262   conf_file_name[0] = 0;
263 #endif
264
265   len = strlen(conf_file_name);
266
267   if (len == 0 || conf_file_name[len - 1] != '\\')
268   conf_file_name[len++] = '\\';
269
270   strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
271 #else
272   strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
273 #endif
274
275   olsr_cnf = olsrd_get_default_cnf();
276   for (i=1; i < argc-1;) {
277     if (strcmp(argv[i], "-f") == 0) {
278       loadedConfig = true;
279
280       if (olsrmain_load_config(argv[i+1]) < 0) {
281         exit(EXIT_FAILURE);
282       }
283
284       if (i+2 < argc) {
285         memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1));
286       }
287       argc -= 2;
288     }
289     else {
290       i++;
291     }
292   }
293
294   /*
295    * set up configuration prior to processing commandline options
296    */
297   if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) {
298     loadedConfig = true;
299   }
300
301   if (!loadedConfig) {
302     olsrd_free_cnf(olsr_cnf);
303     olsr_cnf = olsrd_get_default_cnf();
304   }
305
306   default_ifcnf = get_default_if_config();
307   if (default_ifcnf == NULL) {
308     fprintf(stderr, "No default ifconfig found!\n");
309     exit(EXIT_FAILURE);
310   }
311
312   /* Initialize timers */
313   olsr_init_timers();
314
315   /*
316    * Process olsrd options.
317    */
318   if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) {
319     print_usage();
320     olsr_exit(__func__, EXIT_FAILURE);
321   }
322
323   /*
324    * Set configuration for command-line specified interfaces
325    */
326   set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
327
328   /* free the default ifcnf */
329   free(default_ifcnf);
330
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);
335   }
336
337   /*
338    * Establish file lock to prevent multiple instances
339    */
340   if (olsr_cnf->lock_file) {
341     strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name));
342   } else {
343     size_t l;
344 #ifdef DEFAULT_LOCKFILE_PREFIX
345     strscpy(lock_file_name, DEFAULT_LOCKFILE_PREFIX, sizeof(lock_file_name));
346 #else
347     strscpy(lock_file_name, conf_file_name, sizeof(lock_file_name));
348 #endif
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);
352   }
353
354   /*
355    * Print configuration
356    */
357   if (olsr_cnf->debug_level > 1) {
358     olsrd_print_cnf(olsr_cnf);
359   }
360 #ifndef WIN32
361   /* Disable redirects globally */
362   disable_redirects_global(olsr_cnf->ip_version);
363 #endif
364
365   /*
366    * socket for ioctl calls
367    */
368   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
369   if (olsr_cnf->ioctl_s < 0) {
370 #ifndef WIN32
371     olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
372 #endif
373     olsr_exit(__func__, 0);
374   }
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);
380   }
381   fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
382 #endif
383
384   /*
385    * create routing socket
386    */
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);
392   }
393 #endif
394
395 #if defined linux
396   /* initialize niit if index */
397   if (olsr_cnf->use_niit) {
398     olsr_init_niit();
399   }
400 #endif
401
402   /* Init empty TC timer */
403   set_empty_tc_timer(GET_TIMESTAMP(0));
404
405   /*
406    *enable ip forwarding on host
407    */
408   enable_ip_forwarding(olsr_cnf->ip_version);
409
410   /* Initialize parser */
411   olsr_init_parser();
412
413   /* Initialize route-exporter */
414   olsr_init_export_route();
415
416   /* Initialize message sequencnumber */
417   init_msg_seqno();
418
419   /* Initialize dynamic willingness calculation */
420   olsr_init_willingness();
421
422   /*
423    *Set up willingness/APM
424    */
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);
428
429       olsr_syslog(OLSR_LOG_ERR,
430           "Could not read APM info - setting default willingness(%d)\n",
431           WILL_DEFAULT);
432
433       olsr_cnf->willingness_auto = 0;
434       olsr_cnf->willingness = WILL_DEFAULT;
435     } else {
436       olsr_cnf->willingness = olsr_calculate_willingness();
437
438       OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, olsr_cnf->will_int);
439     }
440   }
441
442   /* Initialize net */
443   init_net();
444
445   /* Initializing networkinterfaces */
446   if (!ifinit()) {
447     if (olsr_cnf->allow_no_interfaces) {
448       fprintf(
449           stderr,
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);
452     } else {
453       fprintf(stderr, "No interfaces detected!\nBailing out!\n");
454       olsr_exit(__func__, EXIT_FAILURE);
455     }
456   }
457
458   olsr_do_startup_sleep();
459
460   /* Print heartbeat to stdout */
461
462 #if !defined WINCE
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);
466   }
467 #endif
468
469   /* Initialize the IPC socket */
470
471   if (olsr_cnf->ipc_connections > 0) {
472     ipc_init();
473   }
474   /* Initialisation of different tables to be used. */
475   olsr_init_tables();
476
477   /* daemon mode */
478 #ifndef WIN32
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));
483       exit(EXIT_FAILURE);
484     }
485   }
486 #endif
487
488   /*
489    * Create locking file for olsrd, will be cleared after olsrd exits
490    */
491   olsr_create_lock_file();
492
493   /* Load plugins */
494   olsr_load_plugins();
495
496   OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
497
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 );
503
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);
517
518     deactivate_spoof(TUNL_BASE, &olsr_cnf->ipip_base_if, AF_INET );//ipip is an ipv4 tunnel
519
520     if (!olsr_cnf->smart_gw_active) 
521     {
522       printf("disabled smart Gateway! (ipip tunnels not useable for olsrd on this host)");
523     }
524     else {
525       struct olsr_if *cfg_if;
526
527       //need sanity checks for routintg tables
528
529       //question: if rttable_default unconfigured, determine one?
530       //yes use 112
531       //same with smartTable (113)
532
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?
536
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 ...
539
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.
543
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)
547
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;
556
557 //!!?? just a test
558 olsr_cnf->rttable_rule=65531;
559
560 printf("\nMain Table is %i prio %i", olsr_cnf->rttable, olsr_cnf->rttable_rule);
561
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);
566       }
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);
573     }
574   }
575
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);
579   }
580
581   /* Create rtnetlink socket to listen on interface change events RTMGRP_LINK and RTMGRP_IPV4_ROUTE */
582   //todo listen on tunl0 events aswell
583
584 #if LINUX_RTNETLINK_LISTEN
585   rtnetlink_register_socket(RTMGRP_LINK);
586 #endif /*LINUX_RTNETLINK_LISTEN*/
587
588 #endif
589
590 #if defined linux
591   /* trigger gateway selection */
592   if (olsr_cnf->smart_gw_active) {
593     olsr_trigger_inetgw_startup();
594   }
595
596   /* trigger niit static route setup */
597   if (olsr_cnf->use_niit) {
598     olsr_setup_niit_routes();
599   }
600 #endif
601
602   /* Start syslog entry */
603   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
604
605   /*
606    *signal-handlers
607    */
608
609   /* ctrl-C and friends */
610 #ifdef WIN32
611 #ifndef WINCE
612   SetConsoleCtrlHandler(SignalHandler, true);
613 #endif
614 #else
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);
623 #endif
624
625   link_changes = false;
626
627   /* Starting scheduler */
628   olsr_scheduler();
629
630   /* Like we're ever going to reach this ;-) */
631   return 1;
632 } /* main */
633
634 /**
635  * Reconfigure olsrd. Currently kind of a hack...
636  *
637  *@param signal the signal that triggered this callback
638  */
639 #ifndef WIN32
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
643    */
644   olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
645   if (!olsr_cnf->no_fork) {
646     if (!fork()) {
647       int i;
648       sigset_t sigs;
649       /* New process */
650       sleep(3);
651       sigemptyset(&sigs);
652       sigaddset(&sigs, SIGHUP);
653       sigprocmask(SIG_UNBLOCK, &sigs, NULL);
654       for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
655         close(i);
656       }
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],
661           strerror(errno));
662     } else {
663       olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING!\n");
664     }
665   }
666   olsr_shutdown(0);
667 }
668 #endif
669
670 static void olsr_shutdown_messages(void) {
671   struct interface *ifn;
672
673   /* send TC reset */
674   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
675     /* clean output buffer */
676     net_output(ifn);
677
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);
682     }
683     else {
684       generate_tc(ifn);
685       generate_hello(ifn);
686     }
687     net_output(ifn);
688   }
689 }
690
691 /**
692  *Function called at shutdown. Signal handler
693  *
694  * @param signal the signal that triggered this call
695  */
696 #ifdef WIN32
697 int __stdcall
698 SignalHandler(unsigned long signo)
699 #else
700 static void olsr_shutdown(int signo __attribute__ ((unused)))
701 #endif
702 {
703   struct interface *ifn;
704   int exit_value;
705
706   OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
707
708 #ifdef WIN32
709   OLSR_PRINTF(1, "Waiting for the scheduler to stop.\n");
710
711   olsr_win32_end_request = TRUE;
712
713   while (!olsr_win32_end_flag)
714   Sleep(100);
715
716   OLSR_PRINTF(1, "Scheduler stopped.\n");
717 #endif
718
719   /* clear all links and send empty hellos/tcs */
720   olsr_reset_all_links();
721
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;
726   }
727   increase_local_ansn();
728
729   /* send first shutdown message burst */
730   olsr_shutdown_messages();
731
732   /* delete all routes */
733   olsr_delete_all_kernel_routes();
734
735 #if defined linux
736   /* trigger gateway selection */
737   if (olsr_cnf->smart_gw_active) {
738     // TODO: cleanup smart gateway routes
739   }
740
741   /* trigger niit static route cleanup */
742   if (olsr_cnf->use_niit) {
743     olsr_cleanup_niit_routes();
744   }
745 #endif
746
747   /* send second shutdown message burst */
748   olsr_shutdown_messages();
749
750   /* now try to cleanup the rest of the mess */
751   olsr_delete_all_tc_entries();
752
753   olsr_delete_all_mid_entries();
754
755   olsr_destroy_parser();
756
757   OLSR_PRINTF(1, "Closing sockets...\n");
758
759   /* front-end IPC socket */
760   if (olsr_cnf->ipc_connections > 0) {
761     shutdown_ipc();
762   }
763
764   /* OLSR sockets */
765   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
766     close(ifn->olsr_socket);
767     close(ifn->send_socket);
768   }
769
770   /* Closing plug-ins */
771   olsr_close_plugins();
772
773   /* Reset network settings */
774   restore_settings(olsr_cnf->ip_version);
775
776   /* ioctl socket */
777   close(olsr_cnf->ioctl_s);
778
779 #if LINUX_POLICY_ROUTING
780
781   /*delete smartgw tunnel if it index is known*/
782   if (olsr_cnf->ipip_if_index) olsr_del_tunl();
783
784   /*!!?? we should take down the tunl0 interface*/
785
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);
791     }
792   }
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);
797
798   /*tunl0*/
799   if (olsr_cnf->ipip_base_orig_down) {
800     printf("\ntakig down tunl0 again");
801     olsr_if_set_state(TUNL_BASE, false);
802   }
803
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);
807   }
808
809   close(olsr_cnf->rtnl_s);
810
811   /*rp_filter*/
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
813 #endif
814
815 /*!!?? we need to reset rp_filter of conf/all aswell, so we really need a new rp_filter reset function*/
816
817 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
818   /* routing socket */
819   close(olsr_cnf->rts);
820 #endif
821
822   /* Free cookies and memory pools attached. */
823   OLSR_PRINTF(0, "Free all memory...\n");
824   olsr_delete_all_cookies();
825
826   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
827
828   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
829
830   exit_value = olsr_cnf->exit_value;
831   olsrd_free_cnf(olsr_cnf);
832
833   exit(exit_value);
834 }
835
836 /**
837  * Print the command line usage
838  */
839 static void print_usage(void) {
840
841   fprintf(
842       stderr,
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");
851 }
852
853 /**
854  * Sets the provided configuration on all unconfigured
855  * interfaces
856  *
857  * @param ifs a linked list of interfaces to check and possible update
858  * @param cnf the default configuration to set on unconfigured interfaces
859  */
860 int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
861   int changes = 0;
862
863   while (ifs) {
864     if (ifs->cnf == NULL) {
865       ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
866           "Set default config");
867       *ifs->cnf = *cnf;
868       changes++;
869     }
870     ifs = ifs->next;
871   }
872   return changes;
873 }
874
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"); \
879       } else { \
880       argv--; \
881       fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
882      } \
883      olsr_exit(__func__, EXIT_FAILURE); \
884      } } while (0)
885
886 /**
887  * Process command line arguments passed to olsrd
888  *
889  */
890 static int olsr_process_arguments(int argc, char *argv[],
891     struct olsrd_config *cnf, struct if_config_options *ifcnf) {
892   while (argc > 1) {
893     NEXT_ARG;
894 #ifdef WIN32
895     /*
896      *Interface list
897      */
898     if (strcmp(*argv, "-int") == 0) {
899       ListInterfaces();
900       exit(0);
901     }
902 #endif
903
904     /*
905      *Configfilename
906      */
907     if (strcmp(*argv, "-f") == 0) {
908       fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
909       olsr_exit(__func__, EXIT_FAILURE);
910     }
911
912     /*
913      *Use IP version 6
914      */
915     if (strcmp(*argv, "-ipv6") == 0) {
916       cnf->ip_version = AF_INET6;
917       continue;
918     }
919
920     /*
921      *Broadcast address
922      */
923     if (strcmp(*argv, "-bcast") == 0) {
924       struct in_addr in;
925       NEXT_ARG;
926       CHECK_ARGC;
927
928       if (inet_aton(*argv, &in) == 0) {
929         printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
930         continue;
931       }
932       memcpy(&ifcnf->ipv4_multicast.v4, &in.s_addr, sizeof(ifcnf->ipv4_multicast.v4));
933       continue;
934     }
935
936     /*
937      * Set LQ level
938      */
939     if (strcmp(*argv, "-lql") == 0) {
940       int tmp_lq_level;
941       NEXT_ARG;
942       CHECK_ARGC;
943
944       /* Sanity checking is done later */
945       sscanf(*argv, "%d", &tmp_lq_level);
946       olsr_cnf->lq_level = tmp_lq_level;
947       continue;
948     }
949
950     /*
951      * Set LQ winsize
952      */
953     if (strcmp(*argv, "-lqa") == 0) {
954       float tmp_lq_aging;
955       NEXT_ARG;
956       CHECK_ARGC;
957
958       sscanf(*argv, "%f", &tmp_lq_aging);
959
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);
964       }
965       olsr_cnf->lq_aging = tmp_lq_aging;
966       continue;
967     }
968
969     /*
970      * Set NAT threshold
971      */
972     if (strcmp(*argv, "-lqnt") == 0) {
973       float tmp_lq_nat_thresh;
974       NEXT_ARG;
975       CHECK_ARGC;
976
977       sscanf(*argv, "%f", &tmp_lq_nat_thresh);
978
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);
983       }
984       olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
985       continue;
986     }
987
988     /*
989      * Enable additional debugging information to be logged.
990      */
991     if (strcmp(*argv, "-d") == 0) {
992       NEXT_ARG;
993       CHECK_ARGC;
994
995       sscanf(*argv, "%d", &cnf->debug_level);
996       continue;
997     }
998
999     /*
1000      * Interfaces to be used by olsrd.
1001      */
1002     if (strcmp(*argv, "-i") == 0) {
1003       NEXT_ARG;
1004       CHECK_ARGC;
1005
1006       if (*argv[0] == '-') {
1007         fprintf(stderr, "You must provide an interface label!\n");
1008         olsr_exit(__func__, EXIT_FAILURE);
1009       }
1010       printf("Queuing if %s\n", *argv);
1011       queue_if(*argv, false);
1012
1013       while ((argc - 1) && (argv[1][0] != '-')) {
1014         NEXT_ARG;
1015         printf("Queuing if %s\n", *argv);
1016         queue_if(*argv, false);
1017       }
1018
1019       continue;
1020     }
1021     /*
1022      * Set the hello interval to be used by olsrd.
1023      *
1024      */
1025     if (strcmp(*argv, "-hint") == 0) {
1026       NEXT_ARG;
1027       CHECK_ARGC;
1028       sscanf(*argv, "%f", &ifcnf->hello_params.emission_interval);
1029       ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval
1030           * 3;
1031       continue;
1032     }
1033
1034     /*
1035      * Set the HNA interval to be used by olsrd.
1036      *
1037      */
1038     if (strcmp(*argv, "-hnaint") == 0) {
1039       NEXT_ARG;
1040       CHECK_ARGC;
1041       sscanf(*argv, "%f", &ifcnf->hna_params.emission_interval);
1042       ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
1043       continue;
1044     }
1045
1046     /*
1047      * Set the MID interval to be used by olsrd.
1048      *
1049      */
1050     if (strcmp(*argv, "-midint") == 0) {
1051       NEXT_ARG;
1052       CHECK_ARGC;
1053       sscanf(*argv, "%f", &ifcnf->mid_params.emission_interval);
1054       ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
1055       continue;
1056     }
1057
1058     /*
1059      * Set the tc interval to be used by olsrd.
1060      *
1061      */
1062     if (strcmp(*argv, "-tcint") == 0) {
1063       NEXT_ARG;
1064       CHECK_ARGC;
1065       sscanf(*argv, "%f", &ifcnf->tc_params.emission_interval);
1066       ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
1067       continue;
1068     }
1069
1070     /*
1071      * Set the polling interval to be used by olsrd.
1072      */
1073     if (strcmp(*argv, "-T") == 0) {
1074       NEXT_ARG;
1075       CHECK_ARGC;
1076       sscanf(*argv, "%f", &cnf->pollrate);
1077       continue;
1078     }
1079
1080     /*
1081      * Should we display the contents of packages beeing sent?
1082      */
1083     if (strcmp(*argv, "-dispin") == 0) {
1084       parser_set_disp_pack_in(true);
1085       continue;
1086     }
1087
1088     /*
1089      * Should we display the contents of incoming packages?
1090      */
1091     if (strcmp(*argv, "-dispout") == 0) {
1092       net_set_disp_pack_out(true);
1093       continue;
1094     }
1095
1096     /*
1097      * Should we set up and send on a IPC socket for the front-end?
1098      */
1099     if (strcmp(*argv, "-ipc") == 0) {
1100       cnf->ipc_connections = 1;
1101       continue;
1102     }
1103
1104     /*
1105      * IPv6 multicast addr
1106      */
1107     if (strcmp(*argv, "-multi") == 0) {
1108       struct in6_addr in6;
1109       NEXT_ARG;
1110       CHECK_ARGC;
1111       if (inet_pton(AF_INET6, *argv, &in6) <= 0) {
1112         fprintf(stderr, "Failed converting IP address %s\n", *argv);
1113         exit(EXIT_FAILURE);
1114       }
1115
1116       memcpy(&ifcnf->ipv6_multicast, &in6, sizeof(struct in6_addr));
1117
1118       continue;
1119     }
1120
1121     /*
1122      * Host emulation
1123      */
1124     if (strcmp(*argv, "-hemu") == 0) {
1125       struct in_addr in;
1126       struct olsr_if *ifa;
1127
1128       NEXT_ARG;
1129       CHECK_ARGC;
1130       if (inet_pton(AF_INET, *argv, &in) <= 0) {
1131         fprintf(stderr, "Failed converting IP address %s\n", *argv);
1132         exit(EXIT_FAILURE);
1133       }
1134       /* Add hemu interface */
1135
1136       ifa = queue_if("hcif01", true);
1137
1138       if (!ifa)
1139         continue;
1140
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;
1145
1146       continue;
1147     }
1148
1149     /*
1150      * Delete possible default GWs
1151      */
1152     if (strcmp(*argv, "-delgw") == 0) {
1153       olsr_cnf->del_gws = true;
1154       continue;
1155     }
1156
1157     if (strcmp(*argv, "-nofork") == 0) {
1158       cnf->no_fork = true;
1159       continue;
1160     }
1161
1162     return -1;
1163   }
1164   return 0;
1165 }
1166
1167 /*
1168  * Local Variables:
1169  * c-basic-offset: 2
1170  * indent-tabs-mode: nil
1171  * End:
1172  */