* made a statement-like macro out of WRITE_BUF
[olsrd.git] / src / cfgparser / cfgfile_gen.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2005, 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: cfgfile_gen.c,v 1.9 2007/10/15 21:01:17 bernd67 Exp $
40  */
41
42
43 #include <stdio.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <sys/types.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49
50 #include "olsrd_conf.h"
51
52
53 int
54 olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
55 {
56   struct hna4_entry        *h4 = cnf->hna4_entries;
57   struct hna6_entry        *h6 = cnf->hna6_entries;
58   struct olsr_if           *in = cnf->interfaces;
59   struct plugin_entry      *pe = cnf->plugins;
60   struct plugin_param      *pp;
61   struct ipc_host          *ih = cnf->ipc_hosts;
62   struct ipc_net           *ie = cnf->ipc_nets;
63   struct olsr_lq_mult      *mult;
64
65   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
66   struct in_addr in4;
67
68   FILE *fd;
69
70   fd = fopen(fname, "w");
71
72   if(fd == NULL)
73     {
74       fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
75       return -1;
76     }
77
78   printf("Writing config to file \"%s\".... ", fname);
79
80   fprintf(fd, "#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
81
82   /* Debug level */
83   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);
84
85   /* IP version */
86   if(cnf->ip_version == AF_INET6)
87     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t6\n\n");
88   else
89     fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t4\n\n");
90
91
92   /* HNA IPv4 */
93   fprintf(fd, "# HNA IPv4 routes\n# syntax: netaddr netmask\n\nHna4\n{\n");
94   while(h4)
95     {
96       in4.s_addr = h4->net.v4;
97       fprintf(fd, "    %s ", inet_ntoa(in4));
98       in4.s_addr = h4->netmask.v4;
99       fprintf(fd, "%s\n", inet_ntoa(in4));
100       h4 = h4->next;
101     }
102   fprintf(fd, "}\n\n");
103
104
105   /* HNA IPv6 */
106   fprintf(fd, "# HNA IPv6 routes\n# syntax: netaddr prefix\n\nHna6\n{\n");
107   while(h6)
108     {
109       fprintf(fd, "    %s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
110       h6 = h6->next;
111     }
112
113   fprintf(fd, "}\n\n");
114
115   /* No interfaces */
116   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");
117   if(cnf->allow_no_interfaces)
118     fprintf(fd, "yes\n\n");
119   else
120     fprintf(fd, "no\n\n");
121
122   /* TOS */
123   fprintf(fd, "# TOS(type of service) to use. Default is 16\n\n");
124   fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
125
126   /* RtTable */
127   fprintf(fd, "# Policy Routing Table to use. Default is 254\n\n");
128   fprintf(fd, "RtTable\t%d\n\n", cnf->rttable);
129
130   /* Willingness */
131   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");
132   if(cnf->willingness_auto)
133     fprintf(fd, "#Willingness\t4\n\n");
134   else
135     fprintf(fd, "Willingness%d\n\n", cnf->willingness);
136
137   /* IPC */
138   fprintf(fd, "# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
139   fprintf(fd, "IpcConnect\n{\n");
140   fprintf(fd, "   MaxConnections  %d\n", cnf->ipc_connections);
141
142   while(ih)
143     {
144       in4.s_addr = ih->host.v4;
145       fprintf(fd, "   Host          %s\n", inet_ntoa(in4));
146       ih = ih->next;
147     }
148   while(ie)
149     {
150       in4.s_addr = ie->net.v4;
151       fprintf(fd, "   Net           %s ", inet_ntoa(in4));
152       in4.s_addr = ie->mask.v4;
153       fprintf(fd, "%s\n", inet_ntoa(in4));
154       ie = ie->next;
155     }
156
157   fprintf(fd, "}\n\n");
158
159
160
161   /* Hysteresis */
162   fprintf(fd, "# Hysteresis adds more robustness to the\n# link sensing.\n# Used by default. 'yes' or 'no'\n\n");
163
164   if(cnf->use_hysteresis)
165     {
166       fprintf(fd, "UseHysteresis\tyes\n\n");
167       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");
168       fprintf(fd, "HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
169       fprintf(fd, "HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
170       fprintf(fd, "HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
171     }
172   else
173     {
174       fprintf(fd, "UseHysteresis\tno\n\n");
175       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");
176       fprintf(fd, "#HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
177       fprintf(fd, "#HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
178       fprintf(fd, "#HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
179     }
180
181   /* Pollrate */
182   fprintf(fd, "# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
183   fprintf(fd, "Pollrate\t%0.2f\n", cnf->pollrate);
184
185   /* NIC Changes Pollrate */
186   fprintf(fd, "# Interval to poll network interfaces for configuration\n# changes. Defaults to 2.5 seconds\n");
187   fprintf(fd, "NicChgsPollInt\t%0.2f\n", cnf->nic_chgs_pollrate);
188
189   /* TC redundancy */
190   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");
191   fprintf(fd, "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
192
193   /* MPR coverage */
194   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");
195
196   fprintf(fd, "MprCoverage\t%d\n\n", cnf->mpr_coverage);
197
198   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");
199   fprintf(fd, "LinkQualityLevel\t%d\n\n", cnf->lq_level);
200
201   fprintf(fd, "# Fish Eye algorithm\n# 0 = do not use fish eye\n# 1 = use fish eye\n\n");
202   fprintf(fd, "LinkQualityFishEye\t%d\n\n", cnf->lq_fish);
203
204   fprintf(fd, "# Link quality window size\n\n");
205   fprintf(fd, "LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
206
207   fprintf(fd, "# Clear screen when printing debug output?\n\n");
208   fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
209
210   /* Plugins */
211   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");
212   if(pe)
213     {
214       while(pe)
215         {
216           fprintf(fd, "LoadPlugin \"%s\"\n{\n", pe->name);
217           pp = pe->params;
218           while(pp)
219             {
220               fprintf(fd, "    PlParam \"%s\" \"%s\"\n", pp->key, pp->value);
221               pp = pp->next;
222             }
223           fprintf(fd, "}\n");
224           pe = pe->next;
225         }
226     }
227   fprintf(fd, "\n");
228
229   
230   
231
232   /* Interfaces */
233   fprintf(fd, "# Interfaces\n# Multiple interfaces with the same configuration\n# can shar the same config block. Just list the\n# interfaces(e.g. Interface \"eth0\" \"eth2\"\n\n");
234   /* Interfaces */
235   if(in)
236     {
237       while(in)
238         {
239           fprintf(fd, "Interface \"%s\"\n{\n", in->name);
240           fprintf(fd, "\n");
241       
242           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");
243
244
245           if(in->cnf->ipv4_broadcast.v4)
246             {
247               in4.s_addr = in->cnf->ipv4_broadcast.v4;
248               fprintf(fd, "    Ip4Broadcast\t %s\n\n", inet_ntoa(in4));
249             }
250           else
251             {
252               fprintf(fd, "    #Ip4Broadcast\t255.255.255.255\n\n");
253             }
254           
255           
256           fprintf(fd, "    # IPv6 address scope to use.\n    # Must be 'site-local' or 'global'\n\n");
257           if(in->cnf->ipv6_addrtype)
258             fprintf(fd, "    Ip6AddrType \tsite-local\n\n");
259           else
260             fprintf(fd, "    Ip6AddrType \tglobal\n\n");
261           
262           fprintf(fd, "    # IPv6 multicast address to use when\n    # using site-local addresses.\n    # If not defined, ff05::15 is used\n");
263           fprintf(fd, "    Ip6MulticastSite\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
264           fprintf(fd, "    # IPv6 multicast address to use when\n    # using global addresses\n    # If not defined, ff0e::1 is used\n");
265           fprintf(fd, "    Ip6MulticastGlobal\t%s\n\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
266           
267           
268           fprintf(fd, "    # Olsrd can autodetect changes in\n    # interface configurations. Enabled by default\n    # turn off to save CPU.\n    AutoDetectChanges: %s\n", in->cnf->autodetect_chg ? "yes" : "no");
269
270           fprintf(fd, "    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
271           
272           
273           if(in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
274             fprintf(fd, "    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
275           else
276             fprintf(fd, "    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
277           if(in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
278             fprintf(fd, "    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
279           else
280             fprintf(fd, "    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
281           if(in->cnf->tc_params.emission_interval != TC_INTERVAL)
282             fprintf(fd, "    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
283           else
284             fprintf(fd, "    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
285           if(in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
286             fprintf(fd, "    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
287           else
288             fprintf(fd, "    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
289           if(in->cnf->mid_params.emission_interval != MID_INTERVAL)
290             fprintf(fd, "    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
291           else
292             fprintf(fd, "    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
293           if(in->cnf->mid_params.validity_time != MID_HOLD_TIME)
294             fprintf(fd, "    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
295           else
296             fprintf(fd, "    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
297           if(in->cnf->hna_params.emission_interval != HNA_INTERVAL)
298             fprintf(fd, "    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
299           else
300             fprintf(fd, "    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
301           if(in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
302             fprintf(fd, "    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);       
303           else
304             fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);      
305           
306           mult = in->cnf->lq_mult;
307
308           if (mult == NULL)
309             {
310               fprintf(fd, "    #LinkQualityMult\tdefault 1.0\n");
311             }
312           else
313             {
314               while (mult != NULL)
315                 {
316                   inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf,
317                             sizeof (ipv6_buf));
318                   
319                   fprintf(fd, "    LinkQualityMult\t%s %0.2f\n",
320                           ipv6_buf, mult->val);
321                   
322                   mult = mult->next;
323                 }
324             }
325
326          fprintf(fd, "    # When multiple links exist between hosts\n");
327          fprintf(fd, "    # the weight of interface is used to determine\n");
328          fprintf(fd, "    # the link to use. Normally the weight is\n");
329          fprintf(fd, "    # automatically calculated by olsrd based\n");
330          fprintf(fd, "    # on the characteristics of the interface,\n");
331          fprintf(fd, "    # but here you can specify a fixed value.\n");
332          fprintf(fd, "    # Olsrd will choose links with the lowest value.\n");
333          fprintf(fd, "    # Note:\n");
334          fprintf(fd, "    # Interface weight is used only when LinkQualityLevel is 0.\n");
335          fprintf(fd, "    # For any other value of LinkQualityLevel, the interface ETX\n");
336          fprintf(fd, "    # value is used instead.\n\n");
337           if(in->cnf->weight.fixed)
338             {
339               fprintf(fd, "    Weight\t %d\n\n", in->cnf->weight.value);
340             }
341           else
342             {
343               fprintf(fd, "    #Weight\t 0\n\n");
344             }
345
346           
347           fprintf(fd, "}\n\n");
348           in = in->next;
349         }
350
351     }
352
353
354   fprintf(fd, "\n# END AUTOGENERATED CONFIG\n");
355
356   fclose(fd);
357   printf("DONE\n");
358
359   return 1;
360 }
361
362 #define MAX_LINESIZE 250
363
364 #define WRITE_TO_BUF(fmt, args...)                                      \
365     do {                                                                \
366         if((bufsize - size) < MAX_LINESIZE) {                           \
367             return -1;                                                  \
368         }                                                               \
369         size += snprintf(&buf[size], MAX_LINESIZE, fmt, ##args);        \
370     } while (0)
371
372 int
373 olsrd_write_cnf_buf(struct olsrd_config *cnf, char *buf, olsr_u32_t bufsize)
374 {
375   struct hna4_entry        *h4 = cnf->hna4_entries;
376   struct hna6_entry        *h6 = cnf->hna6_entries;
377   struct olsr_if           *in = cnf->interfaces;
378   struct plugin_entry      *pe = cnf->plugins;
379   struct plugin_param      *pp;
380   struct ipc_host          *ih = cnf->ipc_hosts;
381   struct ipc_net           *ie = cnf->ipc_nets;
382   struct olsr_lq_mult      *mult;
383
384   int size = 0;
385
386   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
387   struct in_addr in4;
388
389 #if 0
390   printf("\n\n\n\nolsrd_write_cnf_buf bufsize  %d\n\n\n\n\n", bufsize);
391 #endif
392   if(buf == NULL || bufsize < MAX_LINESIZE)
393     {
394       return -1;
395     }
396
397   WRITE_TO_BUF("#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
398
399   /* Debug level */
400   WRITE_TO_BUF("# Debug level(0-9)\n# If set to 0 the daemon runs in the background\n\nDebugLevel\t%d\n\n", cnf->debug_level);
401
402   /* IP version */
403   if(cnf->ip_version == AF_INET6)
404       WRITE_TO_BUF("# IP version to use (4 or 6)\n\nIpVersion\t6\n\n");
405   else
406       WRITE_TO_BUF("# IP version to use (4 or 6)\n\nIpVersion\t4\n\n");
407
408   /* HNA IPv4 */
409   WRITE_TO_BUF("# HNA IPv4 routes\n# syntax: netaddr netmask\n\nHna4\n{\n");
410   while(h4)
411     {
412       in4.s_addr = h4->net.v4;
413       WRITE_TO_BUF("    %s ", inet_ntoa(in4));
414       in4.s_addr = h4->netmask.v4;
415       WRITE_TO_BUF("%s\n", inet_ntoa(in4));
416       h4 = h4->next;
417     }
418   WRITE_TO_BUF("}\n\n");
419
420
421   /* HNA IPv6 */
422   WRITE_TO_BUF("# HNA IPv6 routes\n# syntax: netaddr prefix\n\nHna6\n{\n");
423   while(h6)
424     {
425       WRITE_TO_BUF("    %s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
426       h6 = h6->next;
427     }
428
429   WRITE_TO_BUF("}\n\n");
430
431   /* No interfaces */
432   WRITE_TO_BUF("# 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");
433   if(cnf->allow_no_interfaces)
434     WRITE_TO_BUF("yes\n\n");
435   else
436     WRITE_TO_BUF("no\n\n");
437
438   /* TOS */
439   WRITE_TO_BUF("# TOS(type of service) to use. Default is 16\n\n");
440   WRITE_TO_BUF("TosValue\t%d\n\n", cnf->tos);
441
442   /* RtTable */
443   WRITE_TO_BUF("# Policy Routing Tableto use. Default is 254\n\n");
444   WRITE_TO_BUF("RtTable\t%d\n\n", cnf->rttable);
445
446   /* Willingness */
447   WRITE_TO_BUF("# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
448   if(cnf->willingness_auto)
449     WRITE_TO_BUF("#Willingness\t4\n\n");
450   else
451     WRITE_TO_BUF("Willingness%d\n\n", cnf->willingness);
452
453   /* IPC */
454   WRITE_TO_BUF("# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
455   WRITE_TO_BUF("IpcConnect\n{\n");
456   WRITE_TO_BUF("   MaxConnections  %d\n", cnf->ipc_connections);
457
458   while(ih)
459     {
460       in4.s_addr = ih->host.v4;
461       WRITE_TO_BUF("   Host          %s\n", inet_ntoa(in4));
462       ih = ih->next;
463     }
464   while(ie)
465     {
466       in4.s_addr = ie->net.v4;
467       WRITE_TO_BUF("   Net           %s ", inet_ntoa(in4));
468       in4.s_addr = ie->mask.v4;
469       WRITE_TO_BUF("%s\n", inet_ntoa(in4));
470       ie = ie->next;
471     }
472
473   WRITE_TO_BUF("}\n\n");
474
475
476
477   /* Hysteresis */
478   WRITE_TO_BUF("# Hysteresis adds more robustness to the\n# link sensing.\n# Used by default. 'yes' or 'no'\n\n");
479
480   if(cnf->use_hysteresis)
481     {
482       WRITE_TO_BUF("UseHysteresis\tyes\n\n");
483       WRITE_TO_BUF("# 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");
484       WRITE_TO_BUF("HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
485       WRITE_TO_BUF("HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
486       WRITE_TO_BUF("HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
487     }
488   else
489     {
490       WRITE_TO_BUF("UseHysteresis\tno\n\n");
491       WRITE_TO_BUF("# 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");
492       WRITE_TO_BUF("#HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
493       WRITE_TO_BUF("#HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
494       WRITE_TO_BUF("#HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
495     }
496
497   /* Pollrate */
498   WRITE_TO_BUF("# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
499   WRITE_TO_BUF("Pollrate\t%0.2f\n", cnf->pollrate);
500
501   /* TC redundancy */
502   WRITE_TO_BUF("# 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");
503   WRITE_TO_BUF("TcRedundancy\t%d\n\n", cnf->tc_redundancy);
504
505   /* MPR coverage */
506   WRITE_TO_BUF("# 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");
507
508   WRITE_TO_BUF("MprCoverage\t%d\n\n", cnf->mpr_coverage);
509
510   WRITE_TO_BUF("# 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");
511   WRITE_TO_BUF("LinkQualityLevel\t%d\n\n", cnf->lq_level);
512
513   WRITE_TO_BUF("# Link quality window size\n\n");
514   WRITE_TO_BUF("LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
515
516   WRITE_TO_BUF("# Clear screen when printing debug output?\n\n");
517   WRITE_TO_BUF("ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
518
519   /* Plugins */
520   WRITE_TO_BUF("# Olsrd plugins to load\n# This must be the absolute path to the file\n# or the loader will use the following scheme:\n");
521   WRITE_TO_BUF("# - 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");
522   if(pe)
523     {
524       while(pe)
525         {
526           WRITE_TO_BUF("LoadPlugin \"%s\"\n{\n", pe->name);
527           pp = pe->params;
528           while(pp)
529             {
530               WRITE_TO_BUF("    PlParam \"%s\" \"%s\"\n", pp->key, pp->value);
531               pp = pp->next;
532             }
533           WRITE_TO_BUF("}\n");
534           pe = pe->next;
535         }
536     }
537   WRITE_TO_BUF("\n");
538
539   
540   
541
542   /* Interfaces */
543   WRITE_TO_BUF("# Interfaces\n# Multiple interfaces with the same configuration\n");
544   WRITE_TO_BUF("# can shar the same config block. Just list the\n# interfaces(e.g. Interface \"eth0\" \"eth2\"\n\n");
545   /* Interfaces */
546   if(in)
547     {
548       olsr_bool first = OLSR_TRUE;
549       while(in)
550         {
551           WRITE_TO_BUF("Interface \"%s\"\n{\n", in->name);
552
553           if(first)
554              WRITE_TO_BUF("    # 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");
555
556
557           if(in->cnf->ipv4_broadcast.v4)
558             {
559               in4.s_addr = in->cnf->ipv4_broadcast.v4;
560               WRITE_TO_BUF("    Ip4Broadcast\t %s\n", inet_ntoa(in4));
561             }
562           else
563             {
564               if(first)
565                 WRITE_TO_BUF("    #Ip4Broadcast\t255.255.255.255\n");
566             }
567           
568           if(first) WRITE_TO_BUF("\n");
569
570           if(first)
571               WRITE_TO_BUF("    # IPv6 address scope to use.\n    # Must be 'site-local' or 'global'\n\n");
572           if(in->cnf->ipv6_addrtype)
573             WRITE_TO_BUF("    Ip6AddrType \tsite-local\n");
574           else
575             WRITE_TO_BUF("    Ip6AddrType \tglobal\n");
576
577           if(first) WRITE_TO_BUF("\n");
578
579           if(first)
580             WRITE_TO_BUF("    # IPv6 multicast address to use when\n    # using site-local addresses.\n    # If not defined, ff05::15 is used\n");
581           WRITE_TO_BUF("    Ip6MulticastSite\t%s\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
582           if(first) WRITE_TO_BUF("\n");
583           if(first)
584             WRITE_TO_BUF("    # IPv6 multicast address to use when\n    # using global addresses\n    # If not defined, ff0e::1 is used\n");
585           WRITE_TO_BUF("    Ip6MulticastGlobal\t%s\n", (char *)inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
586           if(first) WRITE_TO_BUF("\n");
587           
588           
589           if(first)
590             WRITE_TO_BUF("    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
591           
592           
593           if(in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
594             WRITE_TO_BUF("    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
595           else if(first)
596             WRITE_TO_BUF("    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
597           if(in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
598             WRITE_TO_BUF("    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
599           else if(first)
600             WRITE_TO_BUF("    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
601           if(in->cnf->tc_params.emission_interval != TC_INTERVAL)
602             WRITE_TO_BUF("    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
603           else if(first)
604             WRITE_TO_BUF("    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
605           if(in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
606             WRITE_TO_BUF("    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
607           else if(first)
608             WRITE_TO_BUF("    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
609           if(in->cnf->mid_params.emission_interval != MID_INTERVAL)
610             WRITE_TO_BUF("    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
611           else if(first)
612             WRITE_TO_BUF("    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
613           if(in->cnf->mid_params.validity_time != MID_HOLD_TIME)
614             WRITE_TO_BUF("    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
615           else if(first)
616             WRITE_TO_BUF("    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
617           if(in->cnf->hna_params.emission_interval != HNA_INTERVAL)
618             WRITE_TO_BUF("    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
619           else if(first)
620             WRITE_TO_BUF("    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
621           if(in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
622             WRITE_TO_BUF("    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);      
623           else if(first)
624             WRITE_TO_BUF("    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);     
625           
626           mult = in->cnf->lq_mult;
627
628           if (mult == NULL)
629             {
630               if(first)
631                 WRITE_TO_BUF("    #LinkQualityMult\tdefault 1.0\n");
632             }
633           else
634             {
635               while (mult != NULL)
636                 {
637                   inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf,
638                             sizeof (ipv6_buf));
639                   
640                   WRITE_TO_BUF("    LinkQualityMult\t%s %0.2f\n", ipv6_buf, mult->val);
641                   
642                   mult = mult->next;
643                 }
644             }
645
646           if(first)
647             {
648              WRITE_TO_BUF("    # When multiple links exist between hosts\n");;
649              WRITE_TO_BUF("    # the weight of interface is used to determine\n");;
650              WRITE_TO_BUF("    # the link to use. Normally the weight is\n");
651              WRITE_TO_BUF("    # automatically calculated by olsrd based\n");;
652              WRITE_TO_BUF("    # on the characteristics of the interface,\n");;
653              WRITE_TO_BUF("    # but here you can specify a fixed value.\n");;
654              WRITE_TO_BUF("    # Olsrd will choose links with the lowest value.\n");
655              WRITE_TO_BUF("    # Note:\n");;
656              WRITE_TO_BUF("    # Interface weight is used only when LinkQualityLevel is 0.\n");;
657              WRITE_TO_BUF("    # For any other value of LinkQualityLevel, the interface ETX\n");;
658              WRITE_TO_BUF("    # value is used instead.\n\n");;
659             }
660           if(in->cnf->weight.fixed)
661             {
662               WRITE_TO_BUF("    Weight\t %d\n\n", in->cnf->weight.value);
663             }
664           else
665             {
666               if(first)
667                 WRITE_TO_BUF("    #Weight\t 0\n\n");
668             }
669
670           
671           WRITE_TO_BUF("}\n\n");
672           in = in->next;
673           first = OLSR_FALSE;
674         }
675
676     }
677
678
679   WRITE_TO_BUF("\n# END AUTOGENERATED CONFIG\n");
680
681   return size;
682 }
683