* killed lots of #ifdef ... #endif which make the source quite unreadable
[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   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 #ifndef WIN32
128   olsr_argv = argv;
129 #endif
130   setbuf(stdout, NULL);
131   setbuf(stderr, NULL);
132
133 #ifndef WIN32
134   /* Check if user is root */
135   if(geteuid())
136     {
137       fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
138       exit(EXIT_FAILURE);
139     }
140 #else
141   DisableIcmpRedirects();
142
143   if (WSAStartup(0x0202, &WsaData))
144     {
145       fprintf(stderr, "Could not initialize WinSock.\n");
146       olsr_exit(__func__, EXIT_FAILURE);
147     }
148 #endif
149
150   /* Open syslog */
151   olsr_openlog("olsrd");
152
153   /* Grab initial timestamp */
154   now_times = times(&tms_buf);
155     
156   printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n", 
157          olsrd_version, 
158          build_date,
159          build_host);
160     
161   /* Using PID as random seed */
162   srandom(getpid());
163
164   /* Init widely used statics */
165   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
166
167   /*
168    * Set configfile name and
169    * check if a configfile name was given as parameter
170    */
171 #ifdef WIN32
172 #ifndef WINCE
173   GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
174 #else
175   conf_file_name[0] = 0;
176 #endif
177   
178   len = strlen(conf_file_name);
179   
180   if (len == 0 || conf_file_name[len - 1] != '\\')
181     conf_file_name[len++] = '\\';
182   
183   strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
184 #else
185   strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
186 #endif
187
188   if ((argc > 1) && (strcmp(argv[1], "-f") == 0)) 
189     {
190       struct stat statbuf;
191
192       argv++; argc--;
193       if(argc == 1)
194         {
195           fprintf(stderr, "You must provide a filename when using the -f switch!\n");
196           exit(EXIT_FAILURE);
197         }
198
199       if (stat(argv[1], &statbuf) < 0)
200         {
201           fprintf(stderr, "Could not find specified config file %s!\n%s\n\n", argv[1], strerror(errno));
202           exit(EXIT_FAILURE);
203         }
204                  
205       strscpy(conf_file_name, argv[1], sizeof(conf_file_name));
206       argv++; argc--;
207
208     }
209
210   /*
211    * set up configuration prior to processing commandline options
212    */
213   if(NULL == (olsr_cnf = olsrd_parse_cnf(conf_file_name)))
214     {
215       printf("Using default config values(no configfile)\n");
216       olsr_cnf = olsrd_get_default_cnf();
217     }
218
219   default_ifcnf = get_default_if_config();
220   if (default_ifcnf == NULL) {
221     fprintf(stderr, "No default ifconfig found!\n");
222     exit(EXIT_FAILURE);
223   }
224
225   /* Initialize tick resolution */
226 #ifndef WIN32
227   olsr_cnf->system_tick_divider = 1000/sysconf(_SC_CLK_TCK);
228 #else
229   olsr_cnf->system_tick_divider = 1;
230 #endif
231
232   /* Initialize timers */
233   olsr_init_timers();
234
235   /*
236    * Process olsrd options.
237    */
238   if(olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0)
239     {
240       print_usage();
241       olsr_exit(__func__, EXIT_FAILURE);
242     }
243
244   /*
245    * Set configuration for command-line specified interfaces
246    */
247   set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
248
249   /* free the default ifcnf */
250   free(default_ifcnf);
251
252   /* Sanity check configuration */
253   if(olsrd_sanity_check_cnf(olsr_cnf) < 0)
254     {
255       fprintf(stderr, "Bad configuration!\n");
256       olsr_exit(__func__, EXIT_FAILURE);      
257     }
258
259   /*
260    * Print configuration 
261    */
262   if(olsr_cnf->debug_level > 1) {
263     olsrd_print_cnf(olsr_cnf);
264   }
265 #ifndef WIN32
266   /* Disable redirects globally */
267   disable_redirects_global(olsr_cnf->ip_version);
268 #endif
269
270   /*
271    * socket for ioctl calls
272    */
273   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
274   if (olsr_cnf->ioctl_s < 0) {
275     olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
276     olsr_exit(__func__, 0);
277   }
278
279 #if LINUX_POLICY_ROUTING
280   olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
281   if (olsr_cnf->rtnl_s < 0) {
282     olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
283     olsr_exit(__func__, 0);
284   }
285   fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
286 #endif
287
288 /*
289  * create routing socket
290  */
291 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
292   olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
293   if (olsr_cnf->rts < 0) {
294     olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
295     olsr_exit(__func__, 0);
296   }
297 #endif
298
299   /* Init empty TC timer */
300   set_empty_tc_timer(GET_TIMESTAMP(0));
301
302   /*
303    *enable ip forwarding on host
304    */
305   enable_ip_forwarding(olsr_cnf->ip_version);
306
307   /* Initialize parser */
308   olsr_init_parser();
309
310   /* Initialize route-exporter */
311   olsr_init_export_route();
312
313   /* Initialize message sequencnumber */
314   init_msg_seqno();
315
316   /* Initialize dynamic willingness calculation */
317   olsr_init_willingness();
318
319   /*
320    *Set up willingness/APM
321    */
322   if(olsr_cnf->willingness_auto)
323     {
324       if(apm_init() < 0)
325         {
326           OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
327
328           olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
329
330           olsr_cnf->willingness_auto = 0;
331           olsr_cnf->willingness = WILL_DEFAULT;
332         }
333       else
334         {
335           olsr_cnf->willingness = olsr_calculate_willingness();
336
337           OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, olsr_cnf->will_int);
338         }
339     }
340
341   /* Initialize net */
342   init_net();
343
344   /* Initializing networkinterfaces */
345   if(!ifinit())
346     {
347       if(olsr_cnf->allow_no_interfaces)
348         {
349           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");
350           sleep(5);
351         }
352       else
353         {
354           fprintf(stderr, "No interfaces detected!\nBailing out!\n");
355           olsr_exit(__func__, EXIT_FAILURE);
356         }
357     }
358
359   /* Print heartbeat to stdout */
360
361 #if !defined WINCE
362   if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
363     olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC,
364                      &generate_stdout_pulse, NULL, 0);
365   }
366 #endif
367
368   /* Initialize the IPC socket */
369
370   if (olsr_cnf->ipc_connections > 0) {
371       ipc_init();
372   }
373   /* Initialisation of different tables to be used.*/
374   olsr_init_tables();
375
376   /* daemon mode */
377 #ifndef WIN32
378   if(olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) {
379     printf("%s detaching from the current process...\n", olsrd_version);
380     if (daemon(0, 0) < 0) {
381       printf("daemon(3) failed: %s\n", strerror(errno));
382       exit(EXIT_FAILURE);
383     }
384   }
385 #endif
386
387   /* Load plugins */
388   olsr_load_plugins();
389
390   OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
391
392   /* Start syslog entry */
393   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
394
395   /*
396    *signal-handlers
397    */
398
399   /* ctrl-C and friends */
400 #ifdef WIN32
401 #ifndef WINCE
402   SetConsoleCtrlHandler(SignalHandler, OLSR_TRUE);
403 #endif
404 #else
405   signal(SIGHUP, olsr_reconfigure);  
406   signal(SIGINT,  olsr_shutdown);
407   signal(SIGQUIT, olsr_shutdown);
408   signal(SIGILL,  olsr_shutdown);
409   signal(SIGABRT, olsr_shutdown);
410 //  signal(SIGSEGV, olsr_shutdown);
411   signal(SIGTERM, olsr_shutdown);
412   signal(SIGPIPE, SIG_IGN);
413 #endif
414
415   link_changes = OLSR_FALSE;
416
417   /* Starting scheduler */
418   olsr_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   /* Free cookies and memory pools attached. */
509   olsr_delete_all_cookies();
510
511   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
512
513   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
514
515   exit(olsr_cnf->exit_value);
516 }
517
518 /**
519  * Print the command line usage
520  */
521 static void
522 print_usage(void)
523 {
524
525   fprintf(stderr,
526           "An error occured somwhere between your keyboard and your chair!\n"
527           "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n"
528           "  [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n"
529           "  [-lql <LQ level>] [-lqw <LQ winsize>] [-lqnt <nat threshold>]\n"
530           "  [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n"
531           "  [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
532           "  [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
533           "  [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>]\n"
534           "  [-lql <LQ level>] [-lqa <LQ aging factor>]\n");
535 }
536
537
538 /**
539  * Sets the provided configuration on all unconfigured
540  * interfaces
541  *
542  * @param ifs a linked list of interfaces to check and possible update
543  * @param cnf the default configuration to set on unconfigured interfaces
544  */
545 int
546 set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf)
547 {
548   int changes = 0;
549
550   while(ifs)
551     {
552       if(ifs->cnf == NULL)
553         {
554           ifs->cnf = olsr_malloc(sizeof(struct if_config_options), "Set default config");
555           *ifs->cnf = *cnf;
556           changes++;
557         }
558       ifs = ifs->next;
559     }
560   return changes;
561 }
562
563
564 #define NEXT_ARG do { argv++;argc--; } while (0)
565 #define CHECK_ARGC do { if(!argc) { \
566       if((argc - 1) == 1){ \
567       fprintf(stderr, "Error parsing command line options!\n"); \
568       } else { \
569       argv--; \
570       fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
571      } \
572      olsr_exit(__func__, EXIT_FAILURE); \
573      } } while (0)
574
575 /**
576  * Process command line arguments passed to olsrd
577  *
578  */
579 static int
580 olsr_process_arguments(int argc, char *argv[], 
581                        struct olsrd_config *cnf, 
582                        struct if_config_options *ifcnf)
583 {
584   while (argc > 1)
585     {
586       NEXT_ARG;
587 #ifdef WIN32
588       /*
589        *Interface list
590        */
591       if (strcmp(*argv, "-int") == 0)
592         {
593           ListInterfaces();
594           exit(0);
595         }
596 #endif
597
598       /*
599        *Configfilename
600        */
601       if(strcmp(*argv, "-f") == 0) 
602         {
603           fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
604           olsr_exit(__func__, EXIT_FAILURE);
605         }
606
607       /*
608        *Use IP version 6
609        */
610       if(strcmp(*argv, "-ipv6") == 0) 
611         {
612           cnf->ip_version = AF_INET6;
613           continue;
614         }
615
616       /*
617        *Broadcast address
618        */
619       if(strcmp(*argv, "-bcast") == 0) 
620         {
621           struct in_addr in;
622           NEXT_ARG;
623           CHECK_ARGC;
624
625           if (inet_aton(*argv, &in) == 0)
626             {
627               printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
628               continue;
629             }
630           memcpy(&ifcnf->ipv4_broadcast.v4, &in.s_addr, sizeof(olsr_u32_t));  
631           continue;
632         }
633
634       /*
635        * Set LQ level
636        */
637       if (strcmp(*argv, "-lql") == 0) 
638         {
639           int tmp_lq_level;
640           NEXT_ARG;
641           CHECK_ARGC;
642           
643           /* Sanity checking is done later */
644           sscanf(*argv, "%d", &tmp_lq_level);
645           olsr_cnf->lq_level = tmp_lq_level;
646           continue;
647         }
648
649       /*
650        * Set LQ winsize
651        */
652       if (strcmp(*argv, "-lqa") == 0) 
653         {
654           float tmp_lq_aging;
655           NEXT_ARG;
656           CHECK_ARGC;
657           
658           sscanf(*argv, "%f", &tmp_lq_aging);
659
660           if(tmp_lq_aging < MIN_LQ_AGING || tmp_lq_aging > MAX_LQ_AGING)
661             {
662               printf("LQ aging factor %f not allowed. Range [%f-%f]\n", 
663                      tmp_lq_aging, MIN_LQ_AGING, MAX_LQ_AGING);
664               olsr_exit(__func__, EXIT_FAILURE);
665             }
666           olsr_cnf->lq_aging = tmp_lq_aging;
667           continue;
668         }
669       
670       /*
671        * Set NAT threshold
672        */
673       if (strcmp(*argv, "-lqnt") == 0) 
674         {
675           float tmp_lq_nat_thresh;
676           NEXT_ARG;
677           CHECK_ARGC;
678
679           sscanf(*argv,"%f", &tmp_lq_nat_thresh);
680
681           if(tmp_lq_nat_thresh < 0.1 || tmp_lq_nat_thresh > 1.0)
682             {
683               printf("NAT threshold %f not allowed. Range [%f-%f]\n", 
684                      tmp_lq_nat_thresh, 0.1, 1.0);
685               olsr_exit(__func__, EXIT_FAILURE);
686             }
687           olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
688           continue;
689         }
690
691       /*
692        * Enable additional debugging information to be logged.
693        */
694       if (strcmp(*argv, "-d") == 0) 
695         {
696           NEXT_ARG;
697           CHECK_ARGC;
698
699           sscanf(*argv,"%d", &cnf->debug_level);
700           continue;
701         }
702
703                 
704       /*
705        * Interfaces to be used by olsrd.
706        */
707       if (strcmp(*argv, "-i") == 0) 
708         {
709           NEXT_ARG;
710           CHECK_ARGC;
711
712           if(*argv[0] == '-')
713             {
714               fprintf(stderr, "You must provide an interface label!\n");
715               olsr_exit(__func__, EXIT_FAILURE);
716             }
717           printf("Queuing if %s\n", *argv);
718           queue_if(*argv, OLSR_FALSE);
719
720           while((argc - 1) && (argv[1][0] != '-'))
721             {
722               NEXT_ARG;
723               printf("Queuing if %s\n", *argv);
724               queue_if(*argv, OLSR_FALSE);
725             }
726
727           continue;
728         }
729       /*
730        * Set the hello interval to be used by olsrd.
731        * 
732        */
733       if (strcmp(*argv, "-hint") == 0) 
734         {
735           NEXT_ARG;
736           CHECK_ARGC;
737           sscanf(*argv,"%f", &ifcnf->hello_params.emission_interval);
738           ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval * 3;
739           continue;
740         }
741
742       /*
743        * Set the HNA interval to be used by olsrd.
744        * 
745        */
746       if (strcmp(*argv, "-hnaint") == 0) 
747         {
748           NEXT_ARG;
749           CHECK_ARGC;
750           sscanf(*argv,"%f", &ifcnf->hna_params.emission_interval);
751           ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
752           continue;
753         }
754
755       /*
756        * Set the MID interval to be used by olsrd.
757        * 
758        */
759       if (strcmp(*argv, "-midint") == 0) 
760         {
761           NEXT_ARG;
762           CHECK_ARGC;
763           sscanf(*argv,"%f", &ifcnf->mid_params.emission_interval);
764           ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
765           continue;
766         }
767
768       /*
769        * Set the tc interval to be used by olsrd.
770        * 
771        */
772       if (strcmp(*argv, "-tcint") == 0) 
773         {
774           NEXT_ARG;
775           CHECK_ARGC;
776           sscanf(*argv,"%f", &ifcnf->tc_params.emission_interval);
777           ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
778           continue;
779         }
780
781       /*
782        * Set the polling interval to be used by olsrd.
783        */
784       if (strcmp(*argv, "-T") == 0) 
785         {
786           NEXT_ARG;
787           CHECK_ARGC;
788           sscanf(*argv,"%f",&cnf->pollrate);
789           continue;
790         }
791
792
793       /*
794        * Should we display the contents of packages beeing sent?
795        */
796       if (strcmp(*argv, "-dispin") == 0) 
797         {
798           parser_set_disp_pack_in(OLSR_TRUE);
799           continue;
800         }
801
802       /*
803        * Should we display the contents of incoming packages?
804        */
805       if (strcmp(*argv, "-dispout") == 0) 
806         {
807           net_set_disp_pack_out(OLSR_TRUE);
808           continue;
809         }
810
811
812       /*
813        * Should we set up and send on a IPC socket for the front-end?
814        */
815       if (strcmp(*argv, "-ipc") == 0) 
816         {
817           cnf->ipc_connections = 1;
818           continue;
819         }
820
821       /*
822        * IPv6 multicast addr
823        */
824       if (strcmp(*argv, "-multi") == 0) 
825         {
826           struct in6_addr in6;
827           NEXT_ARG;
828           CHECK_ARGC;
829           if(inet_pton(AF_INET6, *argv, &in6) <= 0)
830             {
831               fprintf(stderr, "Failed converting IP address %s\n", *argv);
832               exit(EXIT_FAILURE);
833             }
834
835           memcpy(&ifcnf->ipv6_multi_glbl, &in6, sizeof(struct in6_addr));
836
837           continue;
838         }
839
840       /*
841        * Host emulation
842        */
843       if (strcmp(*argv, "-hemu") == 0) 
844         {
845           struct in_addr in;
846           struct olsr_if *ifa;
847       
848           NEXT_ARG;
849           CHECK_ARGC;
850           if(inet_pton(AF_INET, *argv, &in) <= 0)
851             {
852               fprintf(stderr, "Failed converting IP address %s\n", *argv);
853               exit(EXIT_FAILURE);
854             }
855           /* Add hemu interface */
856
857           ifa = queue_if("hcif01", OLSR_TRUE);
858
859           if(!ifa)
860             continue;
861
862           ifa->cnf = get_default_if_config();
863           ifa->host_emul = OLSR_TRUE;
864           memcpy(&ifa->hemu_ip, &in, sizeof(union olsr_ip_addr));
865           cnf->host_emul = OLSR_TRUE;
866
867           continue;
868         }
869
870
871       /*
872        * Delete possible default GWs
873        */
874       if (strcmp(*argv, "-delgw") == 0) 
875         {
876           olsr_cnf->del_gws = OLSR_TRUE;
877           continue;
878         }
879
880
881       if (strcmp(*argv, "-nofork") == 0) 
882         {
883           cnf->no_fork = OLSR_TRUE;
884           continue;
885         }
886
887       return -1;
888     }
889   return 0;
890 }
891
892 /*
893  * Local Variables:
894  * c-basic-offset: 2
895  * End:
896  */