f7bee33d47138eb7b9c7330992de99626061577a
[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 "../olsr_cfg.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
54 int
55 olsrd_write_cnf(const struct olsrd_config *cnf, const char *fname)
56 {
57   struct autobuf abuf;
58   FILE *fd = fopen(fname, "w");
59   if (fd == NULL) {
60     fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
61     return -1;
62   }
63
64   printf("Writing config to file \"%s\".... ", fname);
65
66   abuf_init(&abuf, 0);
67   olsrd_write_cnf_buf(&abuf, cnf, OLSR_FALSE);
68   fputs(abuf.buf, fd);
69
70   abuf_free(&abuf);
71   fclose(fd);
72   printf("DONE\n");
73
74   return 1;
75 }
76
77 static INLINE void append_float(struct autobuf *abuf, const char *name, float val, float deflt, olsr_bool first)
78 {
79   if (val != deflt) {
80     abuf_appendf(abuf, "    %s\t%0.2f\n", name, val);
81   } else if (first) {
82     abuf_appendf(abuf, "    #%s\t%0.2f\n", name, val);
83   }
84 }
85
86 void
87 olsrd_write_cnf_buf(struct autobuf *abuf, const struct olsrd_config *cnf, olsr_bool write_more_comments)
88 {
89   char ipv6_buf[INET6_ADDRSTRLEN];             /* buffer for IPv6 inet_ntop */
90   const char *s;
91
92   abuf_appendf(abuf, "#\n"
93                      "# Configuration file for %s\n"
94                      "# automatically generated by olsrd-cnf parser v.  %s\n"
95                      "#\n\n", olsrd_version, PARSER_VERSION);
96
97   /* Debug level */
98   abuf_appendf(abuf, "# Debug level(0-9)\n"
99                      "# If set to 0 the daemon runs in the background\n"
100                      "DebugLevel\t%d\n\n", cnf->debug_level);
101
102   /* IP version */
103   abuf_appendf(abuf, "# IP version to use (4 or 6)\n"
104                      "IpVersion\t%d\n\n", cnf->ip_version == AF_INET ? 4 : 6);
105
106   /* FIB Metric */
107   abuf_appendf(abuf, "# FIBMetric (\"%s\", \"%s\", or \"%s\")\n"
108                      "FIBMetric\t\"%s\"\n\n",
109                      CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX,
110                      FIBM_FLAT == cnf->fib_metric ? CFG_FIBM_FLAT : FIBM_CORRECT == cnf->fib_metric ? CFG_FIBM_CORRECT : CFG_FIBM_APPROX);
111
112   /* HNA IPv4/IPv6 */
113   abuf_appendf(abuf, "# HNA IPv%d routes\n"
114                      "# syntax: netaddr/prefix\n"
115                      "Hna%d {\n", cnf->ip_version == AF_INET ? 4 : 6, cnf->ip_version == AF_INET ? 4 : 6);
116   if (cnf->hna_entries) {
117     struct ip_prefix_list *h;
118     for (h  = cnf->hna_entries; h != NULL; h = h->next) {
119       struct ipprefix_str strbuf;
120       abuf_appendf(abuf, "    %s\n", olsr_ip_prefix_to_string(&strbuf, &h->net));
121     }
122   }
123   abuf_appendf(abuf, "}\n\n");
124
125   /* No interfaces */
126   abuf_appendf(abuf, "# Should olsrd keep on running even if there are\n"
127                      "# no interfaces available? This is a good idea\n"
128                      "# for a PCMCIA/USB hotswap environment.\n"
129                      "# \"yes\" OR \"no\"\n"
130                      "AllowNoInt\t%s\n\n", cnf->allow_no_interfaces ? "yes" : "no");
131
132   /* TOS */
133   abuf_appendf(abuf, "# TOS(type of service) to use. Default is 16\n"
134                       "TosValue\t%d\n\n", cnf->tos);
135
136   /* RtTable */
137   abuf_appendf(abuf, "# Policy Routing Table to use. Default is 254\n"
138                      "RtTable\t\t%d\n\n", cnf->rttable);
139
140   /* RtTableDefault */
141   abuf_appendf(abuf, "# Policy Routing Table to use for the default Route. Default is 0 (Take the same table as specified by RtTable)\n"
142                      "RtTableDefault\t\t%d\n\n", cnf->rttable_default);
143
144   /* Willingness */
145   abuf_appendf(abuf, "# The fixed willingness to use(0-7)\n"
146                      "# If not set willingness will be calculated\n"
147                      "# dynammically based on battery/power status\n"
148                      "%sWillingness\t%d\n\n", cnf->willingness_auto ? "#" : "", cnf->willingness_auto ? 4 : cnf->willingness);
149
150   /* IPC */
151   abuf_appendf(abuf, "# Allow processes like the GUI front-end\n"
152                      "# to connect to the daemon.\n"
153                      "IpcConnect {\n"
154                      "    MaxConnections\t%d\n", cnf->ipc_connections);
155
156   if (cnf->ipc_nets) {
157     struct ip_prefix_list *ie;
158     for (ie = cnf->ipc_nets; ie != NULL; ie = ie->next) {
159       if (ie->net.prefix_len == olsr_cnf->maxplen) {
160         struct ipaddr_str strbuf;
161         abuf_appendf(abuf, "    Host\t\t%s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
162       } else {
163         struct ipprefix_str strbuf;
164         abuf_appendf(abuf, "    Net\t\t\t%s\n", olsr_ip_prefix_to_string(&strbuf, &ie->net));
165       }
166     }
167   }
168
169   abuf_appendf(abuf, "}\n");
170
171   /* Hysteresis */
172   abuf_appendf(abuf, "# Hysteresis adds more robustness to the\n"
173                      "# link sensing.\n"
174                      "# Used by default. 'yes' or 'no'\n"
175                      "UseHysteresis\t%s\n\n", cnf->use_hysteresis ? "yes" : "no");
176
177   abuf_appendf(abuf, "# Hysteresis parameters\n"
178                      "# Do not alter these unless you know \n"
179                      "# what you are doing!\n"
180                      "# Set to auto by default. Allowed\n"
181                      "# values are floating point values\n"
182                      "# in the interval 0,1\n"
183                      "# THR_LOW must always be lower than\n"
184                      "# THR_HIGH!!\n"
185                      "%sHystScaling\t%0.2f\n"
186                      "%sHystThrHigh\t%0.2f\n"
187                      "%sHystThrLow\t%0.2f\n\n",
188                      cnf->use_hysteresis ? "#" : "", cnf->hysteresis_param.scaling,
189                      cnf->use_hysteresis ? "#" : "", cnf->hysteresis_param.thr_high,
190                      cnf->use_hysteresis ? "#" : "", cnf->hysteresis_param.thr_low);
191
192   /* Pollrate */
193   abuf_appendf(abuf, "# Polling rate in seconds(float).\n"
194                      "# Auto uses default value 0.05 sec\n"
195                      "Pollrate\t%0.2f\n", conv_pollrate_to_secs(cnf->pollrate));
196
197   /* NIC Changes Pollrate */
198   abuf_appendf(abuf, "# Interval to poll network interfaces for configuration\n"
199                      "# changes. Defaults to 2.5 seconds\n"
200                      "NicChgsPollInt\t%0.2f\n", cnf->nic_chgs_pollrate);
201
202   /* TC redundancy */
203   abuf_appendf(abuf, "# TC redundancy\n"
204                      "# Specifies how much neighbor info should\n"
205                      "# be sent in TC messages\n"
206                      "# Possible values are:\n"
207                      "# 0 - only send MPR selectors\n"
208                      "# 1 - send MPR selectors and MPRs\n"
209                      "# 2 - send all neighbors\n"
210                      "# defaults to 0\n"
211                      "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
212
213   /* MPR coverage */
214   abuf_appendf(abuf, "# MPR coverage\n"
215                      "# Specifies how many MPRs a node should\n"
216                      "# try select to reach every 2 hop neighbor\n"
217                      "# Can be set to any integer >0\n"
218                      "# defaults to 1\n"
219                      "MprCoverage\t%d\n\n", cnf->mpr_coverage);
220
221   abuf_appendf(abuf, "# Link quality level\n"
222                      "# 0 = do not use link quality\n"
223                      "# 1 = use link quality for MPR selection\n"
224                      "# 2 = use link quality for MPR selection and routing\n"
225                      "LinkQualityLevel\t%d\n\n", cnf->lq_level);
226
227   abuf_appendf(abuf, "# Fish Eye algorithm\n"
228                      "# 0 = do not use fish eye\n"
229                      "# 1 = use fish eye\n"
230                      "LinkQualityFishEye\t%d\n\n", cnf->lq_fish);
231
232   if (cnf->lq_algorithm != NULL) {
233     abuf_appendf(abuf, "# Link quality algorithm (if LinkQualityLevel > 0)\n"
234                        "# etx_fpm (hello loss, fixed point math)\n"
235                        "# etx_float (hello loss, floating point)\n"
236                        "# etx_ff (packet loss for freifunk compat)\n"
237                        "LinkQualityAlgorithm\t\"%s\"\n\n", cnf->lq_algorithm);
238   }
239
240   abuf_appendf(abuf, "# Link quality aging factor\n"
241                      "LinkQualityAging\t%f\n\n", cnf->lq_aging);
242
243   abuf_appendf(abuf, "# NAT threshold\n"
244                      "NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
245
246   abuf_appendf(abuf, "# Clear screen when printing debug output?\n"
247                      "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
248
249   /* Plugins */
250   abuf_appendf(abuf, "# Olsrd plugins to load\n"
251                      "# This must be the absolute path to the file\n"
252                      "# or the loader will use the following scheme:\n"
253                      "# - Try the paths in the LD_LIBRARY_PATH \n"
254                      "#   environment variable.\n"
255                      "# - The list of libraries cached in /etc/ld.so.cache\n"
256                      "# - /lib, followed by /usr/lib\n\n");
257   if (cnf->plugins) {
258     struct plugin_entry *pe;
259     for (pe = cnf->plugins; pe != NULL; pe = pe->next) {
260       struct plugin_param  *pp;
261       abuf_appendf(abuf, "LoadPlugin \"%s\" {\n", pe->name);
262       for (pp = pe->params; pp != NULL; pp = pp->next) {
263         abuf_appendf(abuf, "    PlParam \"%s\"\t\"%s\"\n", pp->key, pp->value);
264       }
265       abuf_appendf(abuf, "}\n");
266     }
267   }
268   abuf_appendf(abuf, "\n");
269
270   /* Interfaces */
271   abuf_appendf(abuf, "# Interfaces\n"
272                      "# Multiple interfaces with the same configuration\n"
273                      "# can shar the same config block. Just list the\n"
274                      "# interfaces(e.g. Interface \"eth0\" \"eth2\"\n");
275   /* Interfaces */
276   if (cnf->interfaces) {
277     struct olsr_if *in;
278     olsr_bool first;
279     for (in = cnf->interfaces, first = write_more_comments;
280          in != NULL;
281          in = in->next, first = OLSR_FALSE)        {
282       abuf_appendf(abuf, "Interface \"%s\" {\n", in->name);
283
284       if (first) {
285         abuf_appendf(abuf, "    # IPv4 broadcast address to use. The\n"
286                            "    # one usefull example would be 255.255.255.255\n"
287                            "    # If not defined the broadcastaddress\n"
288                            "    # every card is configured with is used\n\n");
289       }
290
291       if (in->cnf->ipv4_broadcast.v4.s_addr) {
292         abuf_appendf(abuf, "    Ip4Broadcast\t%s\n", inet_ntoa(in->cnf->ipv4_broadcast.v4));
293       } else if (first) {
294         abuf_appendf(abuf, "    #Ip4Broadcast\t255.255.255.255\n");
295       }
296           
297       if (first) {
298         abuf_appendf(abuf, "\n    # IPv6 address type to use.\n"
299                            "    # Must be 'auto', 'site-local', 'unique-local' or 'global'\n\n");
300       }
301       if (in->cnf->ipv6_addrtype == OLSR_IP6T_SITELOCAL) s = CFG_IP6T_SITELOCAL;
302       else if(in->cnf->ipv6_addrtype == OLSR_IP6T_UNIQUELOCAL) s = CFG_IP6T_UNIQUELOCAL;
303       else if(in->cnf->ipv6_addrtype == OLSR_IP6T_GLOBAL) s = CFG_IP6T_GLOBAL;
304       else s = CFG_IP6T_AUTO;
305       abuf_appendf(abuf, "    Ip6AddrType\t%s\n\n", s);
306
307       if (first) {
308         abuf_appendf(abuf, "\n"
309                            "    # IPv6 multicast address to use when\n"
310                            "    # using site-local addresses.\n"
311                            "    # If not defined, ff05::15 is used\n");
312       }
313       abuf_appendf(abuf, "    Ip6MulticastSite\t%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
314       if (first) {
315         abuf_appendf(abuf, "\n    # IPv6 multicast address to use when\n"
316                            "    # using global addresses\n"
317                            "    # If not defined, ff0e::1 is used\n");
318       }
319       abuf_appendf(abuf, "    Ip6MulticastGlobal\t%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
320       if (first) {
321         abuf_appendf(abuf, "\n");
322       }
323       abuf_appendf(abuf, "    # Olsrd can autodetect changes in\n"
324                          "    # interface configurations. Enabled by default\n"
325                          "    # turn off to save CPU.\n"
326                          "    AutoDetectChanges: %s\n\n", in->cnf->autodetect_chg ? "yes" : "no");
327
328       if (first) {
329         abuf_appendf(abuf, "    # Emission and validity intervals.\n"
330                            "    # If not defined, RFC proposed values will\n"
331                            "    # in most cases be used.\n");
332       }
333       append_float(abuf, "HelloInterval", in->cnf->hello_params.emission_interval, HELLO_INTERVAL, first);
334       append_float(abuf, "HelloValidityTime", in->cnf->hello_params.validity_time, NEIGHB_HOLD_TIME, first);
335       append_float(abuf, "TcInterval", in->cnf->tc_params.emission_interval, TC_INTERVAL, first);
336       append_float(abuf, "TcValidityTime", in->cnf->tc_params.validity_time, TOP_HOLD_TIME, first);
337       append_float(abuf, "MidValidityTime", in->cnf->mid_params.validity_time, MID_HOLD_TIME, first);
338       append_float(abuf, "HnaInterval", in->cnf->hna_params.emission_interval, HNA_INTERVAL, first);
339       append_float(abuf, "HnaValidityTime", in->cnf->hna_params.validity_time, HNA_HOLD_TIME, first);
340       if (in->cnf->lq_mult == NULL) {
341         if (first) {
342           abuf_appendf(abuf, "    #LinkQualityMult\tdefault 1.0\n");
343         }
344       } else {
345         struct olsr_lq_mult *mult;
346         for (mult = in->cnf->lq_mult; mult != NULL; mult = mult->next) {
347           abuf_appendf(abuf, "    LinkQualityMult\t%s %0.2f\n",
348                              inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
349                              (float)mult->value / 65536.0);
350         }
351       }
352
353       if (first) {
354         abuf_appendf(abuf, "    # When multiple links exist between hosts\n"
355                            "    # the weight of interface is used to determine\n"
356                            "    # the link to use. Normally the weight is\n"
357                            "    # automatically calculated by olsrd based\n"
358                            "    # on the characteristics of the interface,\n"
359                            "    # but here you can specify a fixed value.\n"
360                            "    # Olsrd will choose links with the lowest value.\n"
361                            "    # Note:\n"
362                            "    # Interface weight is used only when LinkQualityLevel is 0.\n"
363                            "    # For any other value of LinkQualityLevel, the interface ETX\n"
364                            "    # value is used instead.\n\n");
365       }
366       if (in->cnf->weight.fixed) {
367         abuf_appendf(abuf, "    Weight\t %d\n", in->cnf->weight.value);
368       } else if (first) {
369         abuf_appendf(abuf, "    #Weight\t 0\n");
370       }
371
372       abuf_appendf(abuf, "}\n\n");
373     }
374   }
375   abuf_appendf(abuf, "\n# END AUTOGENERATED CONFIG\n");
376 }
377
378 /*
379  * Local Variables:
380  * c-basic-offset: 2
381  * indent-tabs-mode: nil
382  * End:
383  */