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