bf9c8bc06644b30df08271edea7b63298d25d810
[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.28 2004/11/21 17:10:28 tlopatic 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;
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
178   in = cnf->interfaces;
179
180   while(in)
181     {
182       /* set various stuff */
183       in->index = cnf->ifcnt++;
184       in->configured = OLSR_FALSE;
185       in->interf = NULL;
186       in = in->next;
187     }
188
189
190   return cnf;
191 }
192
193
194 int
195 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
196 {
197   struct olsr_if           *in = cnf->interfaces;
198   struct if_config_options *io;
199
200   /* Debug level */
201   if(cnf->debug_level < MIN_DEBUGLVL ||
202      cnf->debug_level > MAX_DEBUGLVL)
203     {
204       fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
205       return -1;
206     }
207
208   /* IP version */
209   if(cnf->ip_version != AF_INET &&
210      cnf->ip_version != AF_INET6)
211     {
212       fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
213       return -1;
214     }
215
216   /* TOS */
217   if(//cnf->tos < MIN_TOS ||
218      cnf->tos > MAX_TOS)
219     {
220       fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
221       return -1;
222     }
223
224   if(cnf->willingness_auto == OLSR_FALSE &&
225      (cnf->willingness < MIN_WILLINGNESS ||
226       cnf->willingness > MAX_WILLINGNESS))
227     {
228       fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
229       return -1;
230     }
231
232   /* Hysteresis */
233   if(cnf->use_hysteresis == OLSR_TRUE)
234     {
235       if(cnf->hysteresis_param.scaling < MIN_HYST_PARAM ||
236          cnf->hysteresis_param.scaling > MAX_HYST_PARAM)
237         {
238           fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
239           return -1;
240         }
241
242       if(cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low)
243         {
244           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);
245           return -1;
246         }
247
248       if(cnf->hysteresis_param.thr_high < MIN_HYST_PARAM ||
249          cnf->hysteresis_param.thr_high > MAX_HYST_PARAM)
250         {
251           fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
252           return -1;
253         }
254
255       if(cnf->hysteresis_param.thr_low < MIN_HYST_PARAM ||
256          cnf->hysteresis_param.thr_low > MAX_HYST_PARAM)
257         {
258           fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
259           return -1;
260         }
261     }
262
263   /* Pollrate */
264
265   if(cnf->pollrate < MIN_POLLRATE ||
266      cnf->pollrate > MAX_POLLRATE)
267     {
268       fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
269       return -1;
270     }
271
272   /* TC redundancy */
273
274   if(//cnf->tc_redundancy < MIN_TC_REDUNDANCY ||
275      cnf->tc_redundancy > MAX_TC_REDUNDANCY)
276     {
277       fprintf(stderr, "TC redundancy %d is not allowed\n", cnf->tc_redundancy);
278       return -1;
279     }
280
281   /* MPR coverage */
282   if(cnf->mpr_coverage < MIN_MPR_COVERAGE ||
283      cnf->mpr_coverage > MAX_MPR_COVERAGE)
284     {
285       fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
286       return -1;
287     }
288
289   /* Link quality window size */
290
291   if (cnf->lq_wsize < MIN_LQ_WSIZE || cnf->lq_wsize > MAX_LQ_WSIZE)
292     {
293       fprintf(stderr, "LQ window size %d is not allowed\n", cnf->lq_wsize);
294       return -1;
295     }
296
297   /* Link quality level */
298
299   if (cnf->lq_level > MAX_LQ_LEVEL)
300     {
301       fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
302       return -1;
303     }
304
305   if(in == NULL)
306     {
307       fprintf(stderr, "No interfaces configured!\n");
308       return -1;
309     }
310
311   /* Interfaces */
312   while(in)
313     {
314       io = in->cnf;
315
316       if(in->name == NULL || !strlen(in->name))
317         {
318           fprintf(stderr, "Interface has no name!\n");
319           return -1;
320         }
321
322       if(io == NULL)
323         {
324           fprintf(stderr, "Interface %s has no configuration!\n", in->name);
325           return -1;
326         }
327
328       /* HELLO interval */
329       if(io->hello_params.emission_interval < cnf->pollrate ||
330          io->hello_params.emission_interval > io->hello_params.validity_time)
331         {
332           fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f)\n", io->hello_params.emission_interval, io->hello_params.validity_time);
333           return -1;
334         }
335
336       /* TC interval */
337       if(io->tc_params.emission_interval < cnf->pollrate ||
338          io->tc_params.emission_interval > io->tc_params.validity_time)
339         {
340           fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f)\n", io->tc_params.emission_interval, io->tc_params.validity_time);
341           return -1;
342         }
343
344       /* MID interval */
345       if(io->mid_params.emission_interval < cnf->pollrate ||
346          io->mid_params.emission_interval > io->mid_params.validity_time)
347         {
348           fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f)\n", io->mid_params.emission_interval, io->mid_params.validity_time);
349           return -1;
350         }
351
352       /* HNA interval */
353       if(io->hna_params.emission_interval < cnf->pollrate ||
354          io->hna_params.emission_interval > io->hna_params.validity_time)
355         {
356           fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f)\n", io->hna_params.emission_interval, io->hna_params.validity_time);
357           return -1;
358         }
359
360       in = in->next;
361     }
362
363   return 0;
364 }
365
366
367 void
368 olsrd_free_cnf(struct olsrd_config *cnf)
369 {
370   struct hna4_entry        *h4d, *h4 = cnf->hna4_entries;
371   struct hna6_entry        *h6d, *h6 = cnf->hna6_entries;
372   struct olsr_if           *ind, *in = cnf->interfaces;
373   struct plugin_entry      *ped, *pe = cnf->plugins;
374   
375   while(h4)
376     {
377       h4d = h4;
378       h4 = h4->next;
379       free(h4d);
380     }
381
382   while(h6)
383     {
384       h6d = h6;
385       h6 = h6->next;
386       free(h6d);
387     }
388
389   while(in)
390     {
391       free(in->cnf);
392       ind = in;
393       in = in->next;
394       free(ind->name);
395       free(ind->config);
396       free(ind);
397     }
398
399   while(pe)
400     {
401       ped = pe;
402       pe = pe->next;
403       free(ped->name);
404       free(ped);
405     }
406
407   return;
408 }
409
410
411
412 struct olsrd_config *
413 olsrd_get_default_cnf()
414 {
415   cnf = malloc(sizeof(struct olsrd_config));
416   if (cnf == NULL)
417     {
418       fprintf(stderr, "Out of memory %s\n", __func__);
419       return NULL;
420   }
421
422   set_default_cnf(cnf);
423
424   return cnf;
425 }
426
427
428
429
430 void
431 set_default_cnf(struct olsrd_config *cnf)
432 {
433     memset(cnf, 0, sizeof(struct olsrd_config));
434     
435     cnf->debug_level = DEF_DEBUGLVL;
436     cnf->ip_version  = AF_INET;
437     cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
438     cnf->tos = DEF_TOS;
439     cnf->willingness_auto = DEF_WILL_AUTO;
440     cnf->ipc_connections = DEF_IPC_CONNECTIONS;
441     cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
442
443     cnf->use_hysteresis = DEF_USE_HYST;
444     cnf->hysteresis_param.scaling = HYST_SCALING;
445     cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
446     cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
447
448     cnf->pollrate = DEF_POLLRATE;
449
450     cnf->tc_redundancy = TC_REDUNDANCY;
451     cnf->mpr_coverage = MPR_COVERAGE;
452     cnf->lq_level = DEF_LQ_LEVEL;
453     cnf->lq_wsize = DEF_LQ_WSIZE;
454     cnf->clear_screen = DEF_CLEAR_SCREEN;
455 }
456
457
458
459
460 struct if_config_options *
461 get_default_if_config()
462 {
463   struct if_config_options *io = malloc(sizeof(struct if_config_options));
464   struct in6_addr in6;
465  
466   memset(io, 0, sizeof(struct if_config_options));
467
468   io->ipv6_addrtype = 1; /* XXX - FixMe */
469
470   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6) < 0)
471     {
472       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_SITE_LOCAL);
473       return NULL;
474     }
475   memcpy(&io->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
476
477   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6) < 0)
478     {
479       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_GLOBAL);
480       return NULL;
481     }
482   memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
483
484
485   io->hello_params.emission_interval = HELLO_INTERVAL;
486   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
487   io->tc_params.emission_interval = TC_INTERVAL;
488   io->tc_params.validity_time = TOP_HOLD_TIME;
489   io->mid_params.emission_interval = MID_INTERVAL;
490   io->mid_params.validity_time = MID_HOLD_TIME;
491   io->hna_params.emission_interval = HNA_INTERVAL;
492   io->hna_params.validity_time = HNA_HOLD_TIME;
493
494   return io;
495
496 }
497
498
499
500
501
502 int
503 olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
504 {
505   struct hna4_entry        *h4 = cnf->hna4_entries;
506   struct hna6_entry        *h6 = cnf->hna6_entries;
507   struct olsr_if           *in = cnf->interfaces;
508   struct plugin_entry      *pe = cnf->plugins;
509   struct plugin_param      *pp;
510   struct ipc_host          *ih = cnf->ipc_hosts;
511   struct ipc_net           *ie = cnf->ipc_nets;
512
513   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
514   struct in_addr in4;
515
516   FILE *fd;
517
518   fd = fopen(fname, "w");
519
520   if(fd == NULL)
521     {
522       fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
523       return -1;
524     }
525
526   printf("Writing config to file \"%s\".... ", fname);
527
528   fprintf(fd, "#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
529
530   /* Debug level */
531   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);
532
533   /* IP version */
534   if(cnf->ip_version == AF_INET6)
535     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t6\n\n");
536   else
537     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t4\n\n");
538
539
540   /* HNA IPv4 */
541   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");
542   while(h4)
543     {
544       in4.s_addr = h4->net.v4;
545       fprintf(fd, "    %s ", inet_ntoa(in4));
546       in4.s_addr = h4->netmask.v4;
547       fprintf(fd, "%s\n", inet_ntoa(in4));
548       h4 = h4->next;
549     }
550   fprintf(fd, "}\n\n");
551
552
553   /* HNA IPv6 */
554   fprintf(fd, "# HNA IPv6 routes\n# syntax: netaddr prefix\n# Example Internet gateway:\nHna6\n{\n");
555   while(h6)
556     {
557       fprintf(fd, "    %s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
558       h6 = h6->next;
559     }
560
561   fprintf(fd, "}\n\n");
562
563   /* No interfaces */
564   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");
565   if(cnf->allow_no_interfaces)
566     fprintf(fd, "yes\n\n");
567   else
568     fprintf(fd, "no\n\n");
569
570   /* TOS */
571   fprintf(fd, "# TOS(type of service) value for\n# the IP header of control traffic.\n# default is 16\n\n");
572   fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
573
574   /* Willingness */
575   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");
576   if(cnf->willingness_auto)
577     fprintf(fd, "#Willingness\t4\n\n");
578   else
579     fprintf(fd, "Willingness%d\n\n", cnf->willingness);
580
581   /* IPC */
582   fprintf(fd, "# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
583   fprintf(fd, "IpcConnect\n{\n");
584   fprintf(fd, "   MaxConnections  %d\n\n", cnf->ipc_connections);
585
586   while(ih)
587     {
588       in4.s_addr = ih->host.v4;
589       fprintf(fd, "   Host          %s\n", inet_ntoa(in4));
590       ih = ih->next;
591     }
592   fprintf(fd, "\n");
593   while(ie)
594     {
595       in4.s_addr = ie->net.v4;
596       fprintf(fd, "   Net           %s ", inet_ntoa(in4));
597       in4.s_addr = ie->mask.v4;
598       fprintf(fd, "%s\n", inet_ntoa(in4));
599       ie = ie->next;
600     }
601
602   fprintf(fd, "}\n\n");
603
604
605
606   /* Hysteresis */
607   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");
608
609   if(cnf->use_hysteresis)
610     {
611       fprintf(fd, "UseHysteresis\tyes\n\n");
612       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");
613       fprintf(fd, "HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
614       fprintf(fd, "HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
615       fprintf(fd, "HystThrLow\t%0.2f\n", cnf->hysteresis_param.thr_low);
616     }
617   else
618     fprintf(fd, "UseHysteresis\tno\n\n");
619
620   fprintf(fd, "\n\n");
621
622   /* Pollrate */
623   fprintf(fd, "# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
624   fprintf(fd, "Pollrate\t%0.2f\n", cnf->pollrate);
625
626   /* TC redundancy */
627   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");
628   fprintf(fd, "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
629
630   /* MPR coverage */
631   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");
632
633   fprintf(fd, "MprCoverage\t%d\n\n", cnf->mpr_coverage);
634
635   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");
636   fprintf(fd, "LinkQualityLevel\t%d\n\n", cnf->lq_level);
637
638   fprintf(fd, "# Link quality window size\n\n");
639   fprintf(fd, "LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
640
641   fprintf(fd, "# Clear screen when printing debug output?\n\n");
642   fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
643
644   /* Plugins */
645   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");
646   if(pe)
647     {
648       while(pe)
649         {
650           fprintf(fd, "LoadPlugin \"%s\"\n{\n", pe->name);
651           pp = pe->params;
652           while(pp)
653             {
654               fprintf(fd, "    PlParam \"%s\" \"%s\"\n", pp->key, pp->value);
655               pp = pp->next;
656             }
657           fprintf(fd, "}\n");
658           pe = pe->next;
659         }
660     }
661   fprintf(fd, "\n");
662
663   
664   
665
666   /* Interfaces */
667   fprintf(fd, "# Interfaces\n\n");
668   /* Interfaces */
669   if(in)
670     {
671       while(in)
672         {
673           fprintf(fd, "Interface \"%s\"\n{\n", in->name);
674           fprintf(fd, "\n");
675       
676           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");
677
678           if(in->cnf->ipv4_broadcast.v4)
679             {
680               in4.s_addr = in->cnf->ipv4_broadcast.v4;
681               fprintf(fd, "    Ip4Broadcast\t %s\n\n", inet_ntoa(in4));
682             }
683           else
684             {
685               fprintf(fd, "    #Ip4Broadcast\t255.255.255.255\n\n");
686             }
687           
688           
689           fprintf(fd, "    # IPv6 address scope to use.\n    # Must be 'site-local' or 'global'\n\n");
690           if(in->cnf->ipv6_addrtype)
691             fprintf(fd, "    Ip6AddrType \tsite-local\n\n");
692           else
693             fprintf(fd, "    Ip6AddrType \tglobal\n\n");
694           
695           fprintf(fd, "    # IPv6 multicast address to use when\n    # using site-local addresses.\n    # If not defined, ff05::15 is used\n");
696           fprintf(fd, "    Ip6MulticastSite\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
697           fprintf(fd, "    # IPv6 multicast address to use when\n    # using global addresses\n    # If not defined, ff0e::1 is used\n");
698           fprintf(fd, "    Ip6MulticastGlobal\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
699           
700           
701           
702           fprintf(fd, "    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
703           
704           
705           if(in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
706             fprintf(fd, "    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
707           else
708             fprintf(fd, "    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
709           if(in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
710             fprintf(fd, "    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
711           else
712             fprintf(fd, "    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
713           if(in->cnf->tc_params.emission_interval != TC_INTERVAL)
714             fprintf(fd, "    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
715           else
716             fprintf(fd, "    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
717           if(in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
718             fprintf(fd, "    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
719           else
720             fprintf(fd, "    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
721           if(in->cnf->mid_params.emission_interval != MID_INTERVAL)
722             fprintf(fd, "    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
723           else
724             fprintf(fd, "    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
725           if(in->cnf->mid_params.validity_time != MID_HOLD_TIME)
726             fprintf(fd, "    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
727           else
728             fprintf(fd, "    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
729           if(in->cnf->hna_params.emission_interval != HNA_INTERVAL)
730             fprintf(fd, "    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
731           else
732             fprintf(fd, "    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
733           if(in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
734             fprintf(fd, "    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);       
735           else
736             fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);      
737           
738           
739           
740           fprintf(fd, "}\n\n");
741           in = in->next;
742         }
743
744     }
745
746
747   fprintf(fd, "\n# END AUTOGENERATED CONFIG\n");
748
749   fclose(fd);
750   printf("DONE\n");
751
752   return 1;
753 }
754
755
756
757
758
759 void
760 olsrd_print_cnf(struct olsrd_config *cnf)
761 {
762   struct hna4_entry        *h4 = cnf->hna4_entries;
763   struct hna6_entry        *h6 = cnf->hna6_entries;
764   struct olsr_if           *in = cnf->interfaces;
765   struct plugin_entry      *pe = cnf->plugins;
766   struct ipc_host          *ih = cnf->ipc_hosts;
767   struct ipc_net           *ie = cnf->ipc_nets;
768   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
769   struct in_addr in4;
770
771   printf(" *** olsrd configuration ***\n");
772
773   printf("Debug Level      : %d\n", cnf->debug_level);
774   if(cnf->ip_version == AF_INET6)
775     printf("IpVersion        : 6\n");
776   else
777     printf("IpVersion        : 4\n");
778   if(cnf->allow_no_interfaces)
779     printf("No interfaces    : ALLOWED\n");
780   else
781     printf("No interfaces    : NOT ALLOWED\n");
782   printf("TOS              : 0x%02x\n", cnf->tos);
783   if(cnf->willingness_auto)
784     printf("Willingness      : AUTO\n");
785   else
786     printf("Willingness      : %d\n", cnf->willingness);
787
788   printf("IPC connections  : %d\n", cnf->ipc_connections);
789
790   while(ih)
791     {
792       in4.s_addr = ih->host.v4;
793       printf("\tHost %s\n", inet_ntoa(in4));
794       ih = ih->next;
795     }
796   
797   while(ie)
798     {
799       in4.s_addr = ie->net.v4;
800       printf("\tNet %s/", inet_ntoa(in4));
801       in4.s_addr = ie->mask.v4;
802       printf("%s\n", inet_ntoa(in4));
803       ie = ie->next;
804     }
805
806
807   printf("Pollrate         : %0.2f\n", cnf->pollrate);
808
809   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
810
811   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
812    
813   printf("LQ level         : %d\n", cnf->lq_level);
814
815   printf("LQ window size   : %d\n", cnf->lq_wsize);
816
817   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
818
819   /* Interfaces */
820   if(in)
821     {
822       printf("Interfaces:\n");
823       while(in)
824         {
825           printf(" dev: \"%s\"\n", in->name);
826           
827           if(in->cnf->ipv4_broadcast.v4)
828             {
829               in4.s_addr = in->cnf->ipv4_broadcast.v4;
830               printf("\tIPv4 broadcast           : %s\n", inet_ntoa(in4));
831             }
832           else
833             {
834               printf("\tIPv4 broadcast           : AUTO\n");
835             }
836           
837           if(in->cnf->ipv6_addrtype)
838             printf("\tIPv6 addrtype            : %s\n", in->cnf->ipv6_addrtype ? "site-local" : "global");
839           
840           //union olsr_ip_addr       ipv6_multi_site;
841           //union olsr_ip_addr       ipv6_multi_glbl;
842           printf("\tIPv6 multicast site/glbl : %s", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
843           printf("/%s\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
844           
845           printf("\tHELLO emission/validity  : %0.2f/%0.2f\n", in->cnf->hello_params.emission_interval, in->cnf->hello_params.validity_time);
846           printf("\tTC emission/validity     : %0.2f/%0.2f\n", in->cnf->tc_params.emission_interval, in->cnf->tc_params.validity_time);
847           printf("\tMID emission/validity    : %0.2f/%0.2f\n", in->cnf->mid_params.emission_interval, in->cnf->mid_params.validity_time);
848           printf("\tHNA emission/validity    : %0.2f/%0.2f\n", in->cnf->hna_params.emission_interval, in->cnf->hna_params.validity_time);
849           
850           
851           
852           in = in->next;
853
854         }
855     }
856
857
858
859
860   /* Plugins */
861   if(pe)
862     {
863       printf("Plugins:\n");
864
865       while(pe)
866         {
867           printf("\tName: \"%s\"\n", pe->name);
868           pe = pe->next;
869         }
870     }
871
872   /* Hysteresis */
873   if(cnf->use_hysteresis)
874     {
875       printf("Using hysteresis:\n");
876       printf("\tScaling      : %0.2f\n", cnf->hysteresis_param.scaling);
877       printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
878     }
879   else
880     printf("Not using hysteresis\n");
881
882   /* HNA IPv4 */
883   if(h4)
884     {
885
886       printf("HNA4 entries:\n");
887       while(h4)
888         {
889           in4.s_addr = h4->net.v4;
890           printf("\t%s/", inet_ntoa(in4));
891           in4.s_addr = h4->netmask.v4;
892           printf("%s\n", inet_ntoa(in4));
893
894           h4 = h4->next;
895         }
896     }
897
898   /* HNA IPv6 */
899   if(h6)
900     {
901       printf("HNA6 entries:\n");
902       while(h6)
903         {
904           printf("\t%s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
905           h6 = h6->next;
906         }
907     }
908 }
909
910 void *olsrd_cnf_malloc(unsigned int len)
911 {
912   return malloc(len);
913 }
914
915 void olsrd_cnf_free(void *addr)
916 {
917   free(addr);
918 }
919
920 #if defined WIN32_STDIO_HACK
921 struct ioinfo
922 {
923         unsigned int handle;
924         unsigned char attr;
925         char buff;
926         int flag;
927         CRITICAL_SECTION lock;
928 };
929
930 void win32_stdio_hack(unsigned int handle)
931 {
932   HMODULE lib;
933   struct ioinfo **info;
934
935   lib = LoadLibrary("msvcrt.dll");
936
937   info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
938
939   // (*info)[1].handle = handle;
940   // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
941
942   (*info)[2].handle = handle;
943   (*info)[2].attr = 0x89;
944
945   // stdout->_file = 1;
946   stderr->_file = 2;
947
948   // setbuf(stdout, NULL);
949   setbuf(stderr, NULL);
950 }
951 #else
952 void win32_stdio_hack(unsigned int handle) {}
953 #endif