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