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