4a239703a70cb13b655115e1a9d3957e69dc3b56
[olsrd.git] / src / cfgparser / olsrd_conf.c
1 /*
2  * OLSR ad-hoc routing table management protocol config parser
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@olsr.org)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org 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  * olsr.org 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  * $Id: olsrd_conf.c,v 1.22 2004/11/20 21:52:09 kattemat Exp $
23  *
24  */
25
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35
36 #include "olsrd_conf.h"
37
38
39 extern FILE *yyin;
40 extern int yyparse(void);
41
42
43 #ifdef MAKELIB
44
45 /* Build as DLL */
46
47 void __attribute__ ((constructor)) 
48 my_init(void);
49
50 void __attribute__ ((destructor)) 
51 my_fini(void);
52
53
54 /**
55  *Constructor
56  */
57 void
58 my_init()
59 {
60   /* Print plugin info to stdout */
61   printf("olsrd config file parser %s loaded\n", PARSER_VERSION);
62
63   return;
64 }
65
66 /**
67  *Destructor
68  */
69 void
70 my_fini()
71 {
72   printf("See you around!\n");
73   return;
74 }
75
76 #else
77
78 #ifdef MAKEBIN
79
80 /* Build as standalone binary */
81 int 
82 main(int argc, char *argv[])
83 {
84   struct olsrd_config *cnf;
85
86   if(argc == 1)
87     {
88       fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
89       exit(EXIT_FAILURE);
90     }
91
92   if((cnf = olsrd_parse_cnf(argv[1])) != NULL)
93     {
94       if((argc > 2) && (!strcmp(argv[2], "-print")))
95         {
96           olsrd_print_cnf(cnf);  
97           olsrd_write_cnf(cnf, "./out.conf");
98         }
99       else
100         printf("Use -print to view parsed values\n");
101       printf("Configfile parsed OK\n");
102     }
103   else
104     {
105       printf("Failed parsing \"%s\"\n", argv[1]);
106     }
107
108   return 0;
109 }
110
111 #else
112
113 /* Build as part of olsrd */
114
115
116 #endif
117
118 #endif
119
120 struct olsrd_config *
121 olsrd_parse_cnf(char *filename)
122 {
123   struct olsr_if *in;
124
125   cnf = malloc(sizeof(struct olsrd_config));
126   if (cnf == NULL)
127     {
128       fprintf(stderr, "Out of memory %s\n", __func__);
129       return NULL;
130   }
131
132   set_default_cnf(cnf);
133
134   printf("Parsing file: \"%s\"\n", filename);
135
136   yyin = fopen(filename, "r");
137   
138   if (yyin == NULL)
139     {
140       fprintf(stderr, "Cannot open configuration file '%s': %s.\n",
141               filename, strerror(errno));
142       free(cnf);
143       return NULL;
144   }
145
146   current_line = 1;
147
148   if (yyparse() != 0)
149     {
150       fclose(yyin);
151       olsrd_free_cnf(cnf);
152       exit(0);
153     }
154   
155   fclose(yyin);
156
157
158   in = cnf->interfaces;
159
160   while(in)
161     {
162       /* set various stuff */
163       in->index = cnf->ifcnt++;
164       in->configured = OLSR_FALSE;
165       in->interf = NULL;
166       in = in->next;
167     }
168
169
170   return cnf;
171 }
172
173
174 int
175 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
176 {
177   struct olsr_if           *in = cnf->interfaces;
178   struct if_config_options *io;
179
180   /* Debug level */
181   if(cnf->debug_level < MIN_DEBUGLVL ||
182      cnf->debug_level > MAX_DEBUGLVL)
183     {
184       fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
185       return -1;
186     }
187
188   /* IP version */
189   if(cnf->ip_version != AF_INET &&
190      cnf->ip_version != AF_INET6)
191     {
192       fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
193       return -1;
194     }
195
196   /* TOS */
197   if(//cnf->tos < MIN_TOS ||
198      cnf->tos > MAX_TOS)
199     {
200       fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
201       return -1;
202     }
203
204   if(cnf->willingness_auto == OLSR_FALSE &&
205      (cnf->willingness < MIN_WILLINGNESS ||
206       cnf->willingness > MAX_WILLINGNESS))
207     {
208       fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
209       return -1;
210     }
211
212   /* Hysteresis */
213   if(cnf->use_hysteresis == OLSR_TRUE)
214     {
215       if(cnf->hysteresis_param.scaling < MIN_HYST_PARAM ||
216          cnf->hysteresis_param.scaling > MAX_HYST_PARAM)
217         {
218           fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
219           return -1;
220         }
221
222       if(cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low)
223         {
224           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);
225           return -1;
226         }
227
228       if(cnf->hysteresis_param.thr_high < MIN_HYST_PARAM ||
229          cnf->hysteresis_param.thr_high > MAX_HYST_PARAM)
230         {
231           fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
232           return -1;
233         }
234
235       if(cnf->hysteresis_param.thr_low < MIN_HYST_PARAM ||
236          cnf->hysteresis_param.thr_low > MAX_HYST_PARAM)
237         {
238           fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
239           return -1;
240         }
241     }
242
243   /* Pollrate */
244
245   if(cnf->pollrate < MIN_POLLRATE ||
246      cnf->pollrate > MAX_POLLRATE)
247     {
248       fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
249       return -1;
250     }
251
252   /* TC redundancy */
253
254   if(//cnf->tc_redundancy < MIN_TC_REDUNDANCY ||
255      cnf->tc_redundancy > MAX_TC_REDUNDANCY)
256     {
257       fprintf(stderr, "TC redundancy %d is not allowed\n", cnf->tc_redundancy);
258       return -1;
259     }
260
261   /* MPR coverage */
262   if(cnf->mpr_coverage < MIN_MPR_COVERAGE ||
263      cnf->mpr_coverage > MAX_MPR_COVERAGE)
264     {
265       fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
266       return -1;
267     }
268
269   if(cnf->allow_no_interfaces == OLSR_FALSE &&
270      in == NULL)
271     {
272       fprintf(stderr, "No interfaces configured - and allow no int set to FALSE!\n");
273       return -1;
274     }
275
276   /* Interfaces */
277   while(in)
278     {
279       io = in->cnf;
280
281       if(in->name == NULL || !strlen(in->name))
282         {
283           fprintf(stderr, "Interface has no name!\n");
284           return -1;
285         }
286
287       if(io == NULL)
288         {
289           fprintf(stderr, "Interface %s has no configuration!\n", in->name);
290           return -1;
291         }
292
293       /* HELLO interval */
294       if(io->hello_params.emission_interval < cnf->pollrate ||
295          io->hello_params.emission_interval > io->hello_params.validity_time)
296         {
297           fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f)\n", io->hello_params.emission_interval, io->hello_params.validity_time);
298           return -1;
299         }
300
301       /* TC interval */
302       if(io->tc_params.emission_interval < cnf->pollrate ||
303          io->tc_params.emission_interval > io->tc_params.validity_time)
304         {
305           fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f)\n", io->tc_params.emission_interval, io->tc_params.validity_time);
306           return -1;
307         }
308
309       /* MID interval */
310       if(io->mid_params.emission_interval < cnf->pollrate ||
311          io->mid_params.emission_interval > io->mid_params.validity_time)
312         {
313           fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f)\n", io->mid_params.emission_interval, io->mid_params.validity_time);
314           return -1;
315         }
316
317       /* HNA interval */
318       if(io->hna_params.emission_interval < cnf->pollrate ||
319          io->hna_params.emission_interval > io->hna_params.validity_time)
320         {
321           fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f)\n", io->hna_params.emission_interval, io->hna_params.validity_time);
322           return -1;
323         }
324
325       in = in->next;
326     }
327
328   return 0;
329 }
330
331
332 void
333 olsrd_free_cnf(struct olsrd_config *cnf)
334 {
335   struct hna4_entry        *h4d, *h4 = cnf->hna4_entries;
336   struct hna6_entry        *h6d, *h6 = cnf->hna6_entries;
337   struct olsr_if           *ind, *in = cnf->interfaces;
338   struct plugin_entry      *ped, *pe = cnf->plugins;
339   
340   while(h4)
341     {
342       h4d = h4;
343       h4 = h4->next;
344       free(h4d);
345     }
346
347   while(h6)
348     {
349       h6d = h6;
350       h6 = h6->next;
351       free(h6d);
352     }
353
354   while(in)
355     {
356       free(in->cnf);
357       ind = in;
358       in = in->next;
359       free(ind->name);
360       free(ind->config);
361       free(ind);
362     }
363
364   while(pe)
365     {
366       ped = pe;
367       pe = pe->next;
368       free(ped->name);
369       free(ped);
370     }
371
372   return;
373 }
374
375
376
377 struct olsrd_config *
378 olsrd_get_default_cnf()
379 {
380   cnf = malloc(sizeof(struct olsrd_config));
381   if (cnf == NULL)
382     {
383       fprintf(stderr, "Out of memory %s\n", __func__);
384       return NULL;
385   }
386
387   set_default_cnf(cnf);
388
389   return cnf;
390 }
391
392
393
394
395 void
396 set_default_cnf(struct olsrd_config *cnf)
397 {
398     memset(cnf, 0, sizeof(struct olsrd_config));
399     
400     cnf->debug_level = DEF_DEBUGLVL;
401     cnf->ip_version  = AF_INET;
402     cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
403     cnf->tos = DEF_TOS;
404     cnf->willingness_auto = DEF_WILL_AUTO;
405     cnf->ipc_connections = DEF_IPC_CONNECTIONS;
406     cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
407
408     cnf->use_hysteresis = DEF_USE_HYST;
409     cnf->hysteresis_param.scaling = HYST_SCALING;
410     cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
411     cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
412
413     cnf->pollrate = DEF_POLLRATE;
414
415     cnf->tc_redundancy = TC_REDUNDANCY;
416     cnf->mpr_coverage = MPR_COVERAGE;
417     cnf->lq_level = DEF_LQ_LEVEL;
418     cnf->lq_wsize = DEF_LQ_WSIZE;
419     cnf->clear_screen = DEF_CLEAR_SCREEN;
420 }
421
422
423
424
425 struct if_config_options *
426 get_default_if_config()
427 {
428   struct if_config_options *io = malloc(sizeof(struct if_config_options));
429   struct in6_addr in6;
430  
431   memset(io, 0, sizeof(struct if_config_options));
432
433   io->ipv6_addrtype = 1; /* XXX - FixMe */
434
435   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6) < 0)
436     {
437       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_SITE_LOCAL);
438       exit(EXIT_FAILURE);
439     }
440   memcpy(&io->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
441
442   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6) < 0)
443     {
444       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_GLOBAL);
445       exit(EXIT_FAILURE);
446     }
447   memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
448
449
450   io->hello_params.emission_interval = HELLO_INTERVAL;
451   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
452   io->tc_params.emission_interval = TC_INTERVAL;
453   io->tc_params.validity_time = TOP_HOLD_TIME;
454   io->mid_params.emission_interval = MID_INTERVAL;
455   io->mid_params.validity_time = MID_HOLD_TIME;
456   io->hna_params.emission_interval = HNA_INTERVAL;
457   io->hna_params.validity_time = HNA_HOLD_TIME;
458
459   return io;
460
461 }
462
463
464
465
466
467 int
468 olsrd_write_cnf(struct olsrd_config *cnf, char *fname)
469 {
470   struct hna4_entry        *h4 = cnf->hna4_entries;
471   struct hna6_entry        *h6 = cnf->hna6_entries;
472   struct olsr_if           *in = cnf->interfaces;
473   struct plugin_entry      *pe = cnf->plugins;
474   struct plugin_param      *pp;
475   struct ipc_host          *ih = cnf->ipc_hosts;
476   struct ipc_net           *ie = cnf->ipc_nets;
477
478   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
479   struct in_addr in4;
480
481   FILE *fd;
482
483   fd = fopen(fname, "w");
484
485   if(fd == NULL)
486     {
487       fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
488       return -1;
489     }
490
491   printf("Writing config to file \"%s\".... ", fname);
492
493   fprintf(fd, "#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
494
495   /* Debug level */
496   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);
497
498   /* IP version */
499   if(cnf->ip_version == AF_INET6)
500     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t6\n\n");
501   else
502     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t4\n\n");
503
504
505   /* HNA IPv4 */
506   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");
507   while(h4)
508     {
509       in4.s_addr = h4->net.v4;
510       fprintf(fd, "    %s ", inet_ntoa(in4));
511       in4.s_addr = h4->netmask.v4;
512       fprintf(fd, "%s\n", inet_ntoa(in4));
513       h4 = h4->next;
514     }
515   fprintf(fd, "}\n\n");
516
517
518   /* HNA IPv6 */
519   fprintf(fd, "# HNA IPv6 routes\n# syntax: netaddr prefix\n# Example Internet gateway:\nHna6\n{\n");
520   while(h6)
521     {
522       fprintf(fd, "    %s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
523       h6 = h6->next;
524     }
525
526   fprintf(fd, "}\n\n");
527
528   /* No interfaces */
529   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");
530   if(cnf->allow_no_interfaces)
531     fprintf(fd, "yes\n\n");
532   else
533     fprintf(fd, "no\n\n");
534
535   /* TOS */
536   fprintf(fd, "# TOS(type of service) value for\n# the IP header of control traffic.\n# default is 16\n\n");
537   fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
538
539   /* Willingness */
540   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");
541   if(cnf->willingness_auto)
542     fprintf(fd, "#Willingness\t4\n\n");
543   else
544     fprintf(fd, "Willingness%d\n\n", cnf->willingness);
545
546   /* IPC */
547   fprintf(fd, "# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
548   fprintf(fd, "IpcConnect\n{\n");
549   fprintf(fd, "   MaxConnections  %d\n\n", cnf->ipc_connections);
550
551   while(ih)
552     {
553       in4.s_addr = ih->host.v4;
554       fprintf(fd, "   Host          %s\n", inet_ntoa(in4));
555       ih = ih->next;
556     }
557   fprintf(fd, "\n");
558   while(ie)
559     {
560       in4.s_addr = ie->net.v4;
561       fprintf(fd, "   Net           %s ", inet_ntoa(in4));
562       in4.s_addr = ie->mask.v4;
563       fprintf(fd, "%s\n", inet_ntoa(in4));
564       ie = ie->next;
565     }
566
567   fprintf(fd, "}\n\n");
568
569
570
571   /* Hysteresis */
572   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");
573
574   if(cnf->use_hysteresis)
575     {
576       fprintf(fd, "UseHysteresis\tyes\n\n");
577       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");
578       fprintf(fd, "HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
579       fprintf(fd, "HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
580       fprintf(fd, "HystThrLow\t%0.2f\n", cnf->hysteresis_param.thr_low);
581     }
582   else
583     fprintf(fd, "UseHysteresis\tno\n\n");
584
585   fprintf(fd, "\n\n");
586
587   /* Pollrate */
588   fprintf(fd, "# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
589   fprintf(fd, "Pollrate\t%0.2f\n", cnf->pollrate);
590
591   /* TC redundancy */
592   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");
593   fprintf(fd, "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
594
595   /* MPR coverage */
596   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");
597
598   fprintf(fd, "MprCoverage\t%d\n\n", cnf->mpr_coverage);
599
600   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");
601   fprintf(fd, "LinkQualityLevel\t%d\n\n", cnf->lq_level);
602
603   fprintf(fd, "# Link quality window size\n\n");
604   fprintf(fd, "LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
605
606   fprintf(fd, "# Clear screen when printing debug output?\n\n");
607   fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
608
609   /* Plugins */
610   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");
611   if(pe)
612     {
613       while(pe)
614         {
615           fprintf(fd, "LoadPlugin \"%s\"\n{\n", pe->name);
616           pp = pe->params;
617           while(pp)
618             {
619               fprintf(fd, "    PlParam \"%s\" \"%s\"\n", pp->key, pp->value);
620               pp = pp->next;
621             }
622           fprintf(fd, "}\n");
623           pe = pe->next;
624         }
625     }
626   fprintf(fd, "\n");
627
628   
629   
630
631   /* Interfaces */
632   fprintf(fd, "# Interfaces\n\n");
633   /* Interfaces */
634   if(in)
635     {
636       while(in)
637         {
638           fprintf(fd, "Interface \"%s\"\n{\n", in->name);
639           fprintf(fd, "\n");
640       
641           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");
642
643           if(in->cnf->ipv4_broadcast.v4)
644             {
645               in4.s_addr = in->cnf->ipv4_broadcast.v4;
646               fprintf(fd, "    Ip4Broadcast\t %s\n\n", inet_ntoa(in4));
647             }
648           else
649             {
650               fprintf(fd, "    #Ip4Broadcast\t255.255.255.255\n\n");
651             }
652           
653           
654           fprintf(fd, "    # IPv6 address scope to use.\n    # Must be 'site-local' or 'global'\n\n");
655           if(in->cnf->ipv6_addrtype)
656             fprintf(fd, "    Ip6AddrType \tsite-local\n\n");
657           else
658             fprintf(fd, "    Ip6AddrType \tglobal\n\n");
659           
660           fprintf(fd, "    # IPv6 multicast address to use when\n    # using site-local addresses.\n    # If not defined, ff05::15 is used\n");
661           fprintf(fd, "    Ip6MulticastSite\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
662           fprintf(fd, "    # IPv6 multicast address to use when\n    # using global addresses\n    # If not defined, ff0e::1 is used\n");
663           fprintf(fd, "    Ip6MulticastGlobal\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
664           
665           
666           
667           fprintf(fd, "    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
668           
669           
670           if(in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
671             fprintf(fd, "    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
672           else
673             fprintf(fd, "    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
674           if(in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
675             fprintf(fd, "    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
676           else
677             fprintf(fd, "    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
678           if(in->cnf->tc_params.emission_interval != TC_INTERVAL)
679             fprintf(fd, "    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
680           else
681             fprintf(fd, "    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
682           if(in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
683             fprintf(fd, "    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
684           else
685             fprintf(fd, "    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
686           if(in->cnf->mid_params.emission_interval != MID_INTERVAL)
687             fprintf(fd, "    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
688           else
689             fprintf(fd, "    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
690           if(in->cnf->mid_params.validity_time != MID_HOLD_TIME)
691             fprintf(fd, "    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
692           else
693             fprintf(fd, "    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
694           if(in->cnf->hna_params.emission_interval != HNA_INTERVAL)
695             fprintf(fd, "    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
696           else
697             fprintf(fd, "    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
698           if(in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
699             fprintf(fd, "    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);       
700           else
701             fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);      
702           
703           
704           
705           fprintf(fd, "}\n\n");
706           in = in->next;
707         }
708
709     }
710
711
712   fprintf(fd, "\n# END AUTOGENERATED CONFIG\n");
713
714   fclose(fd);
715   printf("DONE\n");
716
717   return 1;
718 }
719
720
721
722
723
724 void
725 olsrd_print_cnf(struct olsrd_config *cnf)
726 {
727   struct hna4_entry        *h4 = cnf->hna4_entries;
728   struct hna6_entry        *h6 = cnf->hna6_entries;
729   struct olsr_if           *in = cnf->interfaces;
730   struct plugin_entry      *pe = cnf->plugins;
731   struct ipc_host          *ih = cnf->ipc_hosts;
732   struct ipc_net           *ie = cnf->ipc_nets;
733   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
734   struct in_addr in4;
735
736   printf(" *** olsrd configuration ***\n");
737
738   printf("Debug Level      : %d\n", cnf->debug_level);
739   if(cnf->ip_version == AF_INET6)
740     printf("IpVersion        : 6\n");
741   else
742     printf("IpVersion        : 4\n");
743   if(cnf->allow_no_interfaces)
744     printf("No interfaces    : ALLOWED\n");
745   else
746     printf("No interfaces    : NOT ALLOWED\n");
747   printf("TOS              : 0x%02x\n", cnf->tos);
748   if(cnf->willingness_auto)
749     printf("Willingness      : AUTO\n");
750   else
751     printf("Willingness      : %d\n", cnf->willingness);
752
753   printf("IPC connections  : %d\n", cnf->ipc_connections);
754
755   while(ih)
756     {
757       in4.s_addr = ih->host.v4;
758       printf("\tHost %s\n", inet_ntoa(in4));
759       ih = ih->next;
760     }
761   
762   while(ie)
763     {
764       in4.s_addr = ie->net.v4;
765       printf("\tNet %s/", inet_ntoa(in4));
766       in4.s_addr = ie->mask.v4;
767       printf("%s\n", inet_ntoa(in4));
768       ie = ie->next;
769     }
770
771
772   printf("Pollrate         : %0.2f\n", cnf->pollrate);
773
774   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
775
776   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
777    
778   printf("LQ level         : %d\n", cnf->lq_level);
779
780   printf("LQ window size   : %d\n", cnf->lq_wsize);
781
782   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
783
784   /* Interfaces */
785   if(in)
786     {
787       printf("Interfaces:\n");
788       while(in)
789         {
790           printf(" dev: \"%s\"\n", in->name);
791           
792           if(in->cnf->ipv4_broadcast.v4)
793             {
794               in4.s_addr = in->cnf->ipv4_broadcast.v4;
795               printf("\tIPv4 broadcast        : %s\n", inet_ntoa(in4));
796             }
797           else
798             {
799               printf("\tIPv4 broadcast        : AUTO\n");
800             }
801           
802           if(in->cnf->ipv6_addrtype)
803             printf("\tIPv6 addrtype         : site-local\n");
804           else
805             printf("\tIPv6 addrtype         : global\n");
806           
807           //union olsr_ip_addr       ipv6_multi_site;
808           //union olsr_ip_addr       ipv6_multi_glbl;
809           printf("\tIPv6 multicast site   : %s\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
810           printf("\tIPv6 multicast global : %s\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
811           
812           printf("\tHELLO emission int    : %0.2f\n", in->cnf->hello_params.emission_interval);
813           printf("\tHELLO validity time   : %0.2f\n", in->cnf->hello_params.validity_time);
814           printf("\tTC emission int       : %0.2f\n", in->cnf->tc_params.emission_interval);
815           printf("\tTC validity time      : %0.2f\n", in->cnf->tc_params.validity_time);
816           printf("\tMID emission int      : %0.2f\n", in->cnf->mid_params.emission_interval);
817           printf("\tMID validity time     : %0.2f\n", in->cnf->mid_params.validity_time);
818           printf("\tHNA emission int      : %0.2f\n", in->cnf->hna_params.emission_interval);
819           printf("\tHNA validity time     : %0.2f\n", in->cnf->hna_params.validity_time);
820           
821           
822           
823           in = in->next;
824
825         }
826     }
827
828
829
830
831   /* Plugins */
832   if(pe)
833     {
834       printf("Plugins:\n");
835
836       while(pe)
837         {
838           printf("\tName: \"%s\"\n", pe->name);
839           pe = pe->next;
840         }
841     }
842
843   /* Hysteresis */
844   if(cnf->use_hysteresis)
845     {
846       printf("Using hysteresis:\n");
847       printf("\tScaling : %0.2f\n", cnf->hysteresis_param.scaling);
848       printf("\tThr high: %0.2f\n", cnf->hysteresis_param.thr_high);
849       printf("\tThr low : %0.2f\n", cnf->hysteresis_param.thr_low);
850     }
851   else
852     printf("Not using hysteresis\n");
853
854   /* HNA IPv4 */
855   if(h4)
856     {
857
858       printf("HNA4 entries:\n");
859       while(h4)
860         {
861           in4.s_addr = h4->net.v4;
862           printf("\t%s/", inet_ntoa(in4));
863           in4.s_addr = h4->netmask.v4;
864           printf("%s\n", inet_ntoa(in4));
865
866           h4 = h4->next;
867         }
868     }
869
870   /* HNA IPv6 */
871   if(h6)
872     {
873       printf("HNA6 entries:\n");
874       while(h6)
875         {
876           printf("\t%s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
877           h6 = h6->next;
878         }
879     }
880 }
881
882 void *olsrd_cnf_malloc(unsigned int len)
883 {
884   return malloc(len);
885 }
886
887 void olsrd_cnf_free(void *addr)
888 {
889   free(addr);
890 }