Added -nofork option
[olsrd.git] / src / cfgparser / olsrd_conf.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: olsrd_conf.c,v 1.35 2005/03/10 18:09:32 kattemat Exp $
40  */
41
42
43 #include <stdio.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <stdlib.h>
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
51
52 #include "olsrd_conf.h"
53
54
55 extern FILE *yyin;
56 extern int yyparse(void);
57
58 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.";
59
60 #ifdef MAKELIB
61
62 /* Build as DLL */
63
64 void __attribute__ ((constructor)) 
65 my_init(void);
66
67 void __attribute__ ((destructor)) 
68 my_fini(void);
69
70
71 /**
72  *Constructor
73  */
74 void
75 my_init()
76 {
77   /* Print plugin info to stdout */
78   printf("olsrd config file parser %s loaded\n", PARSER_VERSION);
79
80   return;
81 }
82
83 /**
84  *Destructor
85  */
86 void
87 my_fini()
88 {
89   printf("See you around!\n");
90   return;
91 }
92
93 #else
94
95 #ifdef MAKEBIN
96
97 /* Build as standalone binary */
98 int 
99 main(int argc, char *argv[])
100 {
101   struct olsrd_config *cnf;
102
103   if(argc == 1)
104     {
105       fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
106       exit(EXIT_FAILURE);
107     }
108
109   if((cnf = olsrd_parse_cnf(argv[1])) != NULL)
110     {
111       if((argc > 2) && (!strcmp(argv[2], "-print")))
112         {
113           olsrd_print_cnf(cnf);  
114           olsrd_write_cnf(cnf, "./out.conf");
115         }
116       else
117         printf("Use -print to view parsed values\n");
118       printf("Configfile parsed OK\n");
119     }
120   else
121     {
122       printf("Failed parsing \"%s\"\n", argv[1]);
123     }
124
125   return 0;
126 }
127
128 #else
129
130 /* Build as part of olsrd */
131
132
133 #endif
134
135 #endif
136
137 struct olsrd_config *
138 olsrd_parse_cnf(const char *filename)
139 {
140   struct olsr_if *in, *new_ifqueue, *in_tmp;
141
142   /* Stop the compiler from complaining */
143   strlen(copyright_string);
144
145   cnf = malloc(sizeof(struct olsrd_config));
146   if (cnf == NULL)
147     {
148       fprintf(stderr, "Out of memory %s\n", __func__);
149       return NULL;
150   }
151
152   set_default_cnf(cnf);
153
154   printf("Parsing file: \"%s\"\n", filename);
155
156   yyin = fopen(filename, "r");
157   
158   if (yyin == NULL)
159     {
160       fprintf(stderr, "Cannot open configuration file '%s': %s.\n",
161               filename, strerror(errno));
162       free(cnf);
163       return NULL;
164   }
165
166   current_line = 1;
167
168   if (yyparse() != 0)
169     {
170       fclose(yyin);
171       olsrd_free_cnf(cnf);
172       return NULL;
173     }
174   
175   fclose(yyin);
176
177   /* Reverse the queue (added by user request) */
178   in = cnf->interfaces;
179   new_ifqueue = NULL;
180
181   while(in)
182     {
183       in_tmp = in; 
184       in = in->next;
185
186       in_tmp->next = new_ifqueue;
187       new_ifqueue = in_tmp;
188     }
189
190   cnf->interfaces = new_ifqueue;
191
192   in = cnf->interfaces;
193
194   while(in)
195     {
196       /* set various stuff */
197       in->index = cnf->ifcnt++;
198       in->configured = OLSR_FALSE;
199       in->interf = NULL;
200       in = in->next;
201     }
202
203
204   return cnf;
205 }
206
207
208 int
209 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
210 {
211   struct olsr_if           *in = cnf->interfaces;
212   struct if_config_options *io;
213
214   /* Debug level */
215   if(cnf->debug_level < MIN_DEBUGLVL ||
216      cnf->debug_level > MAX_DEBUGLVL)
217     {
218       fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
219       return -1;
220     }
221
222   /* IP version */
223   if(cnf->ip_version != AF_INET &&
224      cnf->ip_version != AF_INET6)
225     {
226       fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
227       return -1;
228     }
229
230   /* TOS */
231   if(//cnf->tos < MIN_TOS ||
232      cnf->tos > MAX_TOS)
233     {
234       fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
235       return -1;
236     }
237
238   if(cnf->willingness_auto == OLSR_FALSE &&
239      (cnf->willingness < MIN_WILLINGNESS ||
240       cnf->willingness > MAX_WILLINGNESS))
241     {
242       fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
243       return -1;
244     }
245
246   /* Hysteresis */
247   if(cnf->use_hysteresis == OLSR_TRUE)
248     {
249       if(cnf->hysteresis_param.scaling < MIN_HYST_PARAM ||
250          cnf->hysteresis_param.scaling > MAX_HYST_PARAM)
251         {
252           fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
253           return -1;
254         }
255
256       if(cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low)
257         {
258           fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
259           return -1;
260         }
261
262       if(cnf->hysteresis_param.thr_high < MIN_HYST_PARAM ||
263          cnf->hysteresis_param.thr_high > MAX_HYST_PARAM)
264         {
265           fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
266           return -1;
267         }
268
269       if(cnf->hysteresis_param.thr_low < MIN_HYST_PARAM ||
270          cnf->hysteresis_param.thr_low > MAX_HYST_PARAM)
271         {
272           fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
273           return -1;
274         }
275     }
276
277   /* Pollrate */
278
279   if(cnf->pollrate < MIN_POLLRATE ||
280      cnf->pollrate > MAX_POLLRATE)
281     {
282       fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
283       return -1;
284     }
285
286   /* TC redundancy */
287
288   if(//cnf->tc_redundancy < MIN_TC_REDUNDANCY ||
289      cnf->tc_redundancy > MAX_TC_REDUNDANCY)
290     {
291       fprintf(stderr, "TC redundancy %d is not allowed\n", cnf->tc_redundancy);
292       return -1;
293     }
294
295   /* MPR coverage */
296   if(cnf->mpr_coverage < MIN_MPR_COVERAGE ||
297      cnf->mpr_coverage > MAX_MPR_COVERAGE)
298     {
299       fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
300       return -1;
301     }
302
303   /* Link Q and hysteresis cannot be activated at the same time */
304   if(cnf->use_hysteresis == OLSR_TRUE && cnf->lq_level)
305     {
306       fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
307       return -1;
308     }
309
310   /* Link quality level */
311
312   if(cnf->lq_level > MAX_LQ_LEVEL)
313     {
314       fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
315       return -1;
316     }
317
318   /* Link quality window size */
319   if(cnf->lq_level && (cnf->lq_wsize < MIN_LQ_WSIZE || cnf->lq_wsize > MAX_LQ_WSIZE))
320     {
321       fprintf(stderr, "LQ window size %d is not allowed\n", cnf->lq_wsize);
322       return -1;
323     }
324
325   if(in == NULL)
326     {
327       fprintf(stderr, "No interfaces configured!\n");
328       return -1;
329     }
330
331   /* Interfaces */
332   while(in)
333     {
334       io = in->cnf;
335
336       if(in->name == NULL || !strlen(in->name))
337         {
338           fprintf(stderr, "Interface has no name!\n");
339           return -1;
340         }
341
342       if(io == NULL)
343         {
344           fprintf(stderr, "Interface %s has no configuration!\n", in->name);
345           return -1;
346         }
347         
348       /* HELLO interval */
349       if(io->hello_params.emission_interval < cnf->pollrate ||
350          io->hello_params.emission_interval > io->hello_params.validity_time)
351         {
352           fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f)\n", io->hello_params.emission_interval, io->hello_params.validity_time);
353           return -1;
354         }
355
356       /* TC interval */
357       if(io->tc_params.emission_interval < cnf->pollrate ||
358          io->tc_params.emission_interval > io->tc_params.validity_time)
359         {
360           fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f)\n", io->tc_params.emission_interval, io->tc_params.validity_time);
361           return -1;
362         }
363
364       /* MID interval */
365       if(io->mid_params.emission_interval < cnf->pollrate ||
366          io->mid_params.emission_interval > io->mid_params.validity_time)
367         {
368           fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f)\n", io->mid_params.emission_interval, io->mid_params.validity_time);
369           return -1;
370         }
371
372       /* HNA interval */
373       if(io->hna_params.emission_interval < cnf->pollrate ||
374          io->hna_params.emission_interval > io->hna_params.validity_time)
375         {
376           fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f)\n", io->hna_params.emission_interval, io->hna_params.validity_time);
377           return -1;
378         }
379
380       in = in->next;
381     }
382
383   return 0;
384 }
385
386
387 void
388 olsrd_free_cnf(struct olsrd_config *cnf)
389 {
390   struct hna4_entry        *h4d, *h4 = cnf->hna4_entries;
391   struct hna6_entry        *h6d, *h6 = cnf->hna6_entries;
392   struct olsr_if           *ind, *in = cnf->interfaces;
393   struct plugin_entry      *ped, *pe = cnf->plugins;
394   struct olsr_lq_mult      *mult, *next_mult;
395   
396   while(h4)
397     {
398       h4d = h4;
399       h4 = h4->next;
400       free(h4d);
401     }
402
403   while(h6)
404     {
405       h6d = h6;
406       h6 = h6->next;
407       free(h6d);
408     }
409
410   while(in)
411     {
412       for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult)
413       {
414         next_mult = mult->next;
415         free(mult);
416       }
417
418       free(in->cnf);
419       ind = in;
420       in = in->next;
421       free(ind->name);
422       free(ind->config);
423       free(ind);
424     }
425
426   while(pe)
427     {
428       ped = pe;
429       pe = pe->next;
430       free(ped->name);
431       free(ped);
432     }
433
434   return;
435 }
436
437
438
439 struct olsrd_config *
440 olsrd_get_default_cnf()
441 {
442   cnf = malloc(sizeof(struct olsrd_config));
443   if (cnf == NULL)
444     {
445       fprintf(stderr, "Out of memory %s\n", __func__);
446       return NULL;
447   }
448
449   set_default_cnf(cnf);
450
451   return cnf;
452 }
453
454
455
456
457 void
458 set_default_cnf(struct olsrd_config *cnf)
459 {
460     memset(cnf, 0, sizeof(struct olsrd_config));
461     
462     cnf->debug_level = DEF_DEBUGLVL;
463     cnf->no_fork = OLSR_FALSE;
464     cnf->ip_version  = AF_INET;
465     cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
466     cnf->tos = DEF_TOS;
467     cnf->willingness_auto = DEF_WILL_AUTO;
468     cnf->ipc_connections = DEF_IPC_CONNECTIONS;
469     cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
470
471     cnf->use_hysteresis = DEF_USE_HYST;
472     cnf->hysteresis_param.scaling = HYST_SCALING;
473     cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
474     cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
475
476     cnf->pollrate = DEF_POLLRATE;
477
478     cnf->tc_redundancy = TC_REDUNDANCY;
479     cnf->mpr_coverage = MPR_COVERAGE;
480     cnf->lq_level = DEF_LQ_LEVEL;
481     cnf->lq_wsize = DEF_LQ_WSIZE;
482     cnf->clear_screen = DEF_CLEAR_SCREEN;
483 }
484
485
486
487
488 struct if_config_options *
489 get_default_if_config()
490 {
491   struct if_config_options *io = malloc(sizeof(struct if_config_options));
492   struct in6_addr in6;
493  
494   memset(io, 0, sizeof(struct if_config_options));
495
496   io->ipv6_addrtype = 1; /* XXX - FixMe */
497
498   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6) < 0)
499     {
500       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_SITE_LOCAL);
501       return NULL;
502     }
503   memcpy(&io->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
504
505   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6) < 0)
506     {
507       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_GLOBAL);
508       return NULL;
509     }
510   memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
511
512   io->lq_mult = NULL;
513
514   io->weight.fixed = OLSR_FALSE;
515   io->weight.value = 0;
516
517   io->hello_params.emission_interval = HELLO_INTERVAL;
518   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
519   io->tc_params.emission_interval = TC_INTERVAL;
520   io->tc_params.validity_time = TOP_HOLD_TIME;
521   io->mid_params.emission_interval = MID_INTERVAL;
522   io->mid_params.validity_time = MID_HOLD_TIME;
523   io->hna_params.emission_interval = HNA_INTERVAL;
524   io->hna_params.validity_time = HNA_HOLD_TIME;
525
526   return io;
527
528 }
529
530
531
532
533
534 int
535 olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
536 {
537   struct hna4_entry        *h4 = cnf->hna4_entries;
538   struct hna6_entry        *h6 = cnf->hna6_entries;
539   struct olsr_if           *in = cnf->interfaces;
540   struct plugin_entry      *pe = cnf->plugins;
541   struct plugin_param      *pp;
542   struct ipc_host          *ih = cnf->ipc_hosts;
543   struct ipc_net           *ie = cnf->ipc_nets;
544   struct olsr_lq_mult      *mult;
545
546   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
547   struct in_addr in4;
548
549   FILE *fd;
550
551   fd = fopen(fname, "w");
552
553   if(fd == NULL)
554     {
555       fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
556       return -1;
557     }
558
559   printf("Writing config to file \"%s\".... ", fname);
560
561   fprintf(fd, "#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
562
563   /* Debug level */
564   fprintf(fd, "# Debug level(0-9)\n# If set to 0 the daemon runs in the background\n\nDebugLevel\t%d\n\n", cnf->debug_level);
565
566   /* IP version */
567   if(cnf->ip_version == AF_INET6)
568     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t6\n\n");
569   else
570     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t4\n\n");
571
572
573   /* HNA IPv4 */
574   fprintf(fd, "# HNA IPv4 routes\n# syntax: netaddr netmask\n# Example Internet gateway:\n# 0.0.0.0 0.0.0.0\n\nHna4\n{\n");
575   while(h4)
576     {
577       in4.s_addr = h4->net.v4;
578       fprintf(fd, "    %s ", inet_ntoa(in4));
579       in4.s_addr = h4->netmask.v4;
580       fprintf(fd, "%s\n", inet_ntoa(in4));
581       h4 = h4->next;
582     }
583   fprintf(fd, "}\n\n");
584
585
586   /* HNA IPv6 */
587   fprintf(fd, "# HNA IPv6 routes\n# syntax: netaddr prefix\n# Example Internet gateway:\nHna6\n{\n");
588   while(h6)
589     {
590       fprintf(fd, "    %s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
591       h6 = h6->next;
592     }
593
594   fprintf(fd, "}\n\n");
595
596   /* No interfaces */
597   fprintf(fd, "# Should olsrd keep on running even if there are\n# no interfaces available? This is a good idea\n# for a PCMCIA/USB hotswap environment.\n# \"yes\" OR \"no\"\n\nAllowNoInt\t");
598   if(cnf->allow_no_interfaces)
599     fprintf(fd, "yes\n\n");
600   else
601     fprintf(fd, "no\n\n");
602
603   /* TOS */
604   fprintf(fd, "# TOS(type of service) value for\n# the IP header of control traffic.\n# default is 16\n\n");
605   fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
606
607   /* Willingness */
608   fprintf(fd, "# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
609   if(cnf->willingness_auto)
610     fprintf(fd, "#Willingness\t4\n\n");
611   else
612     fprintf(fd, "Willingness%d\n\n", cnf->willingness);
613
614   /* IPC */
615   fprintf(fd, "# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
616   fprintf(fd, "IpcConnect\n{\n");
617   fprintf(fd, "   MaxConnections  %d\n\n", cnf->ipc_connections);
618
619   while(ih)
620     {
621       in4.s_addr = ih->host.v4;
622       fprintf(fd, "   Host          %s\n", inet_ntoa(in4));
623       ih = ih->next;
624     }
625   fprintf(fd, "\n");
626   while(ie)
627     {
628       in4.s_addr = ie->net.v4;
629       fprintf(fd, "   Net           %s ", inet_ntoa(in4));
630       in4.s_addr = ie->mask.v4;
631       fprintf(fd, "%s\n", inet_ntoa(in4));
632       ie = ie->next;
633     }
634
635   fprintf(fd, "}\n\n");
636
637
638
639   /* Hysteresis */
640   fprintf(fd, "# Wether to use hysteresis or not\n# Hysteresis adds more robustness to the\n# link sensing but delays neighbor registration.\n# Used by default. 'yes' or 'no'\n\n");
641
642   if(cnf->use_hysteresis)
643     {
644       fprintf(fd, "UseHysteresis\tyes\n\n");
645       fprintf(fd, "# Hysteresis parameters\n# Do not alter these unless you know \n# what you are doing!\n# Set to auto by default. Allowed\n# values are floating point values\n# in the interval 0,1\n# THR_LOW must always be lower than\n# THR_HIGH!!\n\n");
646       fprintf(fd, "HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
647       fprintf(fd, "HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
648       fprintf(fd, "HystThrLow\t%0.2f\n", cnf->hysteresis_param.thr_low);
649     }
650   else
651     fprintf(fd, "UseHysteresis\tno\n\n");
652
653   fprintf(fd, "\n\n");
654
655   /* Pollrate */
656   fprintf(fd, "# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
657   fprintf(fd, "Pollrate\t%0.2f\n", cnf->pollrate);
658
659   /* TC redundancy */
660   fprintf(fd, "# TC redundancy\n# Specifies how much neighbor info should\n# be sent in TC messages\n# Possible values are:\n# 0 - only send MPR selectors\n# 1 - send MPR selectors and MPRs\n# 2 - send all neighbors\n#\n# defaults to 0\n\n");
661   fprintf(fd, "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
662
663   /* MPR coverage */
664   fprintf(fd, "# MPR coverage\n# Specifies how many MPRs a node should\n# try select to reach every 2 hop neighbor\n# Can be set to any integer >0\n# defaults to 1\n\n");
665
666   fprintf(fd, "MprCoverage\t%d\n\n", cnf->mpr_coverage);
667
668   fprintf(fd, "# Link quality level\n# 0 = do not use link quality\n# 1 = use link quality for MPR selection\n# 2 = use link quality for MPR selection and routing\n\n");
669   fprintf(fd, "LinkQualityLevel\t%d\n\n", cnf->lq_level);
670
671   fprintf(fd, "# Link quality window size\n\n");
672   fprintf(fd, "LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
673
674   fprintf(fd, "# Clear screen when printing debug output?\n\n");
675   fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
676
677   /* Plugins */
678   fprintf(fd, "# Olsrd plugins to load\n# This must be the absolute path to the file\n# or the loader will use the following scheme:\n# - Try the paths in the LD_LIBRARY_PATH \n#   environment variable.\n# - The list of libraries cached in /etc/ld.so.cache\n# - /lib, followed by /usr/lib\n\n");
679   if(pe)
680     {
681       while(pe)
682         {
683           fprintf(fd, "LoadPlugin \"%s\"\n{\n", pe->name);
684           pp = pe->params;
685           while(pp)
686             {
687               fprintf(fd, "    PlParam \"%s\" \"%s\"\n", pp->key, pp->value);
688               pp = pp->next;
689             }
690           fprintf(fd, "}\n");
691           pe = pe->next;
692         }
693     }
694   fprintf(fd, "\n");
695
696   
697   
698
699   /* Interfaces */
700   fprintf(fd, "# Interfaces\n\n");
701   /* Interfaces */
702   if(in)
703     {
704       while(in)
705         {
706           fprintf(fd, "Interface \"%s\"\n{\n", in->name);
707           fprintf(fd, "\n");
708       
709           fprintf(fd, "    # IPv4 broadcast address to use. The\n    # one usefull example would be 255.255.255.255\n    # If not defined the broadcastaddress\n    # every card is configured with is used\n\n");
710
711
712           if(in->cnf->ipv4_broadcast.v4)
713             {
714               in4.s_addr = in->cnf->ipv4_broadcast.v4;
715               fprintf(fd, "    Ip4Broadcast\t %s\n\n", inet_ntoa(in4));
716             }
717           else
718             {
719               fprintf(fd, "    #Ip4Broadcast\t255.255.255.255\n\n");
720             }
721           
722           
723           fprintf(fd, "    # IPv6 address scope to use.\n    # Must be 'site-local' or 'global'\n\n");
724           if(in->cnf->ipv6_addrtype)
725             fprintf(fd, "    Ip6AddrType \tsite-local\n\n");
726           else
727             fprintf(fd, "    Ip6AddrType \tglobal\n\n");
728           
729           fprintf(fd, "    # IPv6 multicast address to use when\n    # using site-local addresses.\n    # If not defined, ff05::15 is used\n");
730           fprintf(fd, "    Ip6MulticastSite\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
731           fprintf(fd, "    # IPv6 multicast address to use when\n    # using global addresses\n    # If not defined, ff0e::1 is used\n");
732           fprintf(fd, "    Ip6MulticastGlobal\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
733           
734           
735           
736           fprintf(fd, "    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
737           
738           
739           if(in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
740             fprintf(fd, "    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
741           else
742             fprintf(fd, "    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
743           if(in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
744             fprintf(fd, "    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
745           else
746             fprintf(fd, "    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
747           if(in->cnf->tc_params.emission_interval != TC_INTERVAL)
748             fprintf(fd, "    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
749           else
750             fprintf(fd, "    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
751           if(in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
752             fprintf(fd, "    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
753           else
754             fprintf(fd, "    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
755           if(in->cnf->mid_params.emission_interval != MID_INTERVAL)
756             fprintf(fd, "    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
757           else
758             fprintf(fd, "    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
759           if(in->cnf->mid_params.validity_time != MID_HOLD_TIME)
760             fprintf(fd, "    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
761           else
762             fprintf(fd, "    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
763           if(in->cnf->hna_params.emission_interval != HNA_INTERVAL)
764             fprintf(fd, "    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
765           else
766             fprintf(fd, "    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
767           if(in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
768             fprintf(fd, "    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);       
769           else
770             fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);      
771           
772           mult = in->cnf->lq_mult;
773
774           if (mult == NULL)
775             {
776               fprintf(fd, "    #LinkQualityMult\tdefault 1.0\n");
777             }
778           else
779             {
780               while (mult != NULL)
781                 {
782                   inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf,
783                             sizeof (ipv6_buf));
784                   
785                   fprintf(fd, "    LinkQualityMult\t%s %0.2f\n",
786                           ipv6_buf, mult->val);
787                   
788                   mult = mult->next;
789                 }
790             }
791
792           fprintf(fd, "    # When multiple links exist between hosts\n    # the weight of interface is used to determine\n    # the link to use. Normally the weight is\n    # automatically calculated by olsrd based\n    # on the characteristics of the interface,\n    # but here you can specify a fixed value.\n    # Olsrd will choose links with the lowest value.");
793           if(in->cnf->weight.fixed)
794             {
795               fprintf(fd, "    Weight\t %d\n\n", in->cnf->weight.value);
796             }
797           else
798             {
799               fprintf(fd, "    #Weight\t 0\n\n");
800             }
801
802           
803           fprintf(fd, "}\n\n");
804           in = in->next;
805         }
806
807     }
808
809
810   fprintf(fd, "\n# END AUTOGENERATED CONFIG\n");
811
812   fclose(fd);
813   printf("DONE\n");
814
815   return 1;
816 }
817
818
819
820
821
822 void
823 olsrd_print_cnf(struct olsrd_config *cnf)
824 {
825   struct hna4_entry        *h4 = cnf->hna4_entries;
826   struct hna6_entry        *h6 = cnf->hna6_entries;
827   struct olsr_if           *in = cnf->interfaces;
828   struct plugin_entry      *pe = cnf->plugins;
829   struct ipc_host          *ih = cnf->ipc_hosts;
830   struct ipc_net           *ie = cnf->ipc_nets;
831   struct olsr_lq_mult      *mult;
832   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
833   struct in_addr in4;
834
835   printf(" *** olsrd configuration ***\n");
836
837   printf("Debug Level      : %d\n", cnf->debug_level);
838   if(cnf->ip_version == AF_INET6)
839     printf("IpVersion        : 6\n");
840   else
841     printf("IpVersion        : 4\n");
842   if(cnf->allow_no_interfaces)
843     printf("No interfaces    : ALLOWED\n");
844   else
845     printf("No interfaces    : NOT ALLOWED\n");
846   printf("TOS              : 0x%02x\n", cnf->tos);
847   if(cnf->willingness_auto)
848     printf("Willingness      : AUTO\n");
849   else
850     printf("Willingness      : %d\n", cnf->willingness);
851
852   printf("IPC connections  : %d\n", cnf->ipc_connections);
853
854   while(ih)
855     {
856       in4.s_addr = ih->host.v4;
857       printf("\tHost %s\n", inet_ntoa(in4));
858       ih = ih->next;
859     }
860   
861   while(ie)
862     {
863       in4.s_addr = ie->net.v4;
864       printf("\tNet %s/", inet_ntoa(in4));
865       in4.s_addr = ie->mask.v4;
866       printf("%s\n", inet_ntoa(in4));
867       ie = ie->next;
868     }
869
870
871   printf("Pollrate         : %0.2f\n", cnf->pollrate);
872
873   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
874
875   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
876    
877   printf("LQ level         : %d\n", cnf->lq_level);
878
879   printf("LQ window size   : %d\n", cnf->lq_wsize);
880
881   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
882
883   /* Interfaces */
884   if(in)
885     {
886       printf("Interfaces:\n");
887       while(in)
888         {
889           printf(" dev: \"%s\"\n", in->name);
890           
891           if(in->cnf->ipv4_broadcast.v4)
892             {
893               in4.s_addr = in->cnf->ipv4_broadcast.v4;
894               printf("\tIPv4 broadcast           : %s\n", inet_ntoa(in4));
895             }
896           else
897             {
898               printf("\tIPv4 broadcast           : AUTO\n");
899             }
900           
901           if(in->cnf->ipv6_addrtype)
902             printf("\tIPv6 addrtype            : %s\n", in->cnf->ipv6_addrtype ? "site-local" : "global");
903           
904           //union olsr_ip_addr       ipv6_multi_site;
905           //union olsr_ip_addr       ipv6_multi_glbl;
906           printf("\tIPv6 multicast site/glbl : %s", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
907           printf("/%s\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
908           
909           printf("\tHELLO emission/validity  : %0.2f/%0.2f\n", in->cnf->hello_params.emission_interval, in->cnf->hello_params.validity_time);
910           printf("\tTC emission/validity     : %0.2f/%0.2f\n", in->cnf->tc_params.emission_interval, in->cnf->tc_params.validity_time);
911           printf("\tMID emission/validity    : %0.2f/%0.2f\n", in->cnf->mid_params.emission_interval, in->cnf->mid_params.validity_time);
912           printf("\tHNA emission/validity    : %0.2f/%0.2f\n", in->cnf->hna_params.emission_interval, in->cnf->hna_params.validity_time);
913           
914           for (mult = in->cnf->lq_mult; mult != NULL; mult = mult->next)
915           {
916             inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf,
917                       sizeof (ipv6_buf));
918
919             printf("\tLinkQualityMult          : %s %0.2f\n",
920                    ipv6_buf, mult->val);
921           }
922           
923           in = in->next;
924         }
925     }
926
927
928
929
930   /* Plugins */
931   if(pe)
932     {
933       printf("Plugins:\n");
934
935       while(pe)
936         {
937           printf("\tName: \"%s\"\n", pe->name);
938           pe = pe->next;
939         }
940     }
941
942   /* Hysteresis */
943   if(cnf->use_hysteresis)
944     {
945       printf("Using hysteresis:\n");
946       printf("\tScaling      : %0.2f\n", cnf->hysteresis_param.scaling);
947       printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
948     }
949   else
950     printf("Not using hysteresis\n");
951
952   /* HNA IPv4 */
953   if(h4)
954     {
955
956       printf("HNA4 entries:\n");
957       while(h4)
958         {
959           in4.s_addr = h4->net.v4;
960           printf("\t%s/", inet_ntoa(in4));
961           in4.s_addr = h4->netmask.v4;
962           printf("%s\n", inet_ntoa(in4));
963
964           h4 = h4->next;
965         }
966     }
967
968   /* HNA IPv6 */
969   if(h6)
970     {
971       printf("HNA6 entries:\n");
972       while(h6)
973         {
974           printf("\t%s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
975           h6 = h6->next;
976         }
977     }
978 }
979
980 void *olsrd_cnf_malloc(unsigned int len)
981 {
982   return malloc(len);
983 }
984
985 void olsrd_cnf_free(void *addr)
986 {
987   free(addr);
988 }
989
990 #if defined WIN32_STDIO_HACK
991 struct ioinfo
992 {
993         unsigned int handle;
994         unsigned char attr;
995         char buff;
996         int flag;
997         CRITICAL_SECTION lock;
998 };
999
1000 void win32_stdio_hack(unsigned int handle)
1001 {
1002   HMODULE lib;
1003   struct ioinfo **info;
1004
1005   lib = LoadLibrary("msvcrt.dll");
1006
1007   info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
1008
1009   // (*info)[1].handle = handle;
1010   // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
1011
1012   (*info)[2].handle = handle;
1013   (*info)[2].attr = 0x89;
1014
1015   // stdout->_file = 1;
1016   stderr->_file = 2;
1017
1018   // setbuf(stdout, NULL);
1019   setbuf(stderr, NULL);
1020 }
1021 #else
1022 void win32_stdio_hack(unsigned int handle) {}
1023 #endif