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