Makefile: WARNINGS: add -Wdouble-promotion
[olsrd.git] / src / cfgparser / olsrd_conf.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 "olsrd_conf.h"
43 #include "ipcalc.h"
44 #include "olsr_cfg.h"
45 #include "defs.h"
46 #include "net_olsr.h"
47 #include "olsr.h"
48
49 #include <assert.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <stdlib.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <netinet/in.h>
57 #include <arpa/inet.h>
58 #ifdef linux
59 #include <linux/types.h>
60 #include <linux/rtnetlink.h>
61 #include <linux/version.h>
62 #endif
63
64 extern FILE *yyin;
65 extern int yyparse(void);
66
67 static char interface_defaults_name[] = "[InterfaceDefaults]";
68
69 const char *FIB_METRIC_TXT[] = {
70   "flat",
71   "correct",
72   "approx",
73 };
74
75 const char *GW_UPLINK_TXT[] = {
76   "none",
77   "ipv4",
78   "ipv6",
79   "both"
80 };
81
82 const char *OLSR_IF_MODE[] = {
83   "mesh",
84   "ether"
85 };
86
87 static char copyright_string[] __attribute__ ((unused)) =
88   "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
89
90 int current_line;
91
92 /* Global stuff externed in defs.h */
93 FILE *debug_handle;                    /* Where to send debug(defaults to stdout) */
94 struct olsrd_config *olsr_cnf;         /* The global configuration */
95
96 #ifdef MAKEBIN
97
98 /* Build as standalone binary */
99 int
100 main(int argc, char *argv[])
101 {
102   struct olsrd_config *cnf;
103
104   if (argc == 1) {
105     fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
106     exit(EXIT_FAILURE);
107   }
108
109   if ((cnf = olsrd_parse_cnf(argv[1])) == 0) {
110     if ((argc > 2) && (!strcmp(argv[2], "-print"))) {
111       olsrd_print_cnf(cnf);
112       olsrd_write_cnf(cnf, "./out.conf");
113     } else
114       printf("Use -print to view parsed values\n");
115     printf("Configfile parsed OK\n");
116   } else {
117     printf("Failed parsing \"%s\"\n", argv[1]);
118   }
119
120   return 0;
121 }
122
123 #else
124
125 /* Build as part of olsrd */
126
127 #endif
128
129 int
130 olsrd_parse_cnf(const char *filename)
131 {
132   struct olsr_if *in, *new_ifqueue;
133   int rc;
134
135   fprintf(stderr, "Parsing file: \"%s\"\n", filename);
136
137   yyin = fopen(filename, "r");
138   if (yyin == NULL) {
139     fprintf(stderr, "Cannot open configuration file '%s': %s.\n", filename, strerror(errno));
140     return -1;
141   }
142
143   current_line = 1;
144   rc = yyparse();
145   fclose(yyin);
146   if (rc != 0) {
147     return -1;
148   }
149
150   /* Reverse the queue (added by user request) */
151   in = olsr_cnf->interfaces;
152   new_ifqueue = NULL;
153
154   while (in) {
155     struct olsr_if *in_tmp = in;
156     in = in->next;
157
158     in_tmp->next = new_ifqueue;
159     new_ifqueue = in_tmp;
160   }
161
162   olsr_cnf->interfaces = new_ifqueue;
163
164   for (in = olsr_cnf->interfaces; in != NULL; in = in->next) {
165     /* set various stuff */
166     in->configured = false;
167     in->interf = NULL;
168     in->host_emul = false;
169   }
170   return 0;
171 }
172
173 /* prints an interface (and checks it againt the default config) and the inverted config */
174 static void
175 olsrd_print_interface_cnf(struct if_config_options *cnf, struct if_config_options *cnfi, bool defcnf)
176 {
177   struct olsr_lq_mult *mult;
178   int lq_mult_cnt = 0;
179   char ipv6_buf[INET6_ADDRSTRLEN];                  /* buffer for IPv6 inet_htop */
180
181   if (cnf->ipv4_multicast.v4.s_addr) {
182     printf("\tIPv4 broadcast/multicast : %s%s\n", inet_ntoa(cnf->ipv4_multicast.v4),DEFAULT_STR(ipv4_multicast.v4.s_addr));
183   } else {
184     printf("\tIPv4 broadcast/multicast : AUTO%s\n",DEFAULT_STR(ipv4_multicast.v4.s_addr));
185   }
186
187   if (cnf->mode==IF_MODE_ETHER){
188     printf("\tMode           : ether%s\n",DEFAULT_STR(mode));
189   } else {
190     printf("\tMode           : mesh%s\n",DEFAULT_STR(mode));
191   }
192
193   printf("\tIPv6 multicast           : %s%s\n", inet_ntop(AF_INET6, &cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)),DEFAULT_STR(ipv6_multicast.v6));
194
195   printf("\tHELLO emission/validity  : %0.2f%s/%0.2f%s\n", (double)cnf->hello_params.emission_interval, DEFAULT_STR(hello_params.emission_interval),
196                   (double)cnf->hello_params.validity_time,DEFAULT_STR(hello_params.validity_time));
197   printf("\tTC emission/validity     : %0.2f%s/%0.2f%s\n", (double)cnf->tc_params.emission_interval, DEFAULT_STR(tc_params.emission_interval),
198                   (double)cnf->tc_params.validity_time,DEFAULT_STR(tc_params.validity_time));
199   printf("\tMID emission/validity    : %0.2f%s/%0.2f%s\n", (double)cnf->mid_params.emission_interval, DEFAULT_STR(mid_params.emission_interval),
200                   (double)cnf->mid_params.validity_time,DEFAULT_STR(mid_params.validity_time));
201   printf("\tHNA emission/validity    : %0.2f%s/%0.2f%s\n", (double)cnf->hna_params.emission_interval, DEFAULT_STR(hna_params.emission_interval),
202                   (double)cnf->hna_params.validity_time,DEFAULT_STR(hna_params.validity_time));
203
204   for (mult = cnf->lq_mult; mult != NULL; mult = mult->next) {
205     lq_mult_cnt++;
206     printf("\tLinkQualityMult          : %s %0.2f %s\n", inet_ntop(olsr_cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
207       (double)(mult->value) / (double)65536.0, ((lq_mult_cnt > cnf->orig_lq_mult_cnt)?" (d)":""));
208   }
209
210   printf("\tAutodetect changes       : %s%s\n", cnf->autodetect_chg ? "yes" : "no",DEFAULT_STR(autodetect_chg));
211 }
212
213 #ifdef linux
214 static int olsrd_sanity_check_rtpolicy(struct olsrd_config *cnf) {
215   int prio;
216
217   /* calculate rt_policy defaults if necessary */
218   if (!cnf->smart_gw_active) {
219     /* default is "no policy rules" and "everything into the main table" */
220     if (cnf->rt_table == DEF_RT_AUTO) {
221       cnf->rt_table = 254;
222     }
223     if (cnf->rt_table_default == DEF_RT_AUTO) {
224       cnf->rt_table_default = cnf->rt_table;
225     }
226     if (cnf->rt_table_tunnel != DEF_RT_AUTO) {
227       fprintf(stderr, "Warning, setting a table for tunnels without SmartGW does not make sense.\n");
228     }
229     cnf->rt_table_tunnel = cnf->rt_table_default;
230
231     /* priority rules default is "none" */
232     if (cnf->rt_table_pri == DEF_RT_AUTO) {
233       cnf->rt_table_pri = DEF_RT_NONE;
234     }
235     if (cnf->rt_table_defaultolsr_pri == DEF_RT_AUTO) {
236       cnf->rt_table_defaultolsr_pri = DEF_RT_NONE;
237     }
238     if (cnf->rt_table_tunnel_pri == DEF_RT_AUTO) {
239       cnf->rt_table_tunnel_pri = DEF_RT_NONE;
240     }
241     if (cnf->rt_table_default_pri == DEF_RT_AUTO) {
242       cnf->rt_table_default_pri = DEF_RT_NONE;
243     }
244   }
245   else {
246     /* default is "policy rules" and "everything into separate tables (254, 223, 224)" */
247     if (cnf->rt_table == DEF_RT_AUTO) {
248       cnf->rt_table = 254;
249     }
250     if (cnf->rt_table_default == DEF_RT_AUTO) {
251       cnf->rt_table_default = 223;
252     }
253     if (cnf->rt_table_tunnel == DEF_RT_AUTO) {
254       cnf->rt_table_tunnel = 224;
255     }
256
257     /* default for "rt_table_pri" is none (main table already has a policy rule */
258     prio = 32766;
259     if (cnf->rt_table_pri > 0) {
260       prio = cnf->rt_table_pri;
261     }
262     else if (cnf->rt_table_pri == DEF_RT_AUTO) {
263       /* choose default */
264       olsr_cnf->rt_table_pri = DEF_RT_NONE;
265       fprintf(stderr, "No policy rule for rt_table_pri\n");
266     }
267
268     /* default for "rt_table_defaultolsr_pri" is +10 */
269     prio += 10;
270     if (cnf->rt_table_defaultolsr_pri > 0) {
271       prio = cnf->rt_table_defaultolsr_pri;
272     }
273     else if (cnf->rt_table_defaultolsr_pri == DEF_RT_AUTO) {
274       olsr_cnf->rt_table_defaultolsr_pri = prio;
275       fprintf(stderr, "Choose priority %u for rt_table_defaultolsr_pri\n", prio);
276     }
277
278     prio += 10;
279     if (cnf->rt_table_tunnel_pri > 0) {
280       prio = cnf->rt_table_tunnel_pri;
281     }
282     else if (cnf->rt_table_tunnel_pri == DEF_RT_AUTO) {
283       olsr_cnf->rt_table_tunnel_pri = prio;
284       fprintf(stderr, "Choose priority %u for rt_table_tunnel_pri\n", prio);
285     }
286
287     prio += 10;
288     if (cnf->rt_table_default_pri == DEF_RT_AUTO) {
289       olsr_cnf->rt_table_default_pri = prio;
290       fprintf(stderr, "Choose priority %u for rt_table_default_pri\n", prio);
291     }
292   }
293
294   /* check rule priorities */
295   if (cnf->rt_table_pri > 0) {
296     if (cnf->rt_table >= 253) {
297       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table);
298       return -1;
299     }
300   }
301
302   prio = cnf->rt_table_pri;
303   if (cnf->rt_table_defaultolsr_pri > 0) {
304     if (prio >= cnf->rt_table_defaultolsr_pri) {
305       fprintf(stderr, "rttable_defaultolsr priority must be greater than %d\n", prio);
306       return -1;
307     }
308     if (cnf->rt_table_default >= 253) {
309       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table_default);
310       return -1;
311     }
312     prio = olsr_cnf->rt_table_defaultolsr_pri;
313   }
314
315   if (cnf->rt_table_tunnel_pri > 0 ) {
316     if (prio >= cnf->rt_table_tunnel_pri) {
317       fprintf(stderr, "rttable_tunnel priority must be greater than %d\n", prio);
318       return -1;
319     }
320     if (cnf->rt_table_tunnel >= 253) {
321       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table_tunnel);
322       return -1;
323     }
324     prio = cnf->rt_table_tunnel_pri;
325   }
326
327   if (cnf->rt_table_default_pri > 0) {
328     if (prio >= cnf->rt_table_default_pri) {
329       fprintf(stderr, "rttable_default priority must be greater than %d\n", prio);
330       return -1;
331     }
332     if (cnf->rt_table_default >= 253) {
333       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table_default);
334       return -1;
335     }
336   }
337
338   /* filter rt_proto entry */
339   if (cnf->rt_proto == 1) {
340     /* protocol 1 is reserved, so better use 0 */
341     cnf->rt_proto = 0;
342   }
343   else if (cnf->rt_proto == 0) {
344     cnf->rt_proto = RTPROT_BOOT;
345   }
346   return 0;
347 }
348
349 #endif
350
351
352 static 
353 int olsrd_sanity_check_interface_cnf(struct if_config_options * io, struct olsrd_config * cnf, char* name) {
354   struct olsr_lq_mult *mult;
355
356   /* HELLO interval */
357
358   if (io->hello_params.validity_time < 0.0f) {
359     if (cnf->lq_level == 0)
360       io->hello_params.validity_time = NEIGHB_HOLD_TIME;
361
362     else
363       io->hello_params.validity_time = (int)(REFRESH_INTERVAL / cnf->lq_aging);
364   }
365
366   if (io->hello_params.emission_interval < cnf->pollrate || io->hello_params.emission_interval > io->hello_params.validity_time) {
367     fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->hello_params.emission_interval,
368                 (double)io->hello_params.validity_time, name);
369     return -1;
370   }
371
372   /* TC interval */
373   if (io->tc_params.emission_interval < cnf->pollrate || io->tc_params.emission_interval > io->tc_params.validity_time) {
374     fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->tc_params.emission_interval,
375                 (double)io->tc_params.validity_time, name);
376     return -1;
377   }
378
379   if (cnf->min_tc_vtime > 0.0f && (io->tc_params.validity_time / io->tc_params.emission_interval) < 128.0f) {
380     fprintf(stderr, "Please use a tc vtime at least 128 times the emission interval while using the min_tc_vtime hack.\n");
381     return -1;
382   }
383   /* MID interval */
384   if (io->mid_params.emission_interval < cnf->pollrate || io->mid_params.emission_interval > io->mid_params.validity_time) {
385     fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->mid_params.emission_interval,
386                 (double)io->mid_params.validity_time, name);
387     return -1;
388   }
389
390   /* HNA interval */
391   if (io->hna_params.emission_interval < cnf->pollrate || io->hna_params.emission_interval > io->hna_params.validity_time) {
392     fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->hna_params.emission_interval,
393                 (double)io->hna_params.validity_time, name);
394     return -1;
395   }
396
397   for (mult = io->lq_mult; mult; mult=mult->next) {
398     if (mult->value > LINK_LOSS_MULTIPLIER) {
399       struct ipaddr_str buf;
400
401       fprintf(stderr, "Bad Linkquality multiplier ('%s' on IP %s: %0.2f)\n",
402           name, olsr_ip_to_string(&buf, &mult->addr), (double)mult->value / (double)LINK_LOSS_MULTIPLIER);
403       return -1;
404     }
405   }
406   return 0;
407 }
408
409
410 int
411 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
412 {
413   struct olsr_if *in = cnf->interfaces;
414   struct if_config_options *io;
415
416   /* Debug level */
417   if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) {
418     fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
419     return -1;
420   }
421
422   /* IP version */
423   if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) {
424     fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
425     return -1;
426   }
427
428   /* TOS range */
429   if (cnf->tos > MAX_TOS) {
430     fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
431     return -1;
432   }
433
434   /* TOS ECN */
435   if (cnf->tos & 0x03) {
436     fprintf(stderr, "TOS %d has set ECN bits, not allowed\n", cnf->tos);
437     return -1;
438   }
439
440   if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) {
441     fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
442     return -1;
443   }
444
445   /* Hysteresis */
446   if (cnf->use_hysteresis == true) {
447     if (cnf->hysteresis_param.scaling < (float)MIN_HYST_PARAM || cnf->hysteresis_param.scaling > (float)MAX_HYST_PARAM) {
448       fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", (double)cnf->hysteresis_param.scaling);
449       return -1;
450     }
451
452     if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) {
453       fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", (double)cnf->hysteresis_param.thr_high,
454                   (double)cnf->hysteresis_param.thr_low);
455       return -1;
456     }
457
458     if (cnf->hysteresis_param.thr_high < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > (float)MAX_HYST_PARAM) {
459       fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_high);
460       return -1;
461     }
462
463     if (cnf->hysteresis_param.thr_low < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > (float)MAX_HYST_PARAM) {
464       fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_low);
465       return -1;
466     }
467   }
468
469   /* Pollrate */
470   if (cnf->pollrate < (float)MIN_POLLRATE || cnf->pollrate > (float)MAX_POLLRATE) {
471     fprintf(stderr, "Pollrate %0.2f is not allowed\n", (double)cnf->pollrate);
472     return -1;
473   }
474
475   /* NIC Changes Pollrate */
476
477   if (cnf->nic_chgs_pollrate < (float)MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > (float)MAX_NICCHGPOLLRT) {
478     fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", (double)cnf->nic_chgs_pollrate);
479     return -1;
480   }
481
482   /* TC redundancy */
483   if (cnf->tc_redundancy != 2) {
484     fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. "
485         "It was discovered late in the stable tree development and cannot "
486         "be solved without a difficult change in the dijkstra code. "
487         "Feel free to contact the olsr-user mailinglist "
488         "(http://www.olsr.org/?q=mailing-lists) to learn more "
489         "about the problem. The next version of OLSR will have working "
490         "tc-redundancy again.\n");
491     return -1;
492   }
493
494   /* MPR coverage */
495   if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) {
496     fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
497     return -1;
498   }
499
500   /* Link Q and hysteresis cannot be activated at the same time */
501   if (cnf->use_hysteresis == true && cnf->lq_level) {
502     fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
503     return -1;
504   }
505
506   /* Link quality level */
507   if (cnf->lq_level != 0 && cnf->lq_level != 2) {
508     fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
509     return -1;
510   }
511
512   /* Link quality window size */
513   if (cnf->lq_level && (cnf->lq_aging < (float)MIN_LQ_AGING || cnf->lq_aging > (float)MAX_LQ_AGING)) {
514     fprintf(stderr, "LQ aging factor %f is not allowed\n", (double)cnf->lq_aging);
515     return -1;
516   }
517
518   /* NAT threshold value */
519   if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1f || cnf->lq_nat_thresh > 1.0f)) {
520     fprintf(stderr, "NAT threshold %f is not allowed\n", (double)cnf->lq_nat_thresh);
521     return -1;
522   }
523
524 #if defined linux
525 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
526   if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) {
527     fprintf(stderr, "Smart gateways are not supported for linux kernel 2.4 and ipv6\n");
528     return -1;
529   }
530 #endif
531
532   /* this rtpolicy settings are also currently only used in Linux */
533   if (olsrd_sanity_check_rtpolicy(cnf)) {
534     return -1;
535   }
536
537 #endif
538
539   if (in == NULL) {
540     fprintf(stderr, "No interfaces configured!\n");
541     return -1;
542   }
543
544   if (cnf->min_tc_vtime < 0.0f) {
545     fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
546     return -1;
547   }
548   if (cnf->min_tc_vtime > 0.0f) {
549           fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
550   }
551
552   if (cnf->smart_gw_period < MIN_SMARTGW_PERIOD || cnf->smart_gw_period > MAX_SMARTGW_PERIOD) {
553     fprintf(stderr, "Error, bad gateway period: %d msec (should be %d-%d)\n",
554         cnf->smart_gw_period, MIN_SMARTGW_PERIOD, MAX_SMARTGW_PERIOD);
555     return -1;
556   }
557   if (cnf->smart_gw_stablecount < MIN_SMARTGW_STABLE || cnf->smart_gw_stablecount > MAX_SMARTGW_STABLE) {
558     fprintf(stderr, "Error, bad gateway stable count: %d (should be %d-%d)\n",
559         cnf->smart_gw_stablecount, MIN_SMARTGW_STABLE, MAX_SMARTGW_STABLE);
560     return -1;
561   }
562   if (((cnf->smart_gw_thresh < MIN_SMARTGW_THRES) || (cnf->smart_gw_thresh > MAX_SMARTGW_THRES)) && (cnf->smart_gw_thresh != 0)) {
563     fprintf(stderr, "Smart gateway threshold %d is not allowed (should be %d-%d)\n", cnf->smart_gw_thresh,
564             MIN_SMARTGW_THRES, MAX_SMARTGW_THRES);
565     return -1;
566   }
567
568   if (cnf->smart_gw_type >= GW_UPLINK_CNT) {
569     fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type);
570     return -1;
571   }
572   if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) {
573     fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n",
574         cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
575     return -1;
576   }
577   if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) {
578     fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n",
579         cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
580     return -1;
581   }
582
583   if (cnf->interface_defaults == NULL) {
584     /* get a default configuration if the user did not specify one */
585     cnf->interface_defaults = get_default_if_config();
586   } else {
587     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false);
588     olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name);
589   }
590
591   /* Interfaces */
592   while (in) {
593     struct olsr_lq_mult *mult, *mult_orig;
594
595     io = in->cnf;
596
597     olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
598
599     /*apply defaults*/
600     {
601       size_t pos;
602       struct olsr_lq_mult *mult_temp, *mult_orig_walk;
603       uint8_t *cnfptr = (uint8_t*)in->cnf;
604       uint8_t *cnfiptr = (uint8_t*)in->cnfi;
605       uint8_t *defptr = (uint8_t*)cnf->interface_defaults;
606
607       /*save interface specific lqmults, as they are merged togehter later*/
608       mult_orig = io->lq_mult;
609
610       assert(in->cnf);
611       assert(in->cnfi);
612       for (pos = 0; pos < sizeof(*in->cnf); pos++) {
613         if (cnfptr[pos] != cnfiptr[pos]) {
614           cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00;
615         }
616         else cnfiptr[pos]=0xFF;
617       }
618
619       io->lq_mult=NULL;
620       /*copy default lqmults into this interface*/
621       for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
622         /*search same lqmult in orig_list*/
623         for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
624           if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
625             break;
626           }
627         }
628         if (mult_orig_walk == NULL) {
629           mult_temp=malloc(sizeof(struct olsr_lq_mult));
630           memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
631           mult_temp->next=io->lq_mult;
632           io->lq_mult=mult_temp;
633         }
634       }
635     }
636
637     if (in->name == NULL || !strlen(in->name)) {
638       fprintf(stderr, "Interface has no name!\n");
639       return -1;
640     }
641
642     if (io == NULL) {
643       fprintf(stderr, "Interface %s has no configuration!\n", in->name);
644       return -1;
645     }
646
647     /*merge lqmults*/
648     if (mult_orig!=NULL) {
649       io->orig_lq_mult_cnt=1;
650       /*search last of interface specific lqmults*/
651       mult = mult_orig;
652       while (mult->next!=NULL) {
653         mult=mult->next;
654       }
655       /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
656       mult->next=io->lq_mult;
657       io->lq_mult=mult_orig;
658     }
659
660     if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1;
661
662     in = in->next;
663   }
664
665   return 0;
666 }
667
668 void
669 olsrd_free_cnf(struct olsrd_config *cnf)
670 {
671   struct ip_prefix_list *hd, *h = cnf->hna_entries;
672   struct olsr_if *ind, *in = cnf->interfaces;
673   struct plugin_entry *ped, *pe = cnf->plugins;
674   struct olsr_lq_mult *mult, *next_mult;
675
676   while (h) {
677     hd = h;
678     h = h->next;
679     free(hd);
680   }
681
682   while (in) {
683     for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult) {
684       next_mult = mult->next;
685       free(mult);
686     }
687
688     free(in->cnf);
689     free(in->cnfi);
690
691     ind = in;
692     in = in->next;
693
694     free(ind);
695   }
696
697   while (pe) {
698     ped = pe;
699     pe = pe->next;
700     free(ped->name);
701     free(ped);
702   }
703
704   return;
705 }
706
707 struct olsrd_config *
708 olsrd_get_default_cnf(void)
709 {
710   struct olsrd_config *c = malloc(sizeof(struct olsrd_config));
711   if (c == NULL) {
712     fprintf(stderr, "Out of memory %s\n", __func__);
713     return NULL;
714   }
715
716   set_default_cnf(c);
717   return c;
718 }
719
720 void
721 set_default_cnf(struct olsrd_config *cnf)
722 {
723   memset(cnf, 0, sizeof(*cnf));
724
725   cnf->debug_level = DEF_DEBUGLVL;
726   cnf->no_fork = false;
727   cnf->host_emul = false;
728   cnf->ip_version = AF_INET;
729   cnf->ipsize = sizeof(struct in_addr);
730   cnf->maxplen = 32;
731   cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
732   cnf->tos = DEF_TOS;
733   cnf->olsrport = DEF_OLSRPORT;
734   cnf->rt_proto = DEF_RTPROTO;
735   cnf->rt_table = DEF_RT_AUTO;
736   cnf->rt_table_default = DEF_RT_AUTO;
737   cnf->rt_table_tunnel = DEF_RT_AUTO;
738   cnf->rt_table_pri = DEF_RT_AUTO;
739   cnf->rt_table_default_pri = DEF_RT_AUTO;
740   cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
741   cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
742
743   cnf->willingness_auto = DEF_WILL_AUTO;
744   cnf->willingness = DEF_WILLINGNESS;
745   cnf->ipc_connections = DEF_IPC_CONNECTIONS;
746   cnf->fib_metric = DEF_FIB_METRIC;
747
748   cnf->use_hysteresis = DEF_USE_HYST;
749   cnf->hysteresis_param.scaling = HYST_SCALING;
750   cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
751   cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
752
753   cnf->pollrate = DEF_POLLRATE;
754   cnf->nic_chgs_pollrate = DEF_NICCHGPOLLRT;
755
756   cnf->tc_redundancy = TC_REDUNDANCY;
757   cnf->mpr_coverage = MPR_COVERAGE;
758   cnf->lq_level = DEF_LQ_LEVEL;
759   cnf->lq_fish = DEF_LQ_FISH;
760   cnf->lq_aging = DEF_LQ_AGING;
761   cnf->lq_algorithm = NULL;
762   cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
763   cnf->clear_screen = DEF_CLEAR_SCREEN;
764
765   cnf->del_gws = false;
766   cnf->will_int = 10 * HELLO_INTERVAL;
767   cnf->max_jitter = 0.0;
768   cnf->exit_value = EXIT_SUCCESS;
769   cnf->max_tc_vtime = 0.0;
770   cnf->ioctl_s = 0;
771   cnf->use_niit = DEF_USE_NIIT;
772   cnf->niit4to6_if_index = 0;
773   cnf->niit6to4_if_index = 0;
774
775   cnf->smart_gw_active = DEF_SMART_GW;
776   cnf->smart_gw_allow_nat = DEF_GW_ALLOW_NAT;
777   cnf->smart_gw_period = DEF_GW_PERIOD;
778   cnf->smart_gw_stablecount = DEF_GW_STABLE_COUNT;
779   cnf->smart_gw_thresh = DEF_GW_THRESH;
780   cnf->smart_gw_type = DEF_GW_TYPE;
781   cnf->smart_gw_uplink = DEF_UPLINK_SPEED;
782   cnf->smart_gw_uplink_nat = DEF_GW_UPLINK_NAT;
783   cnf->smart_gw_downlink = DEF_DOWNLINK_SPEED;
784
785   cnf->use_src_ip_routes = DEF_USE_SRCIP_ROUTES;
786   cnf->set_ip_forward = true;
787
788 #ifdef linux
789   cnf->rtnl_s = 0;
790 #endif
791
792 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
793   cnf->rts = 0;
794 #endif
795
796 #ifdef HTTPINFO_PUD
797   cnf->pud_position = NULL;
798 #endif
799 }
800
801 struct if_config_options *
802 get_default_if_config(void)
803 {
804   struct if_config_options *io = malloc(sizeof(*io));
805
806   if (io == NULL) {
807     fprintf(stderr, "Out of memory %s\n", __func__);
808     return NULL;
809   }
810
811   memset(io, 0, sizeof(*io));
812
813   io->mode = DEF_IF_MODE;
814
815   io->ipv6_multicast = ipv6_def_multicast;
816
817   io->lq_mult = NULL;
818
819   io->weight.fixed = false;
820   io->weight.value = 0;
821
822   io->hello_params.emission_interval = HELLO_INTERVAL;
823   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
824   io->tc_params.emission_interval = TC_INTERVAL;
825   io->tc_params.validity_time = TOP_HOLD_TIME;
826   io->mid_params.emission_interval = MID_INTERVAL;
827   io->mid_params.validity_time = MID_HOLD_TIME;
828   io->hna_params.emission_interval = HNA_INTERVAL;
829   io->hna_params.validity_time = HNA_HOLD_TIME;
830   io->autodetect_chg = true;
831
832   return io;
833
834 }
835
836 void
837 olsrd_print_cnf(struct olsrd_config *cnf)
838 {
839   struct ip_prefix_list *h = cnf->hna_entries;
840   struct olsr_if *in = cnf->interfaces;
841   struct plugin_entry *pe = cnf->plugins;
842   struct ip_prefix_list *ie = cnf->ipc_nets;
843
844   printf(" *** olsrd configuration ***\n");
845
846   printf("Debug Level      : %d\n", cnf->debug_level);
847   if (cnf->ip_version == AF_INET6)
848     printf("IpVersion        : 6\n");
849   else
850     printf("IpVersion        : 4\n");
851   if (cnf->allow_no_interfaces)
852     printf("No interfaces    : ALLOWED\n");
853   else
854     printf("No interfaces    : NOT ALLOWED\n");
855   printf("TOS              : 0x%02x\n", cnf->tos);
856   printf("OlsrPort          : %d\n", cnf->olsrport);
857   printf("RtTable          : %u\n", cnf->rt_table);
858   printf("RtTableDefault   : %u\n", cnf->rt_table_default);
859   printf("RtTableTunnel    : %u\n", cnf->rt_table_tunnel);
860   if (cnf->willingness_auto)
861     printf("Willingness      : AUTO\n");
862   else
863     printf("Willingness      : %d\n", cnf->willingness);
864
865   printf("IPC connections  : %d\n", cnf->ipc_connections);
866   while (ie) {
867     struct ipaddr_str strbuf;
868     if (ie->net.prefix_len == olsr_cnf->maxplen) {
869       printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
870     } else {
871       printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
872     }
873     ie = ie->next;
874   }
875
876   printf("Pollrate         : %0.2f\n", (double)cnf->pollrate);
877
878   printf("NIC ChangPollrate: %0.2f\n", (double)cnf->nic_chgs_pollrate);
879
880   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
881
882   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
883
884   printf("LQ level         : %d\n", cnf->lq_level);
885
886   printf("LQ fish eye      : %d\n", cnf->lq_fish);
887
888   printf("LQ aging factor  : %f\n", (double)cnf->lq_aging);
889
890   printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default");
891
892   printf("NAT threshold    : %f\n", (double)cnf->lq_nat_thresh);
893
894   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
895
896   printf("Use niit         : %s\n", cnf->use_niit ? "yes" : "no");
897
898   printf("Smart Gateway    : %s\n", cnf->smart_gw_active ? "yes" : "no");
899
900   printf("SmGw. Allow NAT  : %s\n", cnf->smart_gw_allow_nat ? "yes" : "no");
901
902   printf("SmGw. period     : %d\n", cnf->smart_gw_period);
903
904   printf("SmGw. stablecount: %d\n", cnf->smart_gw_stablecount);
905
906   printf("SmGw. threshold  : %d%%\n", cnf->smart_gw_thresh);
907
908   printf("Smart Gw. Uplink : %s\n", GW_UPLINK_TXT[cnf->smart_gw_type]);
909
910   printf("SmGw. Uplink NAT : %s\n", cnf->smart_gw_uplink_nat ? "yes" : "no");
911
912   printf("Smart Gw. speed  : %d kbit/s up, %d kbit/s down\n",
913       cnf->smart_gw_uplink, cnf->smart_gw_downlink);
914
915   if (olsr_cnf->smart_gw_prefix.prefix_len == 0) {
916     printf("# Smart Gw. prefix : ::/0\n");
917   }
918   else {
919     printf("Smart Gw. prefix : %s\n", olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
920   }
921
922   /* Interfaces */
923   if (in) {
924     /*print interface default config*/
925     printf(" InterfaceDefaults: \n");
926     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, true);
927
928     while (in)
929     { 
930       if (cnf->interface_defaults!=in->cnf)
931       {
932         printf(" dev: \"%s\"\n", in->name);
933
934         olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
935       }
936       in = in->next;
937     }
938   }
939
940   /* Plugins */
941   if (pe) {
942     printf("Plugins:\n");
943
944     while (pe) {
945       printf("\tName: \"%s\"\n", pe->name);
946       pe = pe->next;
947     }
948   }
949
950   /* Hysteresis */
951   if (cnf->use_hysteresis) {
952     printf("Using hysteresis:\n");
953     printf("\tScaling      : %0.2f\n", (double)cnf->hysteresis_param.scaling);
954     printf("\tThr high/low : %0.2f/%0.2f\n", (double)cnf->hysteresis_param.thr_high, (double)cnf->hysteresis_param.thr_low);
955   } else {
956     printf("Not using hysteresis\n");
957   }
958
959   /* HNA IPv4 and IPv6 */
960   if (h) {
961     printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6);
962     while (h) {
963       struct ipaddr_str buf;
964       printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix));
965       if (cnf->ip_version == AF_INET) {
966         union olsr_ip_addr ip;
967         olsr_prefix_to_netmask(&ip, h->net.prefix_len);
968         printf("%s\n", olsr_ip_to_string(&buf, &ip));
969       } else {
970         printf("%d\n", h->net.prefix_len);
971       }
972       h = h->next;
973     }
974   }
975 }
976
977 #if defined WIN32
978 struct ioinfo {
979   unsigned int handle;
980   unsigned char attr;
981   char buff;
982   int flag;
983   CRITICAL_SECTION lock;
984 };
985
986 void
987 win32_stdio_hack(unsigned int handle)
988 {
989   HMODULE lib;
990   struct ioinfo **info;
991
992   lib = LoadLibrary("msvcrt.dll");
993
994   info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
995
996   // (*info)[1].handle = handle;
997   // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
998
999   (*info)[2].handle = handle;
1000   (*info)[2].attr = 0x89;
1001
1002   // stdout->_file = 1;
1003   stderr->_file = 2;
1004
1005   // setbuf(stdout, NULL);
1006   setbuf(stderr, NULL);
1007 }
1008
1009 void *
1010 win32_olsrd_malloc(size_t size)
1011 {
1012   return malloc(size);
1013 }
1014
1015 void
1016 win32_olsrd_free(void *ptr)
1017 {
1018   free(ptr);
1019 }
1020 #endif
1021
1022 static void update_has_gateway_fields(void) {
1023   struct ip_prefix_list *h;
1024
1025   olsr_cnf->has_ipv4_gateway = false;
1026   olsr_cnf->has_ipv6_gateway = false;
1027
1028   for (h = olsr_cnf->hna_entries; h != NULL; h = h->next) {
1029     olsr_cnf->has_ipv4_gateway |= ip_prefix_is_v4_inetgw(&h->net) || ip_prefix_is_mappedv4_inetgw(&h->net);
1030     olsr_cnf->has_ipv6_gateway |= ip_prefix_is_v6_inetgw(&h->net);
1031   }
1032 }
1033
1034 void
1035 ip_prefix_list_add(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
1036 {
1037   struct ip_prefix_list *new_entry = malloc(sizeof(*new_entry));
1038
1039   new_entry->net.prefix = *net;
1040   new_entry->net.prefix_len = prefix_len;
1041
1042   /* Queue */
1043   new_entry->next = *list;
1044   *list = new_entry;
1045
1046   /* update gateway flags */
1047   update_has_gateway_fields();
1048 }
1049
1050 int
1051 ip_prefix_list_remove(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
1052 {
1053   struct ip_prefix_list *h = *list, *prev = NULL;
1054
1055   while (h != NULL) {
1056     if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
1057       /* Dequeue */
1058       if (prev == NULL) {
1059         *list = h->next;
1060       } else {
1061         prev->next = h->next;
1062       }
1063       free(h);
1064
1065       /* update gateway flags */
1066       update_has_gateway_fields();
1067       return 1;
1068     }
1069     prev = h;
1070     h = h->next;
1071   }
1072   return 0;
1073 }
1074
1075 struct ip_prefix_list *
1076 ip_prefix_list_find(struct ip_prefix_list *list, const union olsr_ip_addr *net, uint8_t prefix_len)
1077 {
1078   struct ip_prefix_list *h;
1079   for (h = list; h != NULL; h = h->next) {
1080     if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {
1081       return h;
1082     }
1083   }
1084   return NULL;
1085 }
1086
1087 /*
1088  * Local Variables:
1089  * c-basic-offset: 2
1090  * indent-tabs-mode: nil
1091  * End:
1092  */