* activate -Wshadow
[olsrd.git] / src / main.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(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 <errno.h>
46 #include <sys/times.h>
47
48 #include "ipcalc.h"
49 #include "defs.h"
50 #include "olsr.h"
51 #include "log.h"
52 #include "scheduler.h"
53 #include "parser.h"
54 #include "generate_msg.h"
55 #include "plugin_loader.h"
56 #include "socket_parser.h"
57 #include "apm.h"
58 #include "net_os.h"
59 #include "build_msg.h"
60 #include "net_olsr.h"
61 #include "ipc_frontend.h"
62 #include "common/string.h"
63
64 #if LINUX_POLICY_ROUTING
65 #include <linux/types.h>
66 #include <linux/rtnetlink.h>
67 #include <fcntl.h>
68 #endif
69
70 #ifdef WIN32
71 #define close(x) closesocket(x)
72 int __stdcall SignalHandler(unsigned long signo) __attribute__((noreturn));
73 void ListInterfaces(void);
74 void DisableIcmpRedirects(void);
75 olsr_bool olsr_win32_end_request = OLSR_FALSE;
76 olsr_bool olsr_win32_end_flag = OLSR_FALSE;
77 #else
78 static void
79 olsr_shutdown(int) __attribute__((noreturn));
80 #endif
81
82 /*
83  * Local function prototypes
84  */
85 void
86 olsr_reconfigure(int) __attribute__((noreturn));
87
88 static void
89 print_usage(void);
90
91 static int
92 set_default_ifcnfs(struct olsr_if *, struct if_config_options *);
93
94 static int
95 olsr_process_arguments(int, char *[], 
96                        struct olsrd_config *, 
97                        struct if_config_options *);
98
99 #ifndef WIN32
100 static char **olsr_argv;
101 #endif
102
103 static char copyright_string[] __attribute__((unused)) = "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org) All rights reserved.";
104
105
106 /**
107  * Main entrypoint
108  */
109
110 int
111 main(int argc, char *argv[])
112 {
113   struct if_config_options *default_ifcnf;
114   char conf_file_name[FILENAME_MAX];
115   struct ipaddr_str buf;
116 #ifdef WIN32
117   WSADATA WsaData;
118   size_t len;
119 #endif
120
121   /* paranoia checks */
122   assert(sizeof(olsr_u8_t) == 1);
123   assert(sizeof(olsr_u16_t) == 2);
124   assert(sizeof(olsr_u32_t) == 4);
125   assert(sizeof(olsr_8_t) == 1);
126   assert(sizeof(olsr_16_t) == 2);
127   assert(sizeof(olsr_32_t) == 4);
128
129   debug_handle = stdout;
130 #ifndef WIN32
131   olsr_argv = argv;
132 #endif
133   setbuf(stdout, NULL);
134   setbuf(stderr, NULL);
135
136 #ifndef WIN32
137   /* Check if user is root */
138   if(geteuid())
139     {
140       fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
141       exit(EXIT_FAILURE);
142     }
143 #else
144   DisableIcmpRedirects();
145
146   if (WSAStartup(0x0202, &WsaData))
147     {
148       fprintf(stderr, "Could not initialize WinSock.\n");
149       olsr_exit(__func__, EXIT_FAILURE);
150     }
151 #endif
152
153   /* Open syslog */
154   olsr_openlog("olsrd");
155
156   /* Grab initial timestamp */
157   now_times = olsr_times();
158     
159   printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n", 
160          olsrd_version, 
161          build_date,
162          build_host);
163     
164   /* Using PID as random seed */
165   srandom(getpid());
166
167   /* Init widely used statics */
168   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
169
170   /*
171    * Set configfile name and
172    * check if a configfile name was given as parameter
173    */
174 #ifdef WIN32
175 #ifndef WINCE
176   GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
177 #else
178   conf_file_name[0] = 0;
179 #endif
180   
181   len = strlen(conf_file_name);
182   
183   if (len == 0 || conf_file_name[len - 1] != '\\')
184     conf_file_name[len++] = '\\';
185   
186   strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
187 #else
188   strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
189 #endif
190
191   if ((argc > 1) && (strcmp(argv[1], "-f") == 0)) 
192     {
193       struct stat statbuf;
194
195       argv++; argc--;
196       if(argc == 1)
197         {
198           fprintf(stderr, "You must provide a filename when using the -f switch!\n");
199           exit(EXIT_FAILURE);
200         }
201
202       if (stat(argv[1], &statbuf) < 0)
203         {
204           fprintf(stderr, "Could not find specified config file %s!\n%s\n\n", argv[1], strerror(errno));
205           exit(EXIT_FAILURE);
206         }
207                  
208       strscpy(conf_file_name, argv[1], sizeof(conf_file_name));
209       argv++; argc--;
210
211     }
212
213   /*
214    * set up configuration prior to processing commandline options
215    */
216   if(NULL == (olsr_cnf = olsrd_parse_cnf(conf_file_name)))
217     {
218       printf("Using default config values(no configfile)\n");
219       olsr_cnf = olsrd_get_default_cnf();
220     }
221
222   default_ifcnf = get_default_if_config();
223   if (default_ifcnf == NULL) {
224     fprintf(stderr, "No default ifconfig found!\n");
225     exit(EXIT_FAILURE);
226   }
227
228   /* Initialize tick resolution */
229 #ifndef WIN32
230   olsr_cnf->system_tick_divider = 1000/sysconf(_SC_CLK_TCK);
231 #else
232   olsr_cnf->system_tick_divider = 1;
233 #endif
234
235   /* Initialize timers */
236   olsr_init_timers();
237
238   /*
239    * Process olsrd options.
240    */
241   if(olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0)
242     {
243       print_usage();
244       olsr_exit(__func__, EXIT_FAILURE);
245     }
246
247   /*
248    * Set configuration for command-line specified interfaces
249    */
250   set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
251
252   /* free the default ifcnf */
253   free(default_ifcnf);
254
255   /* Sanity check configuration */
256   if(olsrd_sanity_check_cnf(olsr_cnf) < 0)
257     {
258       fprintf(stderr, "Bad configuration!\n");
259       olsr_exit(__func__, EXIT_FAILURE);      
260     }
261
262   /*
263    * Print configuration 
264    */
265   if(olsr_cnf->debug_level > 1) {
266     olsrd_print_cnf(olsr_cnf);
267   }
268 #ifndef WIN32
269   /* Disable redirects globally */
270   disable_redirects_global(olsr_cnf->ip_version);
271 #endif
272
273   /*
274 <<<<<<< local
275    * socket for ioctl calls
276 =======
277    *socket for ioctl calls
278 >>>>>>> other
279    */
280   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
281   if (olsr_cnf->ioctl_s < 0) {
282     olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
283     olsr_exit(__func__, 0);
284   }
285
286 #if LINUX_POLICY_ROUTING
287   olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
288   if (olsr_cnf->rtnl_s < 0) {
289     olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
290     olsr_exit(__func__, 0);
291   }
292   fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
293 #endif
294
295 /*
296  * create routing socket
297  */
298 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
299   olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
300   if (olsr_cnf->rts < 0) {
301     olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
302     olsr_exit(__func__, 0);
303   }
304 #endif
305
306   /*
307    *enable ip forwarding on host
308    */
309   enable_ip_forwarding(olsr_cnf->ip_version);
310
311   /* Initialize parser */
312   olsr_init_parser();
313
314   /* Initialize route-exporter */
315   olsr_init_export_route();
316
317   /* Initialize message sequencnumber */
318   init_msg_seqno();
319
320   /* Initialize dynamic willingness calculation */
321   olsr_init_willingness();
322
323   /*
324    *Set up willingness/APM
325    */
326   if(olsr_cnf->willingness_auto)
327     {
328       if(apm_init() < 0)
329         {
330           OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
331
332           olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
333
334           olsr_cnf->willingness_auto = 0;
335           olsr_cnf->willingness = WILL_DEFAULT;
336         }
337       else
338         {
339           olsr_cnf->willingness = olsr_calculate_willingness();
340
341           OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, olsr_cnf->will_int);
342         }
343     }
344
345   /* Initialize net */
346   init_net();
347
348   /* Initializing networkinterfaces */
349   if(!ifinit())
350     {
351       if(olsr_cnf->allow_no_interfaces)
352         {
353           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");
354           sleep(5);
355         }
356       else
357         {
358           fprintf(stderr, "No interfaces detected!\nBailing out!\n");
359           olsr_exit(__func__, EXIT_FAILURE);
360         }
361     }
362
363   /* Print heartbeat to stdout */
364
365 #if !defined WINCE
366   if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
367     olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC,
368                      &generate_stdout_pulse, NULL, 0);
369   }
370 #endif
371
372   /* Initialize the IPC socket */
373
374   if (olsr_cnf->ipc_connections > 0) {
375       ipc_init();
376   }
377   /* Initialisation of different tables to be used.*/
378   olsr_init_tables();
379
380   /* daemon mode */
381 #ifndef WIN32
382   if(olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) {
383     printf("%s detaching from the current process...\n", olsrd_version);
384     if (daemon(0, 0) < 0) {
385       printf("daemon(3) failed: %s\n", strerror(errno));
386       exit(EXIT_FAILURE);
387     }
388   }
389 #endif
390
391   /* Load plugins */
392   olsr_load_plugins();
393
394   OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
395
396   /* Start syslog entry */
397   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
398
399   /*
400    *signal-handlers
401    */
402
403   /* ctrl-C and friends */
404 #ifdef WIN32
405 #ifndef WINCE
406   SetConsoleCtrlHandler(SignalHandler, OLSR_TRUE);
407 #endif
408 #else
409   signal(SIGHUP, olsr_reconfigure);  
410   signal(SIGINT,  olsr_shutdown);
411   signal(SIGQUIT, olsr_shutdown);
412   signal(SIGILL,  olsr_shutdown);
413   signal(SIGABRT, olsr_shutdown);
414 //  signal(SIGSEGV, olsr_shutdown);
415   signal(SIGTERM, olsr_shutdown);
416   signal(SIGPIPE, SIG_IGN);
417 #endif
418
419   link_changes = OLSR_FALSE;
420
421   /* Starting scheduler */
422   olsr_scheduler();
423
424   /* Like we're ever going to reach this ;-) */
425   return 1;
426 } /* main */
427
428
429
430 /**
431  * Reconfigure olsrd. Currently kind of a hack...
432  *
433  *@param signal the signal that triggered this callback
434  */
435 #ifndef WIN32
436 void
437 olsr_reconfigure(int signo __attribute__((unused)))
438 {
439   if(!fork())
440     {
441       /* New process */
442       sleep(3);
443       printf("Restarting %s\n", olsr_argv[0]);
444       execv(olsr_argv[0], olsr_argv);
445     }
446   olsr_shutdown(0);
447
448   printf("RECONFIGURING!\n");
449 }
450 #endif
451
452
453 /**
454  *Function called at shutdown. Signal handler
455  *
456  * @param signal the signal that triggered this call
457  */
458 #ifdef WIN32
459 int __stdcall
460 SignalHandler(unsigned long signo)
461 #else
462 static void
463 olsr_shutdown(int signo USED_ONLY_FOR_DEBUG)
464 #endif
465 {
466   struct interface *ifn;
467
468   OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
469
470 #ifdef WIN32
471   OLSR_PRINTF(1, "Waiting for the scheduler to stop.\n");
472
473   olsr_win32_end_request = TRUE;
474
475   while (!olsr_win32_end_flag)
476     Sleep(100);
477
478   OLSR_PRINTF(1, "Scheduler stopped.\n");
479 #endif
480
481   olsr_delete_all_kernel_routes();
482
483   OLSR_PRINTF(1, "Closing sockets...\n");
484
485   /* front-end IPC socket */
486   if (olsr_cnf->ipc_connections > 0) {
487     shutdown_ipc();
488   }
489
490   /* OLSR sockets */
491   for (ifn = ifnet; ifn; ifn = ifn->int_next) 
492     close(ifn->olsr_socket);
493
494   /* Closing plug-ins */
495   olsr_close_plugins();
496
497   /* Reset network settings */
498   restore_settings(olsr_cnf->ip_version);
499
500   /* ioctl socket */
501   close(olsr_cnf->ioctl_s);
502
503 #if LINUX_POLICY_ROUTING
504   close(olsr_cnf->rtnl_s);
505 #endif
506
507 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
508   /* routing socket */
509   close(olsr_cnf->rts);
510 #endif
511
512   /* Free cookies and memory pools attached. */
513   olsr_delete_all_cookies();
514
515   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
516
517   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
518
519   exit(olsr_cnf->exit_value);
520 }
521
522 /**
523  * Print the command line usage
524  */
525 static void
526 print_usage(void)
527 {
528
529   fprintf(stderr,
530           "An error occured somwhere between your keyboard and your chair!\n"
531           "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n"
532           "  [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n"
533           "  [-lql <LQ level>] [-lqw <LQ winsize>] [-lqnt <nat threshold>]\n"
534           "  [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n"
535           "  [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
536           "  [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
537           "  [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>]\n"
538           "  [-lql <LQ level>] [-lqa <LQ aging factor>]\n");
539 }
540
541
542 /**
543  * Sets the provided configuration on all unconfigured
544  * interfaces
545  *
546  * @param ifs a linked list of interfaces to check and possible update
547  * @param cnf the default configuration to set on unconfigured interfaces
548  */
549 int
550 set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf)
551 {
552   int changes = 0;
553
554   while(ifs)
555     {
556       if(ifs->cnf == NULL)
557         {
558           ifs->cnf = olsr_malloc(sizeof(struct if_config_options), "Set default config");
559           *ifs->cnf = *cnf;
560           changes++;
561         }
562       ifs = ifs->next;
563     }
564   return changes;
565 }
566
567
568 #define NEXT_ARG do { argv++;argc--; } while (0)
569 #define CHECK_ARGC do { if(!argc) { \
570       if((argc - 1) == 1){ \
571       fprintf(stderr, "Error parsing command line options!\n"); \
572       } else { \
573       argv--; \
574       fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
575      } \
576      olsr_exit(__func__, EXIT_FAILURE); \
577      } } while (0)
578
579 /**
580  * Process command line arguments passed to olsrd
581  *
582  */
583 static int
584 olsr_process_arguments(int argc, char *argv[], 
585                        struct olsrd_config *cnf, 
586                        struct if_config_options *ifcnf)
587 {
588   while (argc > 1)
589     {
590       NEXT_ARG;
591 #ifdef WIN32
592       /*
593        *Interface list
594        */
595       if (strcmp(*argv, "-int") == 0)
596         {
597           ListInterfaces();
598           exit(0);
599         }
600 #endif
601
602       /*
603        *Configfilename
604        */
605       if(strcmp(*argv, "-f") == 0) 
606         {
607           fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
608           olsr_exit(__func__, EXIT_FAILURE);
609         }
610
611       /*
612        *Use IP version 6
613        */
614       if(strcmp(*argv, "-ipv6") == 0) 
615         {
616           cnf->ip_version = AF_INET6;
617           continue;
618         }
619
620       /*
621        *Broadcast address
622        */
623       if(strcmp(*argv, "-bcast") == 0) 
624         {
625           struct in_addr in;
626           NEXT_ARG;
627           CHECK_ARGC;
628
629           if (inet_aton(*argv, &in) == 0)
630             {
631               printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
632               continue;
633             }
634           memcpy(&ifcnf->ipv4_broadcast.v4, &in.s_addr, sizeof(olsr_u32_t));  
635           continue;
636         }
637
638       /*
639        * Set LQ level
640        */
641       if (strcmp(*argv, "-lql") == 0) 
642         {
643           int tmp_lq_level;
644           NEXT_ARG;
645           CHECK_ARGC;
646           
647           /* Sanity checking is done later */
648           sscanf(*argv, "%d", &tmp_lq_level);
649           olsr_cnf->lq_level = tmp_lq_level;
650           continue;
651         }
652
653       /*
654        * Set LQ winsize
655        */
656       if (strcmp(*argv, "-lqa") == 0) 
657         {
658           float tmp_lq_aging;
659           NEXT_ARG;
660           CHECK_ARGC;
661           
662           sscanf(*argv, "%f", &tmp_lq_aging);
663
664           if(tmp_lq_aging < MIN_LQ_AGING || tmp_lq_aging > MAX_LQ_AGING)
665             {
666               printf("LQ aging factor %f not allowed. Range [%f-%f]\n", 
667                      tmp_lq_aging, MIN_LQ_AGING, MAX_LQ_AGING);
668               olsr_exit(__func__, EXIT_FAILURE);
669             }
670           olsr_cnf->lq_aging = tmp_lq_aging;
671           continue;
672         }
673       
674       /*
675        * Set NAT threshold
676        */
677       if (strcmp(*argv, "-lqnt") == 0) 
678         {
679           float tmp_lq_nat_thresh;
680           NEXT_ARG;
681           CHECK_ARGC;
682
683           sscanf(*argv,"%f", &tmp_lq_nat_thresh);
684
685           if(tmp_lq_nat_thresh < 0.1 || tmp_lq_nat_thresh > 1.0)
686             {
687               printf("NAT threshold %f not allowed. Range [%f-%f]\n", 
688                      tmp_lq_nat_thresh, 0.1, 1.0);
689               olsr_exit(__func__, EXIT_FAILURE);
690             }
691           olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
692           continue;
693         }
694
695       /*
696        * Enable additional debugging information to be logged.
697        */
698       if (strcmp(*argv, "-d") == 0) 
699         {
700           NEXT_ARG;
701           CHECK_ARGC;
702
703           sscanf(*argv,"%d", &cnf->debug_level);
704           continue;
705         }
706
707                 
708       /*
709        * Interfaces to be used by olsrd.
710        */
711       if (strcmp(*argv, "-i") == 0) 
712         {
713           NEXT_ARG;
714           CHECK_ARGC;
715
716           if(*argv[0] == '-')
717             {
718               fprintf(stderr, "You must provide an interface label!\n");
719               olsr_exit(__func__, EXIT_FAILURE);
720             }
721           printf("Queuing if %s\n", *argv);
722           queue_if(*argv, OLSR_FALSE);
723
724           while((argc - 1) && (argv[1][0] != '-'))
725             {
726               NEXT_ARG;
727               printf("Queuing if %s\n", *argv);
728               queue_if(*argv, OLSR_FALSE);
729             }
730
731           continue;
732         }
733       /*
734        * Set the hello interval to be used by olsrd.
735        * 
736        */
737       if (strcmp(*argv, "-hint") == 0) 
738         {
739           NEXT_ARG;
740           CHECK_ARGC;
741           sscanf(*argv,"%f", &ifcnf->hello_params.emission_interval);
742           ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval * 3;
743           continue;
744         }
745
746       /*
747        * Set the HNA interval to be used by olsrd.
748        * 
749        */
750       if (strcmp(*argv, "-hnaint") == 0) 
751         {
752           NEXT_ARG;
753           CHECK_ARGC;
754           sscanf(*argv,"%f", &ifcnf->hna_params.emission_interval);
755           ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
756           continue;
757         }
758
759       /*
760        * Set the MID interval to be used by olsrd.
761        * 
762        */
763       if (strcmp(*argv, "-midint") == 0) 
764         {
765           NEXT_ARG;
766           CHECK_ARGC;
767           sscanf(*argv,"%f", &ifcnf->mid_params.emission_interval);
768           ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
769           continue;
770         }
771
772       /*
773        * Set the tc interval to be used by olsrd.
774        * 
775        */
776       if (strcmp(*argv, "-tcint") == 0) 
777         {
778           NEXT_ARG;
779           CHECK_ARGC;
780           sscanf(*argv,"%f", &ifcnf->tc_params.emission_interval);
781           ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
782           continue;
783         }
784
785       /*
786        * Set the polling interval to be used by olsrd.
787        */
788       if (strcmp(*argv, "-T") == 0) 
789         {
790           NEXT_ARG;
791           CHECK_ARGC;
792           sscanf(*argv,"%f",&cnf->pollrate);
793           continue;
794         }
795
796
797       /*
798        * Should we display the contents of packages beeing sent?
799        */
800       if (strcmp(*argv, "-dispin") == 0) 
801         {
802           parser_set_disp_pack_in(OLSR_TRUE);
803           continue;
804         }
805
806       /*
807        * Should we display the contents of incoming packages?
808        */
809       if (strcmp(*argv, "-dispout") == 0) 
810         {
811           net_set_disp_pack_out(OLSR_TRUE);
812           continue;
813         }
814
815
816       /*
817        * Should we set up and send on a IPC socket for the front-end?
818        */
819       if (strcmp(*argv, "-ipc") == 0) 
820         {
821           cnf->ipc_connections = 1;
822           continue;
823         }
824
825       /*
826        * IPv6 multicast addr
827        */
828       if (strcmp(*argv, "-multi") == 0) 
829         {
830           struct in6_addr in6;
831           NEXT_ARG;
832           CHECK_ARGC;
833           if(inet_pton(AF_INET6, *argv, &in6) <= 0)
834             {
835               fprintf(stderr, "Failed converting IP address %s\n", *argv);
836               exit(EXIT_FAILURE);
837             }
838
839           memcpy(&ifcnf->ipv6_multi_glbl, &in6, sizeof(struct in6_addr));
840
841           continue;
842         }
843
844       /*
845        * Host emulation
846        */
847       if (strcmp(*argv, "-hemu") == 0) 
848         {
849           struct in_addr in;
850           struct olsr_if *ifa;
851       
852           NEXT_ARG;
853           CHECK_ARGC;
854           if(inet_pton(AF_INET, *argv, &in) <= 0)
855             {
856               fprintf(stderr, "Failed converting IP address %s\n", *argv);
857               exit(EXIT_FAILURE);
858             }
859           /* Add hemu interface */
860
861           ifa = queue_if("hcif01", OLSR_TRUE);
862
863           if(!ifa)
864             continue;
865
866           ifa->cnf = get_default_if_config();
867           ifa->host_emul = OLSR_TRUE;
868           memcpy(&ifa->hemu_ip, &in, sizeof(union olsr_ip_addr));
869           cnf->host_emul = OLSR_TRUE;
870
871           continue;
872         }
873
874
875       /*
876        * Delete possible default GWs
877        */
878       if (strcmp(*argv, "-delgw") == 0) 
879         {
880           olsr_cnf->del_gws = OLSR_TRUE;
881           continue;
882         }
883
884
885       if (strcmp(*argv, "-nofork") == 0) 
886         {
887           cnf->no_fork = OLSR_TRUE;
888           continue;
889         }
890
891       return -1;
892     }
893   return 0;
894 }
895
896 /*
897  * a wrapper around times(2). times(2) has the problem, that it may return -1
898  * in case of an err (e.g. EFAULT on the parameter) or immediately before an
899  * overrun (though it is not en error) just because the jiffies (or whatever
900  * the underlying kernel calls the smallest accountable time unit) are
901  * inherently "unsigned" (and always incremented).
902  */
903 unsigned long olsr_times(void)
904 {
905   struct tms tms_buf;
906   const long t = times(&tms_buf);
907   return t < 0 ? -errno : t;
908 }
909
910 /*
911  * Local Variables:
912  * c-basic-offset: 2
913  * End:
914  */