c445f936c55dd91630ab8c98fda97cdee21726e8
[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])) != NULL) {
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", cnf->hello_params.emission_interval, DEFAULT_STR(hello_params.emission_interval),
196          cnf->hello_params.validity_time,DEFAULT_STR(hello_params.validity_time));
197   printf("\tTC emission/validity     : %0.2f%s/%0.2f%s\n", cnf->tc_params.emission_interval, DEFAULT_STR(tc_params.emission_interval),
198          cnf->tc_params.validity_time,DEFAULT_STR(tc_params.validity_time));
199   printf("\tMID emission/validity    : %0.2f%s/%0.2f%s\n", cnf->mid_params.emission_interval, DEFAULT_STR(mid_params.emission_interval),
200          cnf->mid_params.validity_time,DEFAULT_STR(mid_params.validity_time));
201   printf("\tHNA emission/validity    : %0.2f%s/%0.2f%s\n", cnf->hna_params.emission_interval, DEFAULT_STR(hna_params.emission_interval),
202          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       (float)(mult->value) / 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 = 0;
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.0) {
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", io->hello_params.emission_interval,
368             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", io->tc_params.emission_interval,
375         io->tc_params.validity_time, name);
376     return -1;
377   }
378
379   if (cnf->min_tc_vtime > 0.0 && (io->tc_params.validity_time / io->tc_params.emission_interval) < 128) {
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", io->mid_params.emission_interval,
386             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", io->hna_params.emission_interval,
393             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), (float)mult->value / (float)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 < MIN_HYST_PARAM || cnf->hysteresis_param.scaling > MAX_HYST_PARAM) {
448       fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", 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", cnf->hysteresis_param.thr_high,
454               cnf->hysteresis_param.thr_low);
455       return -1;
456     }
457
458     if (cnf->hysteresis_param.thr_high < MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > MAX_HYST_PARAM) {
459       fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
460       return -1;
461     }
462
463     if (cnf->hysteresis_param.thr_low < MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > MAX_HYST_PARAM) {
464       fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
465       return -1;
466     }
467   }
468
469   /* Pollrate */
470   if (cnf->pollrate < MIN_POLLRATE || cnf->pollrate > MAX_POLLRATE) {
471     fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
472     return -1;
473   }
474
475   /* NIC Changes Pollrate */
476
477   if (cnf->nic_chgs_pollrate < MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > MAX_NICCHGPOLLRT) {
478     fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", 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 < MIN_LQ_AGING || cnf->lq_aging > MAX_LQ_AGING)) {
514     fprintf(stderr, "LQ aging factor %f is not allowed\n", cnf->lq_aging);
515     return -1;
516   }
517
518   /* NAT threshold value */
519   if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0)) {
520     fprintf(stderr, "NAT threshold %f is not allowed\n", 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.0) {
545     fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
546     return -1;
547   }
548   if (cnf->min_tc_vtime > 0.0) {
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_type >= GW_UPLINK_CNT) {
553     fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type);
554     return -1;
555   }
556   if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) {
557     fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n",
558         cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
559     return -1;
560   }
561   if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) {
562     fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n",
563         cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
564     return -1;
565   }
566
567   if (cnf->interface_defaults == NULL) {
568     /* get a default configuration if the user did not specify one */
569     cnf->interface_defaults = get_default_if_config();
570   } else {
571     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false);
572     olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name);
573   }
574
575   /* Interfaces */
576   while (in) {
577     struct olsr_lq_mult *mult, *mult_orig;
578
579     io = in->cnf;
580
581     olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
582
583     /*apply defaults*/
584     {
585       size_t pos;
586       struct olsr_lq_mult *mult_temp, *mult_orig_walk;
587       uint8_t *cnfptr = (uint8_t*)in->cnf;
588       uint8_t *cnfiptr = (uint8_t*)in->cnfi;
589       uint8_t *defptr = (uint8_t*)cnf->interface_defaults;
590
591       /*save interface specific lqmults, as they are merged togehter later*/
592       mult_orig = io->lq_mult;
593
594       assert(in->cnf);
595       assert(in->cnfi);
596       for (pos = 0; pos < sizeof(*in->cnf); pos++) {
597         if (cnfptr[pos] != cnfiptr[pos]) {
598           cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00;
599         }
600         else cnfiptr[pos]=0xFF;
601       }
602
603       io->lq_mult=NULL;
604       /*copy default lqmults into this interface*/
605       for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
606         /*search same lqmult in orig_list*/
607         for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
608           if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
609             break;
610           }
611         }
612         if (mult_orig_walk == NULL) {
613           mult_temp=malloc(sizeof(struct olsr_lq_mult));
614           memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
615           mult_temp->next=io->lq_mult;
616           io->lq_mult=mult_temp;
617         }
618       }
619     }
620
621     if (in->name == NULL || !strlen(in->name)) {
622       fprintf(stderr, "Interface has no name!\n");
623       return -1;
624     }
625
626     if (io == NULL) {
627       fprintf(stderr, "Interface %s has no configuration!\n", in->name);
628       return -1;
629     }
630
631     /*merge lqmults*/
632     if (mult_orig!=NULL) {
633       io->orig_lq_mult_cnt=1;
634       /*search last of interface specific lqmults*/
635       mult = mult_orig;
636       while (mult->next!=NULL) {
637         mult=mult->next;
638       }
639       /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
640       mult->next=io->lq_mult;
641       io->lq_mult=mult_orig;
642     }
643
644     if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1;
645
646     in = in->next;
647   }
648
649   return 0;
650 }
651
652 void
653 olsrd_free_cnf(struct olsrd_config *cnf)
654 {
655   struct ip_prefix_list *hd, *h = cnf->hna_entries;
656   struct olsr_if *ind, *in = cnf->interfaces;
657   struct plugin_entry *ped, *pe = cnf->plugins;
658   struct olsr_lq_mult *mult, *next_mult;
659
660   while (h) {
661     hd = h;
662     h = h->next;
663     free(hd);
664   }
665
666   while (in) {
667     for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult) {
668       next_mult = mult->next;
669       free(mult);
670     }
671
672     free(in->cnf);
673     free(in->cnfi);
674
675     ind = in;
676     in = in->next;
677
678     free(ind);
679   }
680
681   while (pe) {
682     ped = pe;
683     pe = pe->next;
684     free(ped->name);
685     free(ped);
686   }
687
688   return;
689 }
690
691 struct olsrd_config *
692 olsrd_get_default_cnf(void)
693 {
694   struct olsrd_config *c = malloc(sizeof(struct olsrd_config));
695   if (c == NULL) {
696     fprintf(stderr, "Out of memory %s\n", __func__);
697     return NULL;
698   }
699
700   set_default_cnf(c);
701   return c;
702 }
703
704 void
705 set_default_cnf(struct olsrd_config *cnf)
706 {
707   memset(cnf, 0, sizeof(*cnf));
708
709   cnf->debug_level = DEF_DEBUGLVL;
710   cnf->no_fork = false;
711   cnf->host_emul = false;
712   cnf->ip_version = AF_INET;
713   cnf->ipsize = sizeof(struct in_addr);
714   cnf->maxplen = 32;
715   cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
716   cnf->tos = DEF_TOS;
717   cnf->olsrport = DEF_OLSRPORT;
718   cnf->rt_proto = DEF_RTPROTO;
719   cnf->rt_table = DEF_RT_AUTO;
720   cnf->rt_table_default = DEF_RT_AUTO;
721   cnf->rt_table_tunnel = DEF_RT_AUTO;
722   cnf->rt_table_pri = DEF_RT_AUTO;
723   cnf->rt_table_default_pri = DEF_RT_AUTO;
724   cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
725   cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
726
727   cnf->willingness_auto = DEF_WILL_AUTO;
728   cnf->willingness = DEF_WILLINGNESS;
729   cnf->ipc_connections = DEF_IPC_CONNECTIONS;
730   cnf->fib_metric = DEF_FIB_METRIC;
731
732   cnf->use_hysteresis = DEF_USE_HYST;
733   cnf->hysteresis_param.scaling = HYST_SCALING;
734   cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
735   cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
736
737   cnf->pollrate = DEF_POLLRATE;
738   cnf->nic_chgs_pollrate = DEF_NICCHGPOLLRT;
739
740   cnf->tc_redundancy = TC_REDUNDANCY;
741   cnf->mpr_coverage = MPR_COVERAGE;
742   cnf->lq_level = DEF_LQ_LEVEL;
743   cnf->lq_fish = DEF_LQ_FISH;
744   cnf->lq_aging = DEF_LQ_AGING;
745   cnf->lq_algorithm = NULL;
746   cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
747   cnf->clear_screen = DEF_CLEAR_SCREEN;
748
749   cnf->del_gws = false;
750   cnf->will_int = 10 * HELLO_INTERVAL;
751   cnf->max_jitter = 0.0;
752   cnf->exit_value = EXIT_SUCCESS;
753   cnf->max_tc_vtime = 0.0;
754   cnf->ioctl_s = 0;
755   cnf->use_niit = DEF_USE_NIIT;
756   cnf->niit4to6_if_index = 0;
757   cnf->niit6to4_if_index = 0;
758
759   cnf->smart_gw_active = DEF_SMART_GW;
760   cnf->smart_gw_allow_nat = DEF_GW_ALLOW_NAT;
761   cnf->smart_gw_type = DEF_GW_TYPE;
762   cnf->smart_gw_uplink = DEF_UPLINK_SPEED;
763   cnf->smart_gw_uplink_nat = DEF_GW_UPLINK_NAT;
764   cnf->smart_gw_downlink = DEF_DOWNLINK_SPEED;
765
766   cnf->use_src_ip_routes = DEF_USE_SRCIP_ROUTES;
767
768 #ifdef LINUX_NETLINK_ROUTING
769   cnf->rtnl_s = 0;
770 #endif
771
772 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
773   cnf->rts = 0;
774 #endif
775 }
776
777 struct if_config_options *
778 get_default_if_config(void)
779 {
780   struct if_config_options *io = malloc(sizeof(*io));
781
782   if (io == NULL) {
783     fprintf(stderr, "Out of memory %s\n", __func__);
784     return NULL;
785   }
786
787   memset(io, 0, sizeof(*io));
788
789   io->mode = DEF_IF_MODE;
790
791   io->ipv6_multicast = ipv6_def_multicast;
792
793   io->lq_mult = NULL;
794
795   io->weight.fixed = false;
796   io->weight.value = 0;
797
798   io->hello_params.emission_interval = HELLO_INTERVAL;
799   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
800   io->tc_params.emission_interval = TC_INTERVAL;
801   io->tc_params.validity_time = TOP_HOLD_TIME;
802   io->mid_params.emission_interval = MID_INTERVAL;
803   io->mid_params.validity_time = MID_HOLD_TIME;
804   io->hna_params.emission_interval = HNA_INTERVAL;
805   io->hna_params.validity_time = HNA_HOLD_TIME;
806   io->autodetect_chg = true;
807
808   return io;
809
810 }
811
812 void
813 olsrd_print_cnf(struct olsrd_config *cnf)
814 {
815   struct ip_prefix_list *h = cnf->hna_entries;
816   struct olsr_if *in = cnf->interfaces;
817   struct plugin_entry *pe = cnf->plugins;
818   struct ip_prefix_list *ie = cnf->ipc_nets;
819
820   printf(" *** olsrd configuration ***\n");
821
822   printf("Debug Level      : %d\n", cnf->debug_level);
823   if (cnf->ip_version == AF_INET6)
824     printf("IpVersion        : 6\n");
825   else
826     printf("IpVersion        : 4\n");
827   if (cnf->allow_no_interfaces)
828     printf("No interfaces    : ALLOWED\n");
829   else
830     printf("No interfaces    : NOT ALLOWED\n");
831   printf("TOS              : 0x%02x\n", cnf->tos);
832   printf("OlsrPort          : 0x%03x\n", cnf->olsrport);
833   printf("RtTable          : %u\n", cnf->rt_table);
834   printf("RtTableDefault   : %u\n", cnf->rt_table_default);
835   printf("RtTableTunnel    : %u\n", cnf->rt_table_tunnel);
836   if (cnf->willingness_auto)
837     printf("Willingness      : AUTO\n");
838   else
839     printf("Willingness      : %d\n", cnf->willingness);
840
841   printf("IPC connections  : %d\n", cnf->ipc_connections);
842   while (ie) {
843     struct ipaddr_str strbuf;
844     if (ie->net.prefix_len == olsr_cnf->maxplen) {
845       printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
846     } else {
847       printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
848     }
849     ie = ie->next;
850   }
851
852   printf("Pollrate         : %0.2f\n", cnf->pollrate);
853
854   printf("NIC ChangPollrate: %0.2f\n", cnf->nic_chgs_pollrate);
855
856   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
857
858   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
859
860   printf("LQ level         : %d\n", cnf->lq_level);
861
862   printf("LQ fish eye      : %d\n", cnf->lq_fish);
863
864   printf("LQ aging factor  : %f\n", cnf->lq_aging);
865
866   printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default");
867
868   printf("NAT threshold    : %f\n", cnf->lq_nat_thresh);
869
870   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
871
872   printf("Use niit         : %s\n", cnf->use_niit ? "yes" : "no");
873
874   printf("Smart Gateway    : %s\n", cnf->smart_gw_active ? "yes" : "no");
875
876   printf("SmGw. Allow NAT  : %s\n", cnf->smart_gw_allow_nat ? "yes" : "no");
877
878   printf("Smart Gw. Uplink : %s\n", GW_UPLINK_TXT[cnf->smart_gw_type]);
879
880   printf("SmGw. Uplink NAT : %s\n", cnf->smart_gw_uplink_nat ? "yes" : "no");
881
882   printf("Smart Gw. speed  : %d kbit/s up, %d kbit/s down\n",
883       cnf->smart_gw_uplink, cnf->smart_gw_downlink);
884
885   if (olsr_cnf->smart_gw_prefix.prefix_len == 0) {
886     printf("# Smart Gw. prefix : ::/0\n");
887   }
888   else {
889     printf("Smart Gw. prefix : %s\n", olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
890   }
891
892   /* Interfaces */
893   if (in) {
894     /*print interface default config*/
895     printf(" InterfaceDefaults: \n");
896     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, true);
897
898     while (in)
899     { 
900       if (cnf->interface_defaults!=in->cnf)
901       {
902         printf(" dev: \"%s\"\n", in->name);
903
904         olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
905       }
906       in = in->next;
907     }
908   }
909
910   /* Plugins */
911   if (pe) {
912     printf("Plugins:\n");
913
914     while (pe) {
915       printf("\tName: \"%s\"\n", pe->name);
916       pe = pe->next;
917     }
918   }
919
920   /* Hysteresis */
921   if (cnf->use_hysteresis) {
922     printf("Using hysteresis:\n");
923     printf("\tScaling      : %0.2f\n", cnf->hysteresis_param.scaling);
924     printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
925   } else {
926     printf("Not using hysteresis\n");
927   }
928
929   /* HNA IPv4 and IPv6 */
930   if (h) {
931     printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6);
932     while (h) {
933       struct ipaddr_str buf;
934       printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix));
935       if (cnf->ip_version == AF_INET) {
936         union olsr_ip_addr ip;
937         olsr_prefix_to_netmask(&ip, h->net.prefix_len);
938         printf("%s\n", olsr_ip_to_string(&buf, &ip));
939       } else {
940         printf("%d\n", h->net.prefix_len);
941       }
942       h = h->next;
943     }
944   }
945 }
946
947 #if defined WIN32
948 struct ioinfo {
949   unsigned int handle;
950   unsigned char attr;
951   char buff;
952   int flag;
953   CRITICAL_SECTION lock;
954 };
955
956 void
957 win32_stdio_hack(unsigned int handle)
958 {
959   HMODULE lib;
960   struct ioinfo **info;
961
962   lib = LoadLibrary("msvcrt.dll");
963
964   info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
965
966   // (*info)[1].handle = handle;
967   // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
968
969   (*info)[2].handle = handle;
970   (*info)[2].attr = 0x89;
971
972   // stdout->_file = 1;
973   stderr->_file = 2;
974
975   // setbuf(stdout, NULL);
976   setbuf(stderr, NULL);
977 }
978
979 void *
980 win32_olsrd_malloc(size_t size)
981 {
982   return malloc(size);
983 }
984
985 void
986 win32_olsrd_free(void *ptr)
987 {
988   free(ptr);
989 }
990 #endif
991
992 static void update_has_gateway_fields(void) {
993   struct ip_prefix_list *h;
994
995   olsr_cnf->has_ipv4_gateway = false;
996   olsr_cnf->has_ipv6_gateway = false;
997
998   for (h = olsr_cnf->hna_entries; h != NULL; h = h->next) {
999     olsr_cnf->has_ipv4_gateway |= ip_prefix_is_v4_inetgw(&h->net) || ip_prefix_is_mappedv4_inetgw(&h->net);
1000     olsr_cnf->has_ipv6_gateway |= ip_prefix_is_v6_inetgw(&h->net);
1001   }
1002 }
1003
1004 void
1005 ip_prefix_list_add(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
1006 {
1007   struct ip_prefix_list *new_entry = malloc(sizeof(*new_entry));
1008
1009   new_entry->net.prefix = *net;
1010   new_entry->net.prefix_len = prefix_len;
1011
1012   /* Queue */
1013   new_entry->next = *list;
1014   *list = new_entry;
1015
1016   /* update gateway flags */
1017   update_has_gateway_fields();
1018 }
1019
1020 int
1021 ip_prefix_list_remove(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
1022 {
1023   struct ip_prefix_list *h = *list, *prev = NULL;
1024
1025   while (h != NULL) {
1026     if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
1027       /* Dequeue */
1028       if (prev == NULL) {
1029         *list = h->next;
1030       } else {
1031         prev->next = h->next;
1032       }
1033       free(h);
1034
1035       /* update gateway flags */
1036       update_has_gateway_fields();
1037       return 1;
1038     }
1039     prev = h;
1040     h = h->next;
1041   }
1042   return 0;
1043 }
1044
1045 struct ip_prefix_list *
1046 ip_prefix_list_find(struct ip_prefix_list *list, const union olsr_ip_addr *net, uint8_t prefix_len)
1047 {
1048   struct ip_prefix_list *h;
1049   for (h = list; h != NULL; h = h->next) {
1050     if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {
1051       return h;
1052     }
1053   }
1054   return NULL;
1055 }
1056
1057 /*
1058  * Local Variables:
1059  * c-basic-offset: 2
1060  * indent-tabs-mode: nil
1061  * End:
1062  */