Replaced unik-olsrd with olsr.org
[olsrd.git] / src / main.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of olsr.org.
6  *
7  * UniK olsrd is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * UniK olsrd is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 /*
24  *This implementation was based on the INRIA OLSR implementation. 
25  *
26  *The INRIA code carries the following copyright:
27  *
28  * This Copyright notice is in French. An English summary is given
29  * but the referee text is the French one.
30  *
31  * Copyright (c) 2000, 2001 Adokoe.Plakoo@inria.fr, INRIA Rocquencourt,
32  *                          Anis.Laouiti@inria.fr, INRIA Rocquencourt.
33  */
34
35
36 #include "main.h"
37 #include "interfaces.h"
38 //#include "ifnet.h"
39 #include "configfile.h"
40 #include "mantissa.h"
41 #include "local_hna_set.h"
42 #include "olsr.h"
43 #include "scheduler.h"
44 #include "parser.h"
45 #include "generate_msg.h"
46 #include "plugin_loader.h"
47 #include "socket_parser.h"
48 #include "apm.h"
49 #include "link_layer.h"
50
51 #ifdef linux
52 #include "linux/tunnel.h"
53 #elif defined WIN32
54 #define close(x) closesocket(x)
55 #include "win32/tunnel.h"
56 int __stdcall SignalHandler(unsigned long signal);
57 void ListInterfaces(void);
58 #else
59 #       error "Unsupported system"
60 #endif
61
62 /**
63  *The main funtion does a LOT of things. It should 
64  *probably be much shorter
65  *
66  *After things are set up and the scheduler thread
67  *is started, the main thread goes into a typical 
68  *select(2) loop listening
69  */
70
71 int
72 main(int argc, char *argv[])
73 {
74   //struct interface *ifp;
75   struct in_addr in;
76
77   /* The thread for the scheduler */
78   pthread_t thread;
79
80   struct stat statbuf;
81   char conf_file_name[FILENAME_MAX];
82   
83 #ifdef WIN32
84   WSADATA WsaData;
85   int len;
86 #endif
87
88   setbuf(stdout, NULL);
89   setbuf(stderr, NULL);
90
91   /* Initialize socket list */
92   olsr_socket_entries = NULL;
93
94 #ifndef WIN32
95   /* Check if user is root */
96   if(getuid() || getgid())
97     {
98       fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
99       exit(EXIT_FAILURE);
100     }
101 #else
102   if (WSAStartup(0x0202, &WsaData))
103     {
104       fprintf(stderr, "Could not initialize WinSock.\n");
105       olsr_exit(__func__, EXIT_FAILURE);
106     }
107 #endif
108
109   /* Open syslog */
110   openlog("olsrd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
111   setlogmask(LOG_UPTO(LOG_INFO));
112
113   /*
114    * Start syslog entry
115    */
116   syslog(LOG_INFO, "%s started", SOFTWARE_VERSION);
117
118   /* Set default values */
119   set_default_values();
120
121   /* Initialize network functions */
122   init_net();
123
124   /* Initialize plugin loader */
125   olsr_init_plugin_loader();
126  
127   /* Get initial timestep */
128   nowtm = NULL;
129   while (nowtm == NULL)
130     {
131       nowtm = gmtime(&now.tv_sec);
132     }
133     
134   /* The port to use for OLSR traffic */
135   olsr_udp_port = htons(OLSRPORT);
136     
137   printf("\n *** %s ***\n Build date: %s\n http://www.olsr.org\n\n", 
138          SOFTWARE_VERSION, 
139          __DATE__);
140     
141   /* Using PID as random seed */
142   srandom(getpid());
143
144
145   /*
146    * Set configfile name and
147    * check if a configfile name was given as parameter
148    */
149 #ifdef WIN32
150   GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
151   
152   len = strlen(conf_file_name);
153   
154   if (conf_file_name[len - 1] != '\\')
155     conf_file_name[len++] = '\\';
156   
157   strcpy(conf_file_name + len, "olsrd.conf");
158 #else
159   strncpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, FILENAME_MAX);
160 #endif
161
162   if ((argc > 1) && (strcmp(argv[1], "-f") == 0)) 
163     {
164       argv++, argc--;
165       if(argc == 1)
166         {
167           fprintf(stderr, "You must provide a filename when using the -f switch!\n");
168           olsr_exit(__func__, EXIT_FAILURE);
169         }
170
171       if (stat(argv[1], &statbuf) < 0)
172         {
173           fprintf(stderr, "Could not finc specified config file %s!\n%s\n\n", argv[1], strerror(errno));
174           olsr_exit(__func__, EXIT_FAILURE);
175         }
176                  
177       strncpy(conf_file_name, argv[1], FILENAME_MAX);
178       argv++, argc--;
179
180     }
181
182   /*
183    * Reading configfile options prior to processing commandline options
184    */
185
186   read_config_file(conf_file_name);
187   
188   /*
189    * Process olsrd options.
190    */
191   
192   argv++, argc--;
193   while (argc > 0 && **argv == '-')
194     {
195 #ifdef WIN32
196       /*
197        *Interface list
198        */
199       if (strcmp(*argv, "-int") == 0)
200         {
201           ListInterfaces();
202           exit(0);
203         }
204 #endif
205
206       /*
207        *Configfilename
208        */
209       if (strcmp(*argv, "-f") == 0) 
210         {
211           fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
212           olsr_exit(__func__, EXIT_FAILURE);
213         }
214
215       /*
216        *Use IP version 6
217        */
218       if (strcmp(*argv, "-ipv6") == 0) 
219         {
220           ipversion = AF_INET6;
221           argv++, argc--;
222           continue;
223         }
224
225
226       /*
227        *Broadcast address
228        */
229       if (strcmp(*argv, "-bcast") == 0) 
230         {
231           argv++, argc--;
232           if(argc == 0)
233             {
234               fprintf(stderr, "You must provide a broadcastaddr when using the -bcast switch!\n");
235               olsr_exit(__func__, EXIT_FAILURE);
236             }
237
238           if (inet_aton(*argv, &in) == 0)
239             {
240               printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
241               continue;
242             }
243
244           bcast_set = 1;
245                  
246           memcpy(&bcastaddr.sin_addr, &in.s_addr, sizeof(olsr_u32_t));
247
248
249           continue;
250         }
251
252
253       /*
254        * Enable additional debugging information to be logged.
255        */
256       if (strcmp(*argv, "-d") == 0) 
257         {
258           argv++, argc--;
259           sscanf(*argv,"%d", &debug_level);
260           argv++, argc--;
261           continue;
262         }
263
264
265
266                 
267       /*
268        * Interfaces to be used by olsrd.
269        */
270       if (strcmp(*argv, "-i") == 0) 
271         {
272           option_i = 1;
273           argv++, argc--;
274           queue_if(*argv);
275           argv++, argc--;
276
277           while((argc) && (**argv != '-'))
278             {
279               queue_if(*argv);
280               argv++; argc--;
281             }
282
283           continue;
284         }
285                 
286       /*
287        * Set the hello interval to be used by olsrd.
288        * 
289        */
290       if (strcmp(*argv, "-hint") == 0) 
291         {
292           argv++, argc--;
293           sscanf(*argv,"%f",&hello_int);
294           argv++, argc--;
295           continue;
296         }
297
298       /*
299        * Set the hello interval to be used by olsrd.
300        * on nonwireless interfaces
301        */
302       if (strcmp(*argv, "-hintn") == 0) 
303         {
304           argv++, argc--;
305           sscanf(*argv,"%f",&hello_int_nw);
306           argv++, argc--;
307           continue;
308         }
309
310       /*
311        * Set the HNA interval to be used by olsrd.
312        * 
313        */
314       if (strcmp(*argv, "-hnaint") == 0) 
315         {
316           argv++, argc--;
317           sscanf(*argv,"%f", &hna_int);
318           argv++, argc--;
319           continue;
320         }
321
322       /*
323        * Set the MID interval to be used by olsrd.
324        * 
325        */
326       if (strcmp(*argv, "-midint") == 0) 
327         {
328           argv++, argc--;
329           sscanf(*argv,"%f", &mid_int);
330           argv++, argc--;
331           continue;
332         }
333
334       /*
335        * Set the tc interval to be used by olsrd.
336        * 
337        */
338       if (strcmp(*argv, "-tcint") == 0) 
339         {
340           argv++, argc--;
341           sscanf(*argv,"%f",&tc_int);
342           argv++, argc--;
343           continue;
344         }
345
346       /*
347        * Set the tos bits to be used by olsrd.
348        * 
349        */
350       if (strcmp(*argv, "-tos") == 0) 
351         {
352           argv++, argc--;
353           sscanf(*argv,"%d",(int *)&tos);
354           argv++, argc--;
355           continue;
356         }
357
358
359       /*
360        * Set the polling interval to be used by olsrd.
361        */
362       if (strcmp(*argv, "-T") == 0) 
363         {
364           argv++, argc--;
365           sscanf(*argv,"%f",&polling_int);
366           argv++, argc--;
367           continue;
368         }
369
370       /*
371        * Set the vtime miltiplier
372        */
373       if (strcmp(*argv, "-hhold") == 0) 
374         {
375           argv++, argc--;
376           sscanf(*argv,"%d",&neighbor_timeout_mult);
377           argv++, argc--;
378           continue;
379         }
380
381       /*
382        * Set the vtime miltiplier for non-WLAN cards
383        */
384       if (strcmp(*argv, "-nhhold") == 0) 
385         {
386           argv++, argc--;
387           sscanf(*argv,"%d",&neighbor_timeout_mult_nw);
388           argv++, argc--;
389           continue;
390         }
391
392       /*
393        * Set the TC vtime multiplier
394        */
395       if (strcmp(*argv, "-thold") == 0) 
396         {
397           argv++, argc--;
398           sscanf(*argv,"%d",&topology_timeout_mult);
399           argv++, argc--;
400           continue;
401         }
402
403       /*
404        * Should we display the contents of packages beeing sent?
405        */
406       if (strcmp(*argv, "-dispin") == 0) 
407         {
408           argv++, argc--;
409           disp_pack_in = 1;
410           continue;
411         }
412
413       /*
414        * Should we display the contents of incoming packages?
415        */
416       if (strcmp(*argv, "-dispout") == 0) 
417         {
418           argv++, argc--;
419           disp_pack_out = 1;
420           continue;
421         }
422
423
424       /*
425        * Should we set up and send on a IPC socket for the front-end?
426        */
427       if (strcmp(*argv, "-ipc") == 0) 
428         {
429           argv++, argc--;
430           use_ipc = 1;
431           continue;
432         }
433
434
435       /*
436        * Display link-layer info(experimental)
437        */
438       if (strcmp(*argv, "-llinfo") == 0) 
439         {
440           argv++, argc--;
441           llinfo = 1;
442           continue;
443         }
444
445       /*
446        * Use Internet gateway tunneling?
447        */
448       if (strcmp(*argv, "-tnl") == 0) 
449         {
450           argv++, argc--;
451           use_tunnel = 1;
452
453           continue;
454         }
455
456
457       /*
458        * IPv6 multicast addr
459        */
460       if (strcmp(*argv, "-multi") == 0) 
461         {
462           argv++, argc--;
463           strncpy(ipv6_mult, *argv, 50);
464
465           argv++, argc--;
466
467           continue;
468         }
469
470
471       /*
472        * Should we display the contents of packages beeing sent?
473        */
474       if (strcmp(*argv, "-delgw") == 0) 
475         {
476           argv++, argc--;
477           del_gws = 1;
478           continue;
479         }
480
481
482       print_usage();
483       olsr_exit(__func__, EXIT_FAILURE);
484     }
485
486
487   /*
488    *Interfaces need to be specified
489    */
490   if(!option_i)
491     {
492       fprintf(stderr, "OLSRD: no interfaces specified!\nuse the -i switch to specify interface(s)\nor set interface(s) in the configuration file!\n");
493       print_usage();
494       olsr_exit(__func__, EXIT_FAILURE);
495     }
496
497   /*
498    *socket for icotl calls
499    */
500   if ((ioctl_s = socket(ipversion, SOCK_DGRAM, 0)) < 0) 
501     {
502       syslog(LOG_ERR, "ioctl socket: %m");
503       close(ioctl_s);
504       olsr_exit(__func__, 0);
505     }
506
507
508   /* Type of service */
509   precedence = IPTOS_PREC(tos);
510   tos_bits = IPTOS_TOS(tos);
511
512
513   /*
514    *enable ip forwarding on host
515    */
516   enable_ip_forwarding(ipversion);
517
518
519
520
521   /* Initialize scheduler MUST HAPPEN BEFORE REGISTERING ANY FUNCTIONS! */
522   init_scheduler(polling_int);
523
524   /* Initialize parser */
525   olsr_init_parser();
526
527   /* Initialize message sequencnumber */
528   init_msg_seqno();
529
530   /* Initialize dynamic willingness calculation */
531   olsr_init_willingness();
532
533
534   /* Initialize values for emission data 
535    * This also initiates message generation
536    */
537   olsr_set_hello_interval(hello_int);
538   olsr_set_hello_nw_interval(hello_int_nw);
539   olsr_set_tc_interval(tc_int);
540   olsr_set_mid_interval(mid_int);
541   olsr_set_hna_interval(hna_int);
542
543   /* Print tables to stdout */
544   if(debug_level > 0)
545     olsr_register_scheduler_event(&generate_tabledisplay, hello_int, 0, NULL);
546
547
548   /* printout settings */
549   olsr_printf(1, "\n\
550 hello interval = %0.2f       hello int nonwireless = %0.2f \n\
551 tc interval = %0.2f          polling interval = %0.2f \n\
552 neighbor_hold_time = %0.2f   neighbor_hold_time_nw = %0.2f \n\
553 topology_hold_time = %0.2f  tos setting = %d \n\
554 hna_interval = %0.2f         mid_interval = %0.2f\n\
555 tc_redunadancy = %d          mpr coverage = %d\n", 
556               hello_int, hello_int_nw, \
557               tc_int, polling_int, \
558               neighbor_hold_time, neighbor_hold_time_nw, topology_hold_time, \
559               tos, hna_int, mid_int, \
560               tc_redundancy, mpr_coverage);
561       
562   if(use_hysteresis)
563     {
564       olsr_printf(1, "hysteresis scaling factor = %0.2f\nhysteresis threshold high = %0.2f\nhysteresis threshold low  = %0.2f\n\n",
565                   hyst_scaling,
566                   hyst_threshold_high,
567                   hyst_threshold_low);
568
569       if(hyst_threshold_high <= hyst_threshold_low)
570         {
571           printf("Hysteresis threshold high lower than threshold low!!\nEdit the configuration file to fix this!\n\n");
572           olsr_exit(__func__, EXIT_FAILURE);
573         }
574     }
575
576   if(ipversion == AF_INET)
577     {
578       if(bcast_set)
579         olsr_printf(2, "Using %s broadcast\n", olsr_ip_to_string((union olsr_ip_addr *) &bcastaddr.sin_addr));
580       else
581         olsr_printf(2, "Using broadcastaddresses fetched from interfaces\n");
582     }
583
584   /*
585    *Set up willingness/APM
586    */
587   if(!willingness_set)
588     {
589       if(apm_init() < 0)
590         {
591           olsr_printf(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
592
593           syslog(LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
594
595           willingness_set = 1;
596           my_willingness = WILL_DEFAULT;
597         }
598       else
599         {
600           my_willingness = olsr_calculate_willingness();
601
602           olsr_printf(1, "Willingness set to %d - next update in %.1f secs\n", my_willingness, will_int);
603         }
604     }
605
606   /**
607    *Set ipsize and minimum packetsize
608    */
609   if(ipversion == AF_INET6)
610     {
611       olsr_printf(1, "Using IP version 6\n");
612       ipsize = sizeof(struct in6_addr);
613
614       /* Set multicast address */
615       if(ipv6_addrtype == IPV6_ADDR_SITELOCAL)
616         {
617           /* Site local */
618           strncpy(ipv6_mult, ipv6_mult_site, 50);
619         }
620       else
621         {
622           /* Global */
623           strncpy(ipv6_mult, ipv6_mult_global, 50);
624         }
625
626       olsr_printf(1, "Using multicast address %s\n", ipv6_mult);
627
628       minsize = (int)sizeof(olsr_u8_t) * 7; /* Minimum packetsize IPv6 */
629     }
630   else
631     {
632       olsr_printf(1, "Using IP version 4\n");
633       ipsize = sizeof(olsr_u32_t);
634
635       minsize = (int)sizeof(olsr_u8_t) * 4; /* Minimum packetsize IPv4 */
636     }
637
638
639   /* Initializing networkinterfaces */
640
641   if(!ifinit())
642     {
643       if(allow_no_int)
644         {
645           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");
646           sleep(5);
647         }
648       else
649         {
650           fprintf(stderr, "No interfaces detected!\nBailing out!\n");
651           olsr_exit(__func__, EXIT_FAILURE);
652         }
653     }
654
655
656   gettimeofday(&now, NULL);
657
658
659   /* Initialize the IPC socket */
660
661   if(use_ipc)
662       ipc_init();
663
664 #ifndef WIN32
665   /* Initialize link-layer notifications */
666   if(llinfo)
667     init_link_layer_notification();
668 #endif
669
670   /* Initialisation of different tables to be used.*/
671   olsr_init_tables();
672
673   /* Load plugins */
674   olsr_load_plugins();
675
676   /* Set up recieving tunnel if Inet gw */
677   if(use_tunnel && inet_gw)
678     set_up_gw_tunnel(&main_addr);
679
680   olsr_printf(1, "Main address: %s\n\n", olsr_ip_to_string(&main_addr));
681
682   olsr_printf(1, "NEIGHBORS: l=linkstate, m=MPR, w=willingness\n\n");
683
684
685   /* daemon mode */
686 #ifndef WIN32
687   if (debug_level == 0)
688     {
689       printf("%s detattching from the current process...\n", SOFTWARE_VERSION);
690       if (fork() != 0)
691         {
692           exit(1);
693         }
694       setsid();
695     }
696 #endif
697   /* Starting scheduler */
698   start_scheduler(&thread);
699
700   /*
701    *signal-handlers
702    */
703
704   /* ctrl-C and friends */
705 #ifdef WIN32
706   SetConsoleCtrlHandler(SignalHandler, TRUE);
707 #else
708   signal(SIGINT, olsr_shutdown);  
709   signal(SIGTERM, olsr_shutdown);  
710 #endif
711
712   /* Go into listenloop */
713   listen_loop();
714
715   /* Like we're ever going to reach this ;-) */
716   return 1;
717
718 } /* main */
719
720
721
722
723
724
725 /**
726  *Function called at shutdown
727  *
728  */
729 #ifdef WIN32
730 int __stdcall
731 SignalHandler(unsigned long signal)
732 #else
733 void
734 olsr_shutdown(int signal)
735 #endif
736 {
737   struct interface *ifn;
738 #ifndef WIN32
739   if(main_thread != pthread_self())
740     {
741       pthread_exit(0);
742     }
743 #endif
744
745   olsr_printf(1, "Received signal %d - shutting down\n", signal);
746
747   olsr_delete_all_kernel_routes();
748
749   olsr_printf(1, "Closing sockets...\n");
750
751   /* front-end IPC socket */
752   if(use_ipc)
753     shutdown_ipc();
754
755   /* OLSR sockets */
756   for (ifn = ifnet; ifn; ifn = ifn->int_next) 
757     close(ifn->olsr_socket);
758
759   /* Closing plug-ins */
760   olsr_close_plugins();
761
762   /* Reset network settings */
763   restore_settings(ipversion);
764
765   /* ioctl socket */
766   close(ioctl_s);
767
768   syslog(LOG_INFO, "%s stopped", SOFTWARE_VERSION);
769
770   olsr_printf(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", SOFTWARE_VERSION);
771
772   exit(exit_value);
773 }
774
775
776
777
778
779
780 /**
781  *Sets the default values of variables at startup
782  */
783 void
784 set_default_values()
785 {
786   memset(&main_addr, 0, sizeof(union olsr_ip_addr));
787   memset(&null_addr6, 0, sizeof (union olsr_ip_addr));
788
789   allow_no_int = 1;
790
791   exit_value = EXIT_SUCCESS; 
792   /* If the application exits by signal it is concidered success,
793    * if not, exit_value is set by the function calling olsr_exit.
794    */
795
796   tos = 16;
797
798   if_names = NULL;
799
800   sending_tc = 0;
801
802   queued_ifs = 0;
803
804   mpr_coverage = MPR_COVERAGE;
805
806   maxmessagesize = MAXMESSAGESIZE;
807
808   ipv6_addrtype = IPV6_ADDR_SITELOCAL;
809
810   /* Default multicastaddresses */
811   strncpy(ipv6_mult_site, OLSR_IPV6_MCAST_SITE_LOCAL, strlen(OLSR_IPV6_MCAST_SITE_LOCAL));
812   strncpy(ipv6_mult_global, OLSR_IPV6_MCAST_GLOBAL, strlen(OLSR_IPV6_MCAST_GLOBAL));
813
814   /* EMISSION/HOLD INTERVALS */
815
816   hello_int = HELLO_INTERVAL;
817   hello_int_nw = HELLO_INTERVAL;
818   tc_int = TC_INTERVAL;
819   hna_int = 2 * TC_INTERVAL;
820   polling_int = 0.1;
821   mid_int = MID_INTERVAL;
822   will_int = 10 * HELLO_INTERVAL; /* Willingness update interval */
823
824   neighbor_timeout_mult = 3;
825   topology_timeout_mult = 3;
826   neighbor_timeout_mult_nw = 3;
827   mid_timeout_mult = 3;
828   hna_timeout_mult = 3;
829
830   topology_hold_time = TOP_HOLD_TIME;
831   neighbor_hold_time = NEIGHB_HOLD_TIME;
832   neighbor_hold_time_nw = NEIGHB_HOLD_TIME;
833   mid_hold_time = MID_HOLD_TIME;
834   hna_hold_time = 2 * (3 * TC_INTERVAL);
835   dup_hold_time = DUP_HOLD_TIME;
836
837   /* TC redundancy */
838   tc_redundancy = TC_REDUNDANCY;
839
840   /* Hysteresis */
841   use_hysteresis = 1;
842   hyst_scaling = HYST_SCALING;
843   hyst_threshold_low = HYST_THRESHOLD_LOW;
844   hyst_threshold_high = HYST_THRESHOLD_HIGH;
845
846   use_ipc = 0;
847   llinfo = 0;
848   bcast_set = 0;
849   del_gws = 0;
850   /* DEBUG ON BY DEFAULT */
851   debug_level = 1;
852
853 #ifndef WIN32
854   /* Get main thread ID */
855   main_thread = pthread_self();
856 #endif
857
858   /* local HNA set must be initialized before reading options */
859   olsr_init_local_hna_set();
860
861   /*
862    * set fixed willingness off by default
863    */
864   willingness_set = 0;
865
866   ipv6_mult[0] = 0;
867
868   /* Gateway tunneling */
869   use_tunnel = 0;
870   inet_tnl_added = 0;
871   gw_tunnel = 0;
872
873   /* Display packet content */
874   disp_pack_in = 0;
875   disp_pack_out = 0;
876
877   ipversion = AF_INET;
878 }
879
880
881
882
883 void
884 print_usage()
885 {
886
887   fprintf(stderr, "An error occured somwhere between your keyboard and your chair!\n"); 
888   fprintf(stderr, "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n");
889   fprintf(stderr, "  [-d <debug_level>] [-ipv6] [-tnl] [-multi <IPv6 multicast address>]\n"); 
890   fprintf(stderr, "  [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n");
891   fprintf(stderr, "  [-midint <mid interval value (secs)>] [-hnaint <hna interval value (secs)>]\n");
892   fprintf(stderr, "  [-hint <hello interval value (secs)>] [-tcint <tc interval value (secs)>]\n");
893   fprintf(stderr, "  [-hhold <HELLO validity time as a multiplier of the HELLO interval>]\n");
894   fprintf(stderr, "  [-nhhold <HELLO validity time on non-wireless interfaces>]\n");
895   fprintf(stderr, "  [-thold <TC validity time as a multiplier of the TC interval>]\n");
896   fprintf(stderr, "  [-tos value (int)] [-nhint <hello interval value (secs) for non-WLAN>]\n");
897   fprintf(stderr, "  [-T <Polling Rate (secs)>]\n"); 
898
899 }