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