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