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