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