Split SmartGatewayNAT into SmartGatewayAllowNAT and SmartGatewayUplinkNAT
[olsrd.git] / src / cfgparser / cfgfile_gen.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2005, Andreas Tonnesen(andreto@olsr.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #include "olsrd_conf.h"
43 #include "../ipcalc.h"
44 #include "../net_olsr.h"
45
46 #include <stdio.h>
47 #include <string.h>
48 #include <errno.h>
49 #include <sys/types.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
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     fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
71     return -1;
72   }
73
74   printf("Writing config to file \"%s\".... ", fname);
75
76   fprintf(fd, "#\n# Configuration file for s%s\n# automatically generated by olsrd-cnf parser v. %s\n#\n\n", olsrd_version,
77           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,
91           cnf->ip_version == AF_INET ? 4 : 6);
92   while (h) {
93     struct ipaddr_str strbuf;
94     fprintf(fd, "    %s/%d\n", olsr_ip_to_string(&strbuf, &h->net.prefix), h->net.prefix_len);
95     h = h->next;
96   }
97   fprintf(fd, "}\n\n");
98
99   /* No interfaces */
100   fprintf(fd,
101           "# 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");
102   if (cnf->allow_no_interfaces)
103     fprintf(fd, "yes\n\n");
104   else
105     fprintf(fd, "no\n\n");
106
107   /* TOS */
108   fprintf(fd, "# TOS(type of service) to use. Default is 16\n\n");
109   fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
110
111   /* OlsrPort */
112   fprintf(fd, "# Port to use. Default is 698! and using other port than IANA assigned one needs a really good reason!\n#possible values 698 or >1000\n\n");
113   fprintf(fd, "OlsrPort\t\t%d\n\n", cnf->olsrport);
114
115   /* RtTable */
116   fprintf(fd, "# Policy Routing Table to use. Default is 254\n\n");
117   fprintf(fd, "RtTable\t\t%d\n\n", cnf->rttable);
118
119   /* RtProto */
120   fprintf(fd, "# Policy Routing Proto to use. Default is 3\n\n");
121   fprintf(fd, "RtProto\t\t%d\n\n", cnf->rtproto);
122
123   /* RtTableDefault */
124   fprintf(fd,
125           "# Policy Routing Table to use for the default Route. Default is 0 (Take the same table as specified by RtTable)\n\n");
126   fprintf(fd, "RtTableDefault\t\t%d\n\n", cnf->rttable_default);
127
128   /* Willingness */
129   fprintf(fd,
130           "# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
131   if (cnf->willingness_auto)
132     fprintf(fd, "#Willingness\t4\n\n");
133   else
134     fprintf(fd, "Willingness\t%d\n\n", cnf->willingness);
135
136   /* IPC */
137   fprintf(fd, "# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
138   fprintf(fd, "IpcConnect {\n");
139   fprintf(fd, "    MaxConnections\t%d\n", cnf->ipc_connections);
140
141   while (ie) {
142     struct ipaddr_str strbuf;
143     if (ie->net.prefix_len == olsr_cnf->maxplen) {
144       fprintf(fd, "    Host\t\t%s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
145     } else {
146       fprintf(fd, "    Net\t\t\t%s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
147     }
148     ie = ie->next;
149   }
150
151   fprintf(fd, "}\n\n");
152
153   /* Hysteresis */
154   fprintf(fd, "# Hysteresis adds more robustness to the\n# link sensing.\n# Used by default. 'yes' or 'no'\n\n");
155
156   if (cnf->use_hysteresis) {
157     fprintf(fd, "UseHysteresis\tyes\n\n");
158     fprintf(fd,
159             "# 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");
160     fprintf(fd, "HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
161     fprintf(fd, "HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
162     fprintf(fd, "HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
163   } else {
164     fprintf(fd, "UseHysteresis\tno\n\n");
165     fprintf(fd,
166             "# 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");
167     fprintf(fd, "#HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
168     fprintf(fd, "#HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
169     fprintf(fd, "#HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
170   }
171
172   /* Pollrate */
173   fprintf(fd, "# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
174   fprintf(fd, "Pollrate\t%0.2f\n", cnf->pollrate);
175
176   /* NIC Changes Pollrate */
177   fprintf(fd, "# Interval to poll network interfaces for configuration\n# changes. Defaults to 2.5 seconds\n");
178   fprintf(fd, "NicChgsPollInt\t%0.2f\n", cnf->nic_chgs_pollrate);
179
180   /* TC redundancy */
181   fprintf(fd,
182           "# 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");
183   fprintf(fd, "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
184
185   /* MPR coverage */
186   fprintf(fd,
187           "# 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");
188
189   fprintf(fd, "MprCoverage\t%d\n\n", cnf->mpr_coverage);
190
191   fprintf(fd,
192           "# 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");
193   fprintf(fd, "LinkQualityLevel\t%d\n\n", cnf->lq_level);
194
195   fprintf(fd, "# Fish Eye algorithm\n# 0 = do not use fish eye\n# 1 = use fish eye\n\n");
196   fprintf(fd, "LinkQualityFishEye\t%d\n\n", cnf->lq_fish);
197
198   if (NULL != cnf->lq_algorithm) {
199     fprintf(fd,
200             "# 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");
201     fprintf(fd, "LinkQualityAlgorithm\t\"%s\"\n\n", cnf->lq_algorithm);
202   }
203
204   fprintf(fd, "# Link quality aging factor\n\n");
205   fprintf(fd, "LinkQualityAging\t%f\n\n", cnf->lq_aging);
206
207   fprintf(fd, "# NAT threshold\n\n");
208   fprintf(fd, "NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
209
210   fprintf(fd, "# Clear screen when printing debug output?\n\n");
211   fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
212
213   fprintf(fd, "# NIIT support\n\n");
214   fprintf(fd, "UseNiit\t%s\n\n", cnf->use_niit ? "yes" : "no");
215
216   fprintf(fd, "# Smart gateway system\n\n");
217   fprintf(fd, "SmartGateway\t%s\n\n", cnf->smart_gw_active ? "yes" : "no");
218
219   fprintf(fd, "# Smart gateway allow NAT\n\n");
220   fprintf(fd, "SmartGatewayAllowNAT\t%s\n\n", cnf->smart_gw_allow_nat ? "yes" : "no");
221
222   fprintf(fd, "# Smart gateway uplink type\n\n");
223   fprintf(fd, "SmartGatewayUplink\t%s\n\n", GW_UPLINK_TXT[cnf->smart_gw_type]);
224
225   fprintf(fd, "# Smart gateway uplink use NAT\n\n");
226   fprintf(fd, "SmartGatewayUplinkNAT\t%s\n\n", cnf->smart_gw_uplink_nat ? "yes" : "no");
227
228   fprintf(fd, "# Smart gateway uplink/downlink speed (in kbit/s)\n\n");
229   fprintf(fd, "SmartGatewaySpeed\t%d %d\n\n", cnf->smart_gw_uplink, cnf->smart_gw_downlink);
230
231   fprintf(fd, "# Smart gateway prefix\n\n");
232   fprintf(fd, "SmartGatewayPrefix\t%s\n\n", olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
233
234   /* Plugins */
235   fprintf(fd,"# Olsrd plugins to load\n"
236              "# This must be the absolute path to the file\n"
237              "# or the loader will use the following scheme:\n"
238              "# - Try the paths in the LD_LIBRARY_PATH \n"
239              "#   environment variable.\n"
240              "# - The list of libraries cached in /etc/ld.so.cache\n"
241              "# - /lib, followed by /usr/lib\n\n");
242   if (pe) {
243     while (pe) {
244       fprintf(fd, "LoadPlugin \"%s\" {\n", pe->name);
245       pp = pe->params;
246       while (pp) {
247         fprintf(fd, "    PlParam \"%s\"\t\"%s\"\n", pp->key, pp->value);
248         pp = pp->next;
249       }
250       fprintf(fd, "}\n");
251       pe = pe->next;
252     }
253   }
254   fprintf(fd, "\n");
255
256   /* Interfaces */
257   fprintf(fd,
258           "# 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");
259   /* Interfaces */
260   if (in) {
261     while (in) {
262       fprintf(fd, "Interface \"%s\" {\n", in->name);
263       fprintf(fd, "\n");
264
265       fprintf(fd,
266               "    # 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");
267
268       if (in->cnf->ipv4_multicast.v4.s_addr) {
269         fprintf(fd, "    Ip4Broadcast\t%s\n\n", inet_ntoa(in->cnf->ipv4_multicast.v4));
270       } else {
271         fprintf(fd, "    #Ip4Broadcast\t255.255.255.255\n\n");
272       }
273  
274       fprintf(fd,
275               "    # Interface Mode to use. Defines\n    # forward behaviour depending on\n    # interface type\n    # valid option are mesh and ether\nDefault is mesh!\n\n");
276
277       if (in->cnf->mode!=IF_MODE_ETHER) {
278         fprintf(fd, "    #Mode\tMesh\n\n");
279       } else {
280         fprintf(fd, "    Mode\tEther\n\n");
281       }
282
283       fprintf(fd,
284               "    # IPv6 multicast address.\n    # If not defined, "OLSR_IPV6_MCAST" is used\n");
285       fprintf(fd, "    IPv6Multicast\t%s\n\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)));
286
287       fprintf(fd,
288               "    # IPv4 src address.\n    # If not defined, the interface IP is used\n");
289       fprintf(fd, "    IPv4Src\t%s\n\n", inet_ntop(AF_INET6, &in->cnf->ipv4_src.v4, ipv6_buf, sizeof(ipv6_buf)));
290
291       fprintf(fd,
292               "    # IPv6 src prefix.\n    # If not defined, a not-linklocal interface IP is used\n");
293       fprintf(fd, "    IPv6Src\t%s\n\n", olsr_ip_prefix_to_string(&in->cnf->ipv6_src));
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", in->cnf->hello_params.emission_interval);
304       else
305         fprintf(fd, "    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
306       if (in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
307         fprintf(fd, "    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
308       else
309         fprintf(fd, "    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
310       if (in->cnf->tc_params.emission_interval != TC_INTERVAL)
311         fprintf(fd, "    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
312       else
313         fprintf(fd, "    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
314       if (in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
315         fprintf(fd, "    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
316       else
317         fprintf(fd, "    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
318       if (in->cnf->mid_params.emission_interval != MID_INTERVAL)
319         fprintf(fd, "    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
320       else
321         fprintf(fd, "    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
322       if (in->cnf->mid_params.validity_time != MID_HOLD_TIME)
323         fprintf(fd, "    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
324       else
325         fprintf(fd, "    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
326       if (in->cnf->hna_params.emission_interval != HNA_INTERVAL)
327         fprintf(fd, "    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
328       else
329         fprintf(fd, "    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
330       if (in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
331         fprintf(fd, "    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
332       else
333         fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
334
335       mult = in->cnf->lq_mult;
336
337       if (mult == NULL) {
338         fprintf(fd, "    #LinkQualityMult\tdefault 1.0\n");
339       } else {
340         while (mult != NULL) {
341           fprintf(fd, "    LinkQualityMult\t%s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
342                   (float)(mult->value) / 65536.0);
343           mult = mult->next;
344         }
345       }
346
347       fprintf(fd, "    # When multiple links exist between hosts\n");
348       fprintf(fd, "    # the weight of interface is used to determine\n");
349       fprintf(fd, "    # the link to use. Normally the weight is\n");
350       fprintf(fd, "    # automatically calculated by olsrd based\n");
351       fprintf(fd, "    # on the characteristics of the interface,\n");
352       fprintf(fd, "    # but here you can specify a fixed value.\n");
353       fprintf(fd, "    # Olsrd will choose links with the lowest value.\n");
354       fprintf(fd, "    # Note:\n");
355       fprintf(fd, "    # Interface weight is used only when LinkQualityLevel is 0.\n");
356       fprintf(fd, "    # For any other value of LinkQualityLevel, the interface ETX\n");
357       fprintf(fd, "    # value is used instead.\n\n");
358       if (in->cnf->weight.fixed) {
359         fprintf(fd, "    Weight\t %d\n\n", in->cnf->weight.value);
360       } else {
361         fprintf(fd, "    #Weight\t 0\n\n");
362       }
363
364       fprintf(fd, "}\n\n");
365       in = in->next;
366     }
367
368   }
369
370   fprintf(fd, "\n# END AUTOGENERATED CONFIG\n");
371
372   fclose(fd);
373   printf("DONE\n");
374
375   return 1;
376 }
377
378 #define MAX_LINESIZE 250
379
380 #define WRITE_TO_BUF(fmt, args...)                                      \
381     do {                                                                \
382         if((bufsize - size) < MAX_LINESIZE) {                           \
383             return -1;                                                  \
384         }                                                               \
385         size += snprintf(&buf[size], MAX_LINESIZE, fmt, ##args);        \
386     } while (0)
387
388 int
389 olsrd_write_cnf_buf(struct olsrd_config *cnf, char *buf, uint32_t bufsize)
390 {
391   struct ip_prefix_list *h = cnf->hna_entries;
392   struct olsr_if *in = cnf->interfaces;
393   struct plugin_entry *pe = cnf->plugins;
394   struct plugin_param *pp;
395   struct ip_prefix_list *ie = cnf->ipc_nets;
396   struct olsr_lq_mult *mult;
397
398   int size = 0;
399
400   char ipv6_buf[100];                  /* buffer for IPv6 inet_htop */
401
402 #if 0
403   printf("\n\n\n\nolsrd_write_cnf_buf bufsize  %d\n\n\n\n\n", bufsize);
404 #endif
405   if (buf == NULL || bufsize < MAX_LINESIZE) {
406     return -1;
407   }
408
409   WRITE_TO_BUF("#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
410
411   /* Debug level */
412   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);
413
414   /* IP version */
415   WRITE_TO_BUF("# IP version to use (4 or 6)\n\nIpVersion\t%d\n\n", cnf->ip_version == AF_INET ? 4 : 6);
416
417   /* FIB Metric */
418   WRITE_TO_BUF("# FIBMetric (\"%s\", \"%s\", or \"%s\")\n\nFIBMetric\t\"%s\"\n\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX,
419                FIBM_FLAT == cnf->fib_metric ? CFG_FIBM_FLAT : FIBM_CORRECT == cnf->fib_metric ? CFG_FIBM_CORRECT : CFG_FIBM_APPROX);
420
421   /* HNA IPv4/IPv6 */
422   WRITE_TO_BUF("# HNA IPv%1$d routes\n# syntax: netaddr netmask\n\nHna%1$d {\n", cnf->ip_version == AF_INET ? 4 : 6);
423   while (h) {
424     struct ipaddr_str strbuf;
425     WRITE_TO_BUF("    %s/%d\n", olsr_ip_to_string(&strbuf, &h->net.prefix), h->net.prefix_len);
426     h = h->next;
427   }
428   WRITE_TO_BUF("}\n\n");
429
430   /* No interfaces */
431   WRITE_TO_BUF
432     ("# 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("# Port to use. Default is 698! and using other port than IANA assigned one needs a really good reason!!\n\n");
444   WRITE_TO_BUF("OlsrPort\t\t%d\n\n", cnf->olsrport);
445
446   /* RtTable */
447   WRITE_TO_BUF("# Policy Routing Table to use. Default is 254\n\n");
448   WRITE_TO_BUF("RtTable\t\t%d\n\n", cnf->rttable);
449
450   /* RtProto */
451   WRITE_TO_BUF("# Routing proto flag to use. Default is 3 (BOOT)\n\n");
452   WRITE_TO_BUF("RtProto\t\t%d\n\n", cnf->rtproto);
453
454   /* Willingness */
455   WRITE_TO_BUF
456     ("# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
457   if (cnf->willingness_auto)
458     WRITE_TO_BUF("#Willingness\t4\n\n");
459   else
460     WRITE_TO_BUF("Willingness\t%d\n\n", cnf->willingness);
461
462   /* IPC */
463   WRITE_TO_BUF("# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
464   WRITE_TO_BUF("IpcConnect {\n");
465   WRITE_TO_BUF("    MaxConnections\t%d\n", cnf->ipc_connections);
466   while (ie) {
467     struct ipaddr_str strbuf;
468     if (ie->net.prefix_len == olsr_cnf->maxplen) {
469       WRITE_TO_BUF("    Host\t\t%s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
470     } else {
471       WRITE_TO_BUF("    Net\t\t\t%s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
472     }
473     ie = ie->next;
474   }
475
476   WRITE_TO_BUF("}\n\n");
477
478   /* Hysteresis */
479   WRITE_TO_BUF("# Hysteresis adds more robustness to the\n# link sensing.\n# Used by default. 'yes' or 'no'\n\n");
480
481   if (cnf->use_hysteresis) {
482     WRITE_TO_BUF("UseHysteresis\tyes\n\n");
483     WRITE_TO_BUF
484       ("# 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");
485     WRITE_TO_BUF("HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
486     WRITE_TO_BUF("HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
487     WRITE_TO_BUF("HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
488   } else {
489     WRITE_TO_BUF("UseHysteresis\tno\n\n");
490     WRITE_TO_BUF
491       ("# 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
503     ("# 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");
504   WRITE_TO_BUF("TcRedundancy\t%d\n\n", cnf->tc_redundancy);
505
506   /* MPR coverage */
507   WRITE_TO_BUF
508     ("# 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");
509
510   WRITE_TO_BUF("MprCoverage\t%d\n\n", cnf->mpr_coverage);
511
512   WRITE_TO_BUF
513     ("# 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");
514   WRITE_TO_BUF("LinkQualityLevel\t%d\n\n", cnf->lq_level);
515
516   WRITE_TO_BUF("# Link quality aging factor\n\n");
517   WRITE_TO_BUF("LinkQualityAging\t%f\n\n", cnf->lq_aging);
518
519   WRITE_TO_BUF("# NAT threshold\n\n");
520   WRITE_TO_BUF("NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
521
522   WRITE_TO_BUF("# Clear screen when printing debug output?\n\n");
523   WRITE_TO_BUF("ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
524
525   /* Plugins */
526   WRITE_TO_BUF
527     ("# Olsrd plugins to load\n# This must be the absolute path to the file\n# or the loader will use the following scheme:\n");
528   WRITE_TO_BUF
529     ("# - 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");
530   if (pe) {
531     while (pe) {
532       WRITE_TO_BUF("LoadPlugin \"%s\" {\n", pe->name);
533       pp = pe->params;
534       while (pp) {
535         WRITE_TO_BUF("    PlParam \"%s\"\t\"%s\"\n", pp->key, pp->value);
536         pp = pp->next;
537       }
538       WRITE_TO_BUF("}\n");
539       pe = pe->next;
540     }
541   }
542   WRITE_TO_BUF("\n");
543
544   /* Interfaces */
545   WRITE_TO_BUF("# Interfaces\n# Multiple interfaces with the same configuration\n");
546   WRITE_TO_BUF("# can shar the same config block. Just list the\n# interfaces(e.g. Interface \"eth0\" \"eth2\"\n\n");
547   /* Interfaces */
548   if (in) {
549     bool first = true;
550     while (in) {
551       WRITE_TO_BUF("Interface \"%s\" {\n", in->name);
552
553       if (first)
554         WRITE_TO_BUF
555           ("   # Interface Mode to use. Defines\n    # forward behaviour depending on\n    # interface type\n    # valid option are [mesh] and ether\n\n");
556
557       if (in->cnf->mode!=1) {
558         WRITE_TO_BUF("    #Mode\tmesh\n\n");
559       } else {
560         if (first)
561           WRITE_TO_BUF("    Mode\tether\n\n");
562       }
563
564       if (first)
565         WRITE_TO_BUF("\n");
566
567       if (first)
568         WRITE_TO_BUF
569           ("    # 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");
570
571       if (in->cnf->ipv4_multicast.v4.s_addr) {
572         WRITE_TO_BUF("    Ip4Broadcast\t%s\n", inet_ntoa(in->cnf->ipv4_multicast.v4));
573       } else {
574         if (first)
575           WRITE_TO_BUF("    #Ip4Broadcast\t255.255.255.255\n");
576       }
577
578       if (first)
579         WRITE_TO_BUF
580           ("    # IPv6 multicast address.\n    # If not defined, "OLSR_IPV6_MCAST" is used\n");
581       WRITE_TO_BUF("    IPv6Multicast\t%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)));
582       if (first)
583         WRITE_TO_BUF("\n");
584
585       if (first)
586         WRITE_TO_BUF
587           ("    # IPv4 src address.\n    # If not defined, the interface IP is used\n");
588       WRITE_TO_BUF("    IPv6Multicast\t%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)));
589       if (first)
590         WRITE_TO_BUF("\n");
591
592       if (first)
593         WRITE_TO_BUF
594           ("    # IPv6 src prefix.\n    # If not defined, a not-linklocal interface IP is used\n");
595       WRITE_TO_BUF("    IPv6Src\t%s\n", olsr_ip_prefix_to_string(&in->cnf->ipv6_src));
596       if (first)
597         WRITE_TO_BUF("\n");
598
599       if (first)
600         WRITE_TO_BUF
601           ("    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
602
603       if (in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
604         WRITE_TO_BUF("    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
605       else if (first)
606         WRITE_TO_BUF("    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
607       if (in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
608         WRITE_TO_BUF("    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
609       else if (first)
610         WRITE_TO_BUF("    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
611       if (in->cnf->tc_params.emission_interval != TC_INTERVAL)
612         WRITE_TO_BUF("    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
613       else if (first)
614         WRITE_TO_BUF("    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
615       if (in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
616         WRITE_TO_BUF("    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
617       else if (first)
618         WRITE_TO_BUF("    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
619       if (in->cnf->mid_params.emission_interval != MID_INTERVAL)
620         WRITE_TO_BUF("    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
621       else if (first)
622         WRITE_TO_BUF("    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
623       if (in->cnf->mid_params.validity_time != MID_HOLD_TIME)
624         WRITE_TO_BUF("    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
625       else if (first)
626         WRITE_TO_BUF("    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
627       if (in->cnf->hna_params.emission_interval != HNA_INTERVAL)
628         WRITE_TO_BUF("    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
629       else if (first)
630         WRITE_TO_BUF("    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
631       if (in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
632         WRITE_TO_BUF("    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
633       else if (first)
634         WRITE_TO_BUF("    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
635
636       mult = in->cnf->lq_mult;
637
638       if (mult == NULL) {
639         if (first)
640           WRITE_TO_BUF("    #LinkQualityMult\tdefault 1.0\n");
641       } else {
642         while (mult != NULL) {
643           WRITE_TO_BUF("    LinkQualityMult\t%s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
644                        (float)(mult->value) / 65536.0);
645           mult = mult->next;
646         }
647       }
648
649       if (first) {
650         WRITE_TO_BUF("    # When multiple links exist between hosts\n");;
651         WRITE_TO_BUF("    # the weight of interface is used to determine\n");;
652         WRITE_TO_BUF("    # the link to use. Normally the weight is\n");
653         WRITE_TO_BUF("    # automatically calculated by olsrd based\n");;
654         WRITE_TO_BUF("    # on the characteristics of the interface,\n");;
655         WRITE_TO_BUF("    # but here you can specify a fixed value.\n");;
656         WRITE_TO_BUF("    # Olsrd will choose links with the lowest value.\n");
657         WRITE_TO_BUF("    # Note:\n");;
658         WRITE_TO_BUF("    # Interface weight is used only when LinkQualityLevel is 0.\n");;
659         WRITE_TO_BUF("    # For any other value of LinkQualityLevel, the interface ETX\n");;
660         WRITE_TO_BUF("    # value is used instead.\n\n");;
661       }
662       if (in->cnf->weight.fixed) {
663         WRITE_TO_BUF("    Weight\t %d\n\n", in->cnf->weight.value);
664       } else {
665         if (first)
666           WRITE_TO_BUF("    #Weight\t 0\n\n");
667       }
668
669       WRITE_TO_BUF("}\n\n");
670       in = in->next;
671       first = false;
672     }
673
674   }
675
676   WRITE_TO_BUF("\n# END AUTOGENERATED CONFIG\n");
677
678   return size;
679 }
680
681 /*
682  * Local Variables:
683  * c-basic-offset: 2
684  * indent-tabs-mode: nil
685  * End:
686  */