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