build: get rid of HTTPINFO_PUD define
[olsrd.git] / src / cfgparser / olsrd_conf.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  *
4  * (c) by the OLSR project
5  *
6  * See our Git repository to find out who worked on this file
7  * and thus is a copyright holder on it.
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in
19  *   the documentation and/or other materials provided with the
20  *   distribution.
21  * * Neither the name of olsr.org, olsrd nor the names of its
22  *   contributors may be used to endorse or promote products derived
23  *   from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Visit http://www.olsr.org for more information.
39  *
40  * If you find this software useful feel free to make a donation
41  * to the project. For more information see the website or contact
42  * the copyright holders.
43  *
44  */
45
46 #include "olsrd_conf.h"
47 #include "ipcalc.h"
48 #include "olsr_cfg.h"
49 #include "defs.h"
50 #include "net_olsr.h"
51 #include "olsr.h"
52 #include "egressTypes.h"
53 #include "gateway.h"
54 #include "lock_file.h"
55
56 #include <assert.h>
57 #include <stdio.h>
58 #include <string.h>
59 #include <errno.h>
60 #include <stdlib.h>
61 #include <sys/types.h>
62 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
65 #include <sys/stat.h>
66 #ifdef __linux__
67 #include <linux/types.h>
68 #include <linux/rtnetlink.h>
69 #include <linux/version.h>
70 #include <sys/stat.h>
71 #include <net/if.h>
72 #include <ctype.h>
73 #endif /* __linux__ */
74
75 extern FILE *yyin;
76 extern int yyparse(void);
77
78 #define valueInRange(value, low, high) ((low <= value) && (value <= high))
79
80 #define rangesOverlap(low1, high1, low2, high2) ( \
81             valueInRange(low1 , low2, high2) || valueInRange(high1, low2, high2) || \
82             valueInRange(low2,  low1, high1) || valueInRange(high2, low1, high1))
83
84 static char interface_defaults_name[] = "[InterfaceDefaults]";
85
86 const char *FIB_METRIC_TXT[] = {
87   "flat",
88   "correct",
89   "approx",
90 };
91
92 const char *GW_UPLINK_TXT[] = {
93   "none",
94   "ipv4",
95   "ipv6",
96   "both"
97 };
98
99 const char *OLSR_IF_MODE[] = {
100   "mesh",
101   "ether"
102 };
103
104 int current_line;
105
106 /* Global stuff externed in defs.h */
107 FILE *debug_handle = NULL;             /* Where to send debug(defaults to stdout) */
108 struct olsrd_config *olsr_cnf = NULL;  /* The global configuration */
109
110 #ifdef MAKEBIN
111
112 /* Build as standalone binary */
113 int
114 main(int argc, char *argv[])
115 {
116   if (argc < 2) {
117     fprintf(stderr, "Usage: olsrd_cfgparser filename [-print]\n\n");
118     exit(EXIT_FAILURE);
119   }
120
121   olsr_cnf = olsrd_get_default_cnf(strdup(argv[1]));
122
123   if (olsrd_parse_cnf(argv[1]) == 0) {
124     if ((argc > 2) && (!strcmp(argv[2], "-print"))) {
125       olsrd_print_cnf(olsr_cnf);
126       olsrd_write_cnf(olsr_cnf, "./out.conf");
127     } else
128       printf("Use -print to view parsed values\n");
129     printf("Configfile parsed OK\n");
130   } else {
131     printf("Failed parsing \"%s\"\n", argv[1]);
132   }
133
134   return 0;
135 }
136
137 void
138 olsr_startup_sleep(int seconds __attribute__((unused))) {
139 }
140
141 #else /* MAKEBIN */
142
143 /* Build as part of olsrd */
144
145 #endif /* MAKEBIN */
146
147 /**
148  * loads a config file
149  * @return <0 if load failed, 0 otherwise
150  */
151 static int
152 olsrmain_load_config(char *file) {
153   struct stat statbuf;
154
155   if (stat(file, &statbuf) < 0) {
156     fprintf(stderr, "Could not find specified config file %s!\n%s\n\n",
157         file, strerror(errno));
158     return -1;
159   }
160
161   if (olsrd_parse_cnf(file) < 0) {
162     fprintf(stderr, "Error while reading config file %s!\n", file);
163     return -1;
164   }
165   return 0;
166 }
167
168 /*
169  * Set configfile name and
170  * check if a configfile name was given as parameter
171  */
172 bool loadConfig(int *argc, char *argv[]) {
173   char conf_file_name[FILENAME_MAX] = { 0 };
174   bool loadedConfig = false;
175   int i;
176
177   /* setup the default olsrd configuration file name in conf_file_name */
178 #ifdef _WIN32
179   size_t len = 0;
180
181 #ifndef WINCE
182   /* get the current directory */
183   GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
184 #else /* WINCE */
185   conf_file_name[0] = '\0';
186 #endif /* WINCE */
187
188   len = strlen(conf_file_name);
189   if (!len || (conf_file_name[len - 1] != '\\')) {
190     conf_file_name[len++] = '\\';
191   }
192
193   strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
194 #else /* _WIN32 */
195   strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
196 #endif /* _WIN32 */
197
198   /* get the default configuration */
199   olsr_cnf = olsrd_get_default_cnf(strdup(conf_file_name));
200
201   /* scan for -f configFile arguments */
202   for (i = 1; i < (*argc - 1);) {
203     if (strcmp(argv[i], "-f") == 0) {
204       /* setup the provided olsrd configuration file name in conf_file_name */
205       strscpy(conf_file_name, argv[i + 1], sizeof(conf_file_name));
206
207       /* remove -f confgFile arguments from argc and argv */
208       if ((i + 2) < *argc) {
209         memmove(&argv[i], &argv[i + 2], sizeof(*argv) * (*argc - i - 1));
210       }
211       *argc -= 2;
212
213       /* load the config from the file */
214       if (olsrmain_load_config(conf_file_name) < 0) {
215         return false;
216       }
217
218       loadedConfig = true;
219     } else {
220       i++;
221     }
222   }
223
224   /* set up configuration prior to processing command-line options */
225   if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) {
226     loadedConfig = true;
227   }
228
229   if (!loadedConfig) {
230     olsrd_free_cnf(&olsr_cnf);
231     olsr_cnf = olsrd_get_default_cnf(strdup(conf_file_name));
232   }
233
234   return true;
235 }
236
237 int
238 olsrd_parse_cnf(const char *filename)
239 {
240   struct olsr_if *in, *new_ifqueue;
241   int rc;
242
243   fprintf(stderr, "Parsing file: \"%s\"\n", filename);
244
245   yyin = fopen(filename, "r");
246   if (yyin == NULL) {
247     fprintf(stderr, "Cannot open configuration file '%s': %s.\n", filename, strerror(errno));
248     return -1;
249   }
250
251   current_line = 1;
252   rc = yyparse();
253   fclose(yyin);
254   if (rc != 0) {
255     /* Interface names that were parsed successfully are not cleaned up. */
256     struct olsr_if* b = olsr_cnf->interfaces;
257     while (b) {
258       free(b->name);
259       b->name = NULL;
260       b = b->next;
261     }
262     return -1;
263   }
264
265   /* Reverse the queue (added by user request) */
266   in = olsr_cnf->interfaces;
267   new_ifqueue = NULL;
268
269   while (in) {
270     struct olsr_if *in_tmp = in;
271     in = in->next;
272
273     in_tmp->next = new_ifqueue;
274     new_ifqueue = in_tmp;
275   }
276
277   olsr_cnf->interfaces = new_ifqueue;
278
279   for (in = olsr_cnf->interfaces; in != NULL; in = in->next) {
280     /* set various stuff */
281     in->configured = false;
282     in->interf = NULL;
283     in->host_emul = false;
284   }
285   return 0;
286 }
287
288 /* prints an interface (and checks it againt the default config) and the inverted config */
289 static void
290 olsrd_print_interface_cnf(struct if_config_options *cnf, struct if_config_options *cnfi, bool defcnf)
291 {
292   struct olsr_lq_mult *mult;
293   int lq_mult_cnt = 0;
294   char ipv6_buf[INET6_ADDRSTRLEN];                  /* buffer for IPv6 inet_htop */
295
296   if (cnf->ipv4_multicast.v4.s_addr) {
297     printf("\tIPv4 broadcast/multicast : %s%s\n", inet_ntoa(cnf->ipv4_multicast.v4),DEFAULT_STR(ipv4_multicast.v4.s_addr));
298   } else {
299     printf("\tIPv4 broadcast/multicast : AUTO%s\n",DEFAULT_STR(ipv4_multicast.v4.s_addr));
300   }
301
302   if (cnf->mode==IF_MODE_ETHER){
303     printf("\tMode           : ether%s\n",DEFAULT_STR(mode));
304   } else {
305     printf("\tMode           : mesh%s\n",DEFAULT_STR(mode));
306   }
307
308   printf("\tIPv6 multicast           : %s%s\n", inet_ntop(AF_INET6, &cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)),DEFAULT_STR(ipv6_multicast.v6));
309
310   printf("\tHELLO emission/validity  : %0.2f%s/%0.2f%s\n", (double)cnf->hello_params.emission_interval, DEFAULT_STR(hello_params.emission_interval),
311                   (double)cnf->hello_params.validity_time,DEFAULT_STR(hello_params.validity_time));
312   printf("\tTC emission/validity     : %0.2f%s/%0.2f%s\n", (double)cnf->tc_params.emission_interval, DEFAULT_STR(tc_params.emission_interval),
313                   (double)cnf->tc_params.validity_time,DEFAULT_STR(tc_params.validity_time));
314   printf("\tMID emission/validity    : %0.2f%s/%0.2f%s\n", (double)cnf->mid_params.emission_interval, DEFAULT_STR(mid_params.emission_interval),
315                   (double)cnf->mid_params.validity_time,DEFAULT_STR(mid_params.validity_time));
316   printf("\tHNA emission/validity    : %0.2f%s/%0.2f%s\n", (double)cnf->hna_params.emission_interval, DEFAULT_STR(hna_params.emission_interval),
317                   (double)cnf->hna_params.validity_time,DEFAULT_STR(hna_params.validity_time));
318
319   for (mult = cnf->lq_mult; mult != NULL; mult = mult->next) {
320     lq_mult_cnt++;
321     printf("\tLinkQualityMult          : %s %0.2f %s\n", inet_ntop(olsr_cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
322       (double)(mult->value) / (double)65536.0, ((lq_mult_cnt > cnf->orig_lq_mult_cnt)?" (d)":""));
323   }
324
325   printf("\tAutodetect changes       : %s%s\n", cnf->autodetect_chg ? "yes" : "no",DEFAULT_STR(autodetect_chg));
326 }
327
328 #ifdef __linux__
329 static int olsrd_sanity_check_rtpolicy(struct olsrd_config *cnf) {
330   int prio;
331
332   /* calculate rt_policy defaults if necessary */
333   if (!cnf->smart_gw_active) {
334     /* default is "no policy rules" and "everything into the main table" */
335     if (cnf->rt_table == DEF_RT_AUTO) {
336       cnf->rt_table = DEF_RT_TABLE_NR;
337     }
338     if (cnf->rt_table_default == DEF_RT_AUTO) {
339       cnf->rt_table_default = DEF_RT_TABLE_DEFAULT_NR;
340     }
341     if (cnf->rt_table_tunnel != DEF_RT_AUTO) {
342       fprintf(stderr, "Warning, setting a table for tunnels without SmartGW does not make sense.\n");
343     }
344     cnf->rt_table_tunnel = DEF_RT_TABLE_TUNNEL_NR;
345
346     /* priority rules default is "none" */
347     if (cnf->rt_table_pri == DEF_RT_AUTO) {
348       cnf->rt_table_pri = DEF_RT_TABLE_PRI;
349     }
350     if (cnf->rt_table_defaultolsr_pri == DEF_RT_AUTO) {
351       cnf->rt_table_defaultolsr_pri = DEF_RT_TABLE_DEFAULTOLSR_PRI;
352     }
353     if (cnf->rt_table_tunnel_pri == DEF_RT_AUTO) {
354       cnf->rt_table_tunnel_pri = DEF_RT_TABLE_TUNNEL_PRI;
355     }
356     if (cnf->rt_table_default_pri == DEF_RT_AUTO) {
357       cnf->rt_table_default_pri = DEF_RT_TABLE_DEFAULT_PRI;
358     }
359   }
360   else {
361     /* default is "policy rules" and "everything into separate tables (254, 223, 224)" */
362     if (cnf->rt_table == DEF_RT_AUTO) {
363       cnf->rt_table = DEF_SGW_RT_TABLE_NR;
364     }
365     if (cnf->rt_table_default == DEF_RT_AUTO) {
366       cnf->rt_table_default = DEF_SGW_RT_TABLE_DEFAULT_NR;
367     }
368     if (cnf->rt_table_tunnel == DEF_RT_AUTO) {
369       cnf->rt_table_tunnel = DEF_SGW_RT_TABLE_TUNNEL_NR;
370     }
371
372     /* default for "rt_table_pri" is none (main table already has a policy rule */
373     prio = DEF_SGW_RT_TABLE_PRI_BASE;
374     if (cnf->rt_table_pri > 0) {
375       prio = cnf->rt_table_pri;
376     }
377     else if (cnf->rt_table_pri == DEF_RT_AUTO) {
378       /* choose default */
379       olsr_cnf->rt_table_pri = DEF_SGW_RT_TABLE_PRI;
380       fprintf(stderr, "No policy rule for rt_table_pri\n");
381     }
382
383     /* default for "rt_table_defaultolsr_pri" is +10 */
384     prio += DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER;
385     if (cnf->rt_table_defaultolsr_pri > 0) {
386       prio = cnf->rt_table_defaultolsr_pri;
387     }
388     else if (cnf->rt_table_defaultolsr_pri == DEF_RT_AUTO) {
389       olsr_cnf->rt_table_defaultolsr_pri = prio;
390       fprintf(stderr, "Choose priority %u for rt_table_defaultolsr_pri\n", prio);
391     }
392
393     prio += DEF_SGW_RT_TABLE_TUNNEL_PRI_ADDER;
394     if (cnf->rt_table_tunnel_pri > 0) {
395       prio = cnf->rt_table_tunnel_pri;
396     }
397     else if (cnf->rt_table_tunnel_pri == DEF_RT_AUTO) {
398       olsr_cnf->rt_table_tunnel_pri = prio;
399       fprintf(stderr, "Choose priority %u for rt_table_tunnel_pri\n", prio);
400     }
401
402     prio += DEF_SGW_RT_TABLE_DEFAULT_PRI_ADDER;
403     if (cnf->rt_table_default_pri > 0) {
404       prio = cnf->rt_table_default_pri;
405     }
406     else if (cnf->rt_table_default_pri == DEF_RT_AUTO) {
407       olsr_cnf->rt_table_default_pri = prio;
408       fprintf(stderr, "Choose priority %u for rt_table_default_pri\n", prio);
409     }
410   }
411
412   /* check rule priorities */
413   if (cnf->rt_table_pri > 0) {
414     if (cnf->rt_table >= 253) {
415       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table);
416       return -1;
417     }
418   }
419
420   prio = cnf->rt_table_pri;
421   if (cnf->rt_table_defaultolsr_pri > 0) {
422     if (prio >= cnf->rt_table_defaultolsr_pri) {
423       fprintf(stderr, "rttable_defaultolsr priority must be greater than %d\n", prio);
424       return -1;
425     }
426     if (cnf->rt_table_default >= 253) {
427       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table_default);
428       return -1;
429     }
430     prio = olsr_cnf->rt_table_defaultolsr_pri;
431   }
432
433   if (cnf->rt_table_tunnel_pri > 0 ) {
434     if (prio >= cnf->rt_table_tunnel_pri) {
435       fprintf(stderr, "rttable_tunnel priority must be greater than %d\n", prio);
436       return -1;
437     }
438     if (cnf->rt_table_tunnel >= 253) {
439       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table_tunnel);
440       return -1;
441     }
442     prio = cnf->rt_table_tunnel_pri;
443   }
444
445   if (cnf->rt_table_default_pri > 0) {
446     if (prio >= cnf->rt_table_default_pri) {
447       fprintf(stderr, "rttable_default priority must be greater than %d\n", prio);
448       return -1;
449     }
450     if (cnf->rt_table_default >= 253) {
451       fprintf(stderr, "rttable %d does not need policy rules from OLSRd\n", cnf->rt_table_default);
452       return -1;
453     }
454   }
455
456   /* filter rt_proto entry */
457   if (cnf->rt_proto == 1) {
458     /* protocol 1 is reserved, so better use 0 */
459     cnf->rt_proto = 0;
460   }
461   else if (cnf->rt_proto == 0) {
462     cnf->rt_proto = RTPROT_BOOT;
463   }
464   return 0;
465 }
466
467 #endif /* __linux__ */
468
469
470 static 
471 int olsrd_sanity_check_interface_cnf(struct if_config_options * io, struct olsrd_config * cnf, char* name) {
472   struct olsr_lq_mult *mult;
473
474   /* HELLO interval */
475
476   if (io->hello_params.validity_time < 0.0f) {
477     if (cnf->lq_level == 0)
478       io->hello_params.validity_time = NEIGHB_HOLD_TIME;
479
480     else
481       io->hello_params.validity_time = (int)(REFRESH_INTERVAL / cnf->lq_aging);
482   }
483
484   if (io->hello_params.emission_interval < cnf->pollrate || io->hello_params.emission_interval > io->hello_params.validity_time) {
485     fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->hello_params.emission_interval,
486                 (double)io->hello_params.validity_time, name);
487     return -1;
488   }
489
490   /* TC interval */
491   if (io->tc_params.emission_interval < cnf->pollrate || io->tc_params.emission_interval > io->tc_params.validity_time) {
492     fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->tc_params.emission_interval,
493                 (double)io->tc_params.validity_time, name);
494     return -1;
495   }
496
497   if (cnf->min_tc_vtime > 0.0f && (io->tc_params.validity_time / io->tc_params.emission_interval) < 128.0f) {
498     fprintf(stderr, "Please use a tc vtime at least 128 times the emission interval while using the min_tc_vtime hack.\n");
499     return -1;
500   }
501   /* MID interval */
502   if (io->mid_params.emission_interval < cnf->pollrate || io->mid_params.emission_interval > io->mid_params.validity_time) {
503     fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->mid_params.emission_interval,
504                 (double)io->mid_params.validity_time, name);
505     return -1;
506   }
507
508   /* HNA interval */
509   if (io->hna_params.emission_interval < cnf->pollrate || io->hna_params.emission_interval > io->hna_params.validity_time) {
510     fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", (double)io->hna_params.emission_interval,
511                 (double)io->hna_params.validity_time, name);
512     return -1;
513   }
514
515   for (mult = io->lq_mult; mult; mult=mult->next) {
516     if (mult->value > LINK_LOSS_MULTIPLIER) {
517       struct ipaddr_str buf;
518
519       fprintf(stderr, "Bad Linkquality multiplier ('%s' on IP %s: %0.2f)\n",
520           name, olsr_ip_to_string(&buf, &mult->addr), (double)mult->value / (double)LINK_LOSS_MULTIPLIER);
521       return -1;
522     }
523   }
524   return 0;
525 }
526
527
528 int
529 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
530 {
531   struct olsr_if *in = cnf->interfaces;
532   struct if_config_options *io;
533
534   /* Debug level */
535   if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) {
536     fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
537     return -1;
538   }
539
540   /* IP version */
541   if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) {
542     fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
543     return -1;
544   }
545
546   /* TOS range */
547   if (cnf->tos > MAX_TOS) {
548     fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
549     return -1;
550   }
551
552   /* TOS ECN */
553   if (cnf->tos & 0x03) {
554     fprintf(stderr, "TOS %d has set ECN bits, not allowed\n", cnf->tos);
555     return -1;
556   }
557
558   if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) {
559     fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
560     return -1;
561   }
562
563   /* Hysteresis */
564   if (cnf->use_hysteresis == true) {
565     if (cnf->hysteresis_param.scaling < (float)MIN_HYST_PARAM || cnf->hysteresis_param.scaling > (float)MAX_HYST_PARAM) {
566       fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", (double)cnf->hysteresis_param.scaling);
567       return -1;
568     }
569
570     if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) {
571       fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", (double)cnf->hysteresis_param.thr_high,
572                   (double)cnf->hysteresis_param.thr_low);
573       return -1;
574     }
575
576     if (cnf->hysteresis_param.thr_high < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > (float)MAX_HYST_PARAM) {
577       fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_high);
578       return -1;
579     }
580
581     if (cnf->hysteresis_param.thr_low < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > (float)MAX_HYST_PARAM) {
582       fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_low);
583       return -1;
584     }
585   }
586
587   /* Pollrate */
588   if (cnf->pollrate < (float)MIN_POLLRATE || cnf->pollrate > (float)MAX_POLLRATE) {
589     fprintf(stderr, "Pollrate %0.2f is not allowed\n", (double)cnf->pollrate);
590     return -1;
591   }
592
593   /* NIC Changes Pollrate */
594
595   if (cnf->nic_chgs_pollrate < (float)MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > (float)MAX_NICCHGPOLLRT) {
596     fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", (double)cnf->nic_chgs_pollrate);
597     return -1;
598   }
599
600   /* TC redundancy */
601   if (cnf->tc_redundancy != 2) {
602     fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. "
603         "It was discovered late in the stable tree development and cannot "
604         "be solved without a difficult change in the dijkstra code. "
605         "Feel free to contact the olsr-user mailinglist "
606         "(http://www.olsr.org/?q=mailing-lists) to learn more "
607         "about the problem. The next version of OLSR will have working "
608         "tc-redundancy again.\n");
609     return -1;
610   }
611
612   /* MPR coverage */
613   if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) {
614     fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
615     return -1;
616   }
617
618   /* Link Q and hysteresis cannot be activated at the same time */
619   if (cnf->use_hysteresis == true && cnf->lq_level) {
620     fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
621     return -1;
622   }
623
624   /* Link quality level */
625   if (cnf->lq_level != 0 && cnf->lq_level != 2) {
626     fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
627     return -1;
628   }
629
630   /* Link quality window size */
631   if (cnf->lq_level && (cnf->lq_aging < (float)MIN_LQ_AGING || cnf->lq_aging > (float)MAX_LQ_AGING)) {
632     fprintf(stderr, "LQ aging factor %f is not allowed\n", (double)cnf->lq_aging);
633     return -1;
634   }
635
636   /* NAT threshold value */
637   if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1f || cnf->lq_nat_thresh > 1.0f)) {
638     fprintf(stderr, "NAT threshold %f is not allowed\n", (double)cnf->lq_nat_thresh);
639     return -1;
640   }
641
642 #ifdef __linux__
643 #if !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION
644 #error "Both LINUX_VERSION_CODE and KERNEL_VERSION need to be defined"
645 #else /* !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION */
646 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
647   if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) {
648     fprintf(stderr, "Smart gateways are not supported for linux kernel < 2.6.24 and ipv6\n");
649     return -1;
650   }
651 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */
652 #endif /* !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION */
653
654   /* this rtpolicy settings are also currently only used in Linux */
655   if (olsrd_sanity_check_rtpolicy(cnf)) {
656     return -1;
657   }
658
659 #endif /* __linux__ */
660
661   if (in == NULL) {
662     fprintf(stderr, "No interfaces configured!\n");
663     return -1;
664   }
665
666   if (cnf->min_tc_vtime < 0.0f) {
667     fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
668     return -1;
669   }
670   if (cnf->min_tc_vtime > 0.0f) {
671           fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
672   }
673
674 #ifdef __linux__
675   if ((cnf->smart_gw_use_count < MIN_SMARTGW_USE_COUNT_MIN) || (cnf->smart_gw_use_count > MAX_SMARTGW_USE_COUNT_MAX)) {
676     fprintf(stderr, "Error, bad gateway use count %d, outside of range [%d, %d]\n",
677         cnf->smart_gw_use_count, MIN_SMARTGW_USE_COUNT_MIN, MAX_SMARTGW_USE_COUNT_MAX);
678     return -1;
679   }
680
681   if (cnf->smart_gw_use_count > 1) {
682     struct sgw_egress_if * sgwegressif = cnf->smart_gw_egress_interfaces;
683
684     /* check that we're in IPv4 */
685     if (cnf->ip_version != AF_INET) {
686       fprintf(stderr, "Error, multi smart gateway mode is only supported for IPv4\n");
687       return -1;
688     }
689
690         /* check that the sgw takedown percentage is in the range [0, 100] */
691         if (/*(cnf->smart_gw_takedown_percentage < 0) ||*/ (cnf->smart_gw_takedown_percentage > 100)) {
692           fprintf(stderr, "Error, smart gateway takedown percentage (%u) is not in the range [0, 100]\n",
693                   cnf->smart_gw_takedown_percentage);
694           return -1;
695         }
696
697     if (!cnf->smart_gw_instance_id) {
698       fprintf(stderr, "Error, no smart gateway instance id configured in multi-gateway mode\n");
699       return -1;
700     }
701
702     {
703       size_t len = strlen(cnf->smart_gw_instance_id);
704       size_t index = 0;
705
706       if (!len) {
707         fprintf(stderr, "Error, smart gateway instance id can not be empty\n");
708         return -1;
709       }
710
711       while (index++ < len) {
712         if (isspace(cnf->smart_gw_instance_id[index])) {
713           fprintf(stderr, "Error, smart gateway instance id contains whitespace\n");
714           return -1;
715         }
716       }
717     }
718
719     if (!cnf->smart_gw_policyrouting_script) {
720       fprintf(stderr, "Error, no policy routing script configured in multi-gateway mode\n");
721       return -1;
722     }
723
724     {
725       struct stat statbuf;
726
727       int r = stat(cnf->smart_gw_policyrouting_script, &statbuf);
728       if (r) {
729         fprintf(stderr, "Error, policy routing script not found: %s\n", strerror(errno));
730         return -1;
731       }
732
733       if (!S_ISREG(statbuf.st_mode)) {
734         fprintf(stderr, "Error, policy routing script not a regular file\n");
735         return -1;
736       }
737
738       if (statbuf.st_uid) {
739         fprintf(stderr, "Error, policy routing script must be owned by root\n");
740         return -1;
741       }
742
743       if (!(statbuf.st_mode & (S_IRUSR | S_IXUSR))) {
744         fprintf(stderr, "Error, policy routing script is not executable\n");
745         return -1;
746       }
747     }
748
749     /* egress interface(s) must be set */
750     if (!sgwegressif) {
751       fprintf(stderr, "Error, no egress interfaces configured in multi-gateway mode\n");
752       return -1;
753     }
754
755     while (sgwegressif) {
756       struct olsr_if * olsrif;
757
758       /* an egress interface must have a valid length */
759       size_t len = sgwegressif->name ? strlen(sgwegressif->name) : 0;
760       if ((len < 1) || (len > IFNAMSIZ)) {
761         fprintf(stderr, "Error, egress interface '%s' has an invalid length of %lu, allowed: [1, %u]\n", sgwegressif->name, (long unsigned int) len,
762             (unsigned int) IFNAMSIZ);
763         return -1;
764       }
765
766       /* an egress interface must not be an OLSR interface */
767       olsrif = cnf->interfaces;
768       while (olsrif) {
769         if (!strcmp(olsrif->name, sgwegressif->name)) {
770           fprintf(stderr, "Error, egress interface %s already is an OLSR interface\n", sgwegressif->name);
771           return -1;
772         }
773         olsrif = olsrif->next;
774       }
775       cnf->smart_gw_egress_interfaces_count++;
776       sgwegressif = sgwegressif->next;
777     }
778
779     if (cnf->smart_gw_egress_interfaces_count > MAX_SMARTGW_EGRESS_INTERFACE_COUNT_MAX) {
780       fprintf(stderr, "Error, egress interface count %u not in range [1, %u]\n",
781           cnf->smart_gw_egress_interfaces_count, MAX_SMARTGW_EGRESS_INTERFACE_COUNT_MAX);
782       return -1;
783     }
784
785     if (cnf->smart_gw_egress_file_period < MIN_SMARTGW_EGRESS_FILE_PERIOD) {
786       fprintf(stderr, "Error, egress file period must be at least %u\n", MIN_SMARTGW_EGRESS_FILE_PERIOD);
787       return -1;
788     }
789
790     {
791       uint32_t nrOfTables = 1 + cnf->smart_gw_egress_interfaces_count + cnf->smart_gw_use_count;
792
793       uint32_t nrOfBypassRules = cnf->smart_gw_egress_interfaces_count + getNrOfOlsrInterfaces(olsr_cnf);
794       uint32_t nrOfTableRules = nrOfTables;
795       uint32_t nrOfRules = nrOfBypassRules + nrOfTableRules;
796
797       uint32_t tablesLow;
798       uint32_t tablesHigh;
799       uint32_t tablesLowMax = ((1u << 31) - nrOfTables + 1);
800
801       uint32_t rulesLow;
802       uint32_t rulesHigh;
803       uint32_t rulesLowMax = UINT32_MAX - nrOfRules;
804
805       /* setup tables low/high */
806       tablesLow = cnf->smart_gw_offset_tables;
807       tablesHigh = cnf->smart_gw_offset_tables + nrOfTables;
808
809       /*
810        * tablesLow  >  0
811        * tablesLow  >  0
812        * tablesHigh <= 2^31
813        * [tablesLow, tablesHigh] no overlap with [253, 255]
814        */
815       if (!tablesLow) {
816         fprintf(stderr, "Error, smart gateway tables offset can't be zero.\n");
817         return -1;
818       }
819
820       if (tablesLow > tablesLowMax) {
821         fprintf(stderr, "Error, smart gateway tables offset too large, maximum is %ul.\n", tablesLowMax);
822         return -1;
823       }
824
825       if (rangesOverlap(tablesLow, tablesHigh, 253, 255)) {
826         fprintf(stderr, "Error, smart gateway tables range [%u, %u] overlaps with routing tables [253, 255].\n", tablesLow, tablesHigh);
827         return -1;
828       }
829
830       /* set default for rules offset if needed */
831       if (cnf->smart_gw_offset_rules == 0) {
832         if (valueInRange(tablesLow, 1, nrOfBypassRules)) {
833           fprintf(stderr, "Error, smart gateway table offset is too low: %u bypass rules won't fit between it and zero.\n", nrOfBypassRules);
834           return -1;
835         }
836
837         cnf->smart_gw_offset_rules = tablesLow - nrOfBypassRules;
838       }
839
840       /* setup rules low/high */
841       rulesLow = cnf->smart_gw_offset_rules;
842       rulesHigh = cnf->smart_gw_offset_rules + nrOfRules;
843
844       /*
845        * rulesLow  > 0
846        * rulesHigh < 2^32
847        * [rulesLow, rulesHigh] no overlap with [32766, 32767]
848        */
849       if (!rulesLow) {
850         fprintf(stderr, "Error, smart gateway rules offset can't be zero.\n");
851         return -1;
852       }
853
854       if (rulesLow > rulesLowMax) {
855         fprintf(stderr, "Error, smart gateway rules offset too large, maximum is %ul.\n", rulesLowMax);
856         return -1;
857       }
858
859       if (rangesOverlap(rulesLow, rulesHigh, 32766, 32767)) {
860         fprintf(stderr, "Error, smart gateway rules range [%u, %u] overlaps with rules [32766, 32767].\n", rulesLow, rulesHigh);
861         return -1;
862       }
863     }
864   }
865
866   if (cnf->smart_gw_period < MIN_SMARTGW_PERIOD || cnf->smart_gw_period > MAX_SMARTGW_PERIOD) {
867     fprintf(stderr, "Error, bad gateway period: %d msec (should be %d-%d)\n",
868         cnf->smart_gw_period, MIN_SMARTGW_PERIOD, MAX_SMARTGW_PERIOD);
869     return -1;
870   }
871   if (cnf->smart_gw_stablecount < MIN_SMARTGW_STABLE || cnf->smart_gw_stablecount > MAX_SMARTGW_STABLE) {
872     fprintf(stderr, "Error, bad gateway stable count: %d (should be %d-%d)\n",
873         cnf->smart_gw_stablecount, MIN_SMARTGW_STABLE, MAX_SMARTGW_STABLE);
874     return -1;
875   }
876   if (((cnf->smart_gw_thresh < MIN_SMARTGW_THRES) || (cnf->smart_gw_thresh > MAX_SMARTGW_THRES)) && (cnf->smart_gw_thresh != 0)) {
877     fprintf(stderr, "Smart gateway threshold %d is not allowed (should be %d-%d)\n", cnf->smart_gw_thresh,
878             MIN_SMARTGW_THRES, MAX_SMARTGW_THRES);
879     return -1;
880   }
881
882   /* no checks are needed on:
883    * - cnf->smart_gw_weight_exitlink_up
884    * - cnf->smart_gw_weight_exitlink_down
885    * - cnf->smart_gw_weight_etx
886    * - cnf->smart_gw_divider_etx
887    */
888
889   if (cnf->smart_gw_type >= GW_UPLINK_CNT) {
890     fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type);
891     return -1;
892   }
893   if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) {
894     fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n",
895         cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
896     return -1;
897   }
898   if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) {
899     fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n",
900         cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
901     return -1;
902   }
903 #endif /* __linux__ */
904
905   if (cnf->interface_defaults == NULL) {
906     /* get a default configuration if the user did not specify one */
907     cnf->interface_defaults = get_default_if_config();
908   } else {
909     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false);
910     olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name);
911   }
912
913   /* Interfaces */
914   while (in) {
915     struct olsr_lq_mult *mult, *mult_orig;
916
917     assert(in->cnf);
918     assert(in->cnfi);
919
920     io = in->cnf;
921
922     olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
923
924     /*apply defaults*/
925     {
926       size_t pos;
927       struct olsr_lq_mult *mult_temp, *mult_orig_walk;
928       uint8_t *cnfptr = (uint8_t*)in->cnf;
929       uint8_t *cnfiptr = (uint8_t*)in->cnfi;
930       uint8_t *defptr = (uint8_t*)cnf->interface_defaults;
931
932       /*save interface specific lqmults, as they are merged togehter later*/
933       mult_orig = io->lq_mult;
934
935       for (pos = 0; pos < sizeof(*in->cnf); pos++) {
936         if (cnfptr[pos] != cnfiptr[pos]) {
937           cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00;
938         }
939         else cnfiptr[pos]=0xFF;
940       }
941
942       io->lq_mult=NULL;
943       /*copy default lqmults into this interface*/
944       for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
945         /*search same lqmult in orig_list*/
946         for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
947           if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
948             break;
949           }
950         }
951         if (mult_orig_walk == NULL) {
952           mult_temp=malloc(sizeof(struct olsr_lq_mult));
953           memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
954           mult_temp->next=io->lq_mult;
955           io->lq_mult=mult_temp;
956         }
957       }
958     }
959
960     if (in->name == NULL || !strlen(in->name)) {
961       fprintf(stderr, "Interface has no name!\n");
962       return -1;
963     }
964
965     /*merge lqmults*/
966     if (mult_orig!=NULL) {
967       io->orig_lq_mult_cnt=1;
968       /*search last of interface specific lqmults*/
969       mult = mult_orig;
970       while (mult->next!=NULL) {
971         mult=mult->next;
972       }
973       /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
974       mult->next=io->lq_mult;
975       io->lq_mult=mult_orig;
976     }
977
978     if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1;
979
980     in = in->next;
981   }
982
983   return 0;
984 }
985
986 void
987 olsrd_free_cnf(struct olsrd_config **cnfVariableAddress)
988 {
989   struct olsrd_config *cnf;
990
991   if (!cnfVariableAddress || !*cnfVariableAddress) {
992     return;
993   }
994
995   cnf = *cnfVariableAddress;
996
997   free(cnf->smart_gw_status_file);
998   cnf->smart_gw_status_file = NULL;
999
1000   free(cnf->smart_gw_egress_file);
1001   cnf->smart_gw_egress_file = NULL;
1002
1003   // cnf->smart_gw_egress_interfaces : cleaned up by the gateway system
1004
1005   free(cnf->smart_gw_policyrouting_script);
1006   cnf->smart_gw_policyrouting_script = NULL;
1007
1008   free(cnf->smart_gw_instance_id);
1009   cnf->smart_gw_instance_id = NULL;
1010
1011   free(cnf->lock_file);
1012   cnf->lock_file = NULL;
1013
1014   free(cnf->lq_algorithm);
1015   cnf->lq_algorithm = NULL;
1016
1017   while (cnf->interfaces) {
1018     struct olsr_if *interface;
1019     struct olsr_lq_mult *mult = NULL;
1020     struct olsr_lq_mult *next_mult = NULL;
1021
1022     for (mult = cnf->interfaces->cnf->lq_mult; mult != NULL; mult = next_mult) {
1023       next_mult = mult->next;
1024       free(mult);
1025     }
1026
1027     free(cnf->interfaces->cnf);
1028     free(cnf->interfaces->cnfi);
1029
1030     free(cnf->interfaces->name);
1031
1032     interface = cnf->interfaces;
1033     cnf->interfaces = cnf->interfaces->next;
1034
1035     free(interface);
1036   }
1037
1038   free(cnf->interface_defaults);
1039   cnf->interface_defaults = NULL;
1040
1041   ip_prefix_list_clear(&cnf->ipc_nets);
1042
1043   ip_prefix_list_clear(&cnf->hna_entries);
1044
1045   while (cnf->plugins) {
1046     struct plugin_entry *plugin = cnf->plugins;
1047     cnf->plugins = cnf->plugins->next;
1048     free(plugin->name);
1049     free(plugin);
1050   }
1051
1052   free(cnf->pidfile);
1053   cnf->pidfile = NULL;
1054
1055   free(cnf->configuration_file);
1056   cnf->configuration_file = NULL;
1057
1058   free(cnf);
1059   *cnfVariableAddress = NULL;
1060
1061   return;
1062 }
1063
1064 struct olsrd_config *
1065 olsrd_get_default_cnf(char * configuration_file)
1066 {
1067     struct olsrd_config *c = malloc(sizeof(struct olsrd_config));
1068   if (c == NULL) {
1069     fprintf(stderr, "Out of memory %s\n", __func__);
1070     return NULL;
1071   }
1072
1073   set_default_cnf(c, configuration_file);
1074   return c;
1075 }
1076
1077 void
1078 set_default_cnf(struct olsrd_config *cnf, char * configuration_file)
1079 {
1080   cnf->configuration_file = configuration_file;
1081   cnf->olsrport = DEF_OLSRPORT;
1082   cnf->debug_level = DEF_DEBUGLVL;
1083   cnf->no_fork = false;
1084   cnf->pidfile = NULL;
1085   cnf->host_emul = false;
1086   cnf->ip_version = AF_INET;
1087   cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
1088   cnf->tos = DEF_TOS;
1089   cnf->rt_proto = DEF_RTPROTO;
1090   cnf->rt_table = DEF_RT_AUTO;
1091   cnf->rt_table_default = DEF_RT_AUTO;
1092   cnf->rt_table_tunnel = DEF_RT_AUTO;
1093   cnf->rt_table_pri = DEF_RT_AUTO;
1094   cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
1095   cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
1096   cnf->rt_table_default_pri = DEF_RT_AUTO;
1097   cnf->willingness = DEF_WILLINGNESS;
1098   cnf->willingness_auto = DEF_WILL_AUTO;
1099   cnf->ipc_connections = DEF_IPC_CONNECTIONS;
1100   cnf->use_hysteresis = DEF_USE_HYST;
1101   cnf->fib_metric = DEF_FIB_METRIC;
1102   cnf->fib_metric_default = DEF_FIB_METRIC_DEFAULT;
1103   cnf->hysteresis_param.scaling = HYST_SCALING;cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
1104   cnf->plugins = NULL;
1105   cnf->hna_entries = NULL;
1106   cnf->ipc_nets = NULL;
1107   cnf->interface_defaults = NULL;
1108   cnf->interfaces = NULL;
1109   cnf->pollrate = DEF_POLLRATE;
1110   cnf->nic_chgs_pollrate = DEF_NICCHGPOLLRT;
1111   cnf->clear_screen = DEF_CLEAR_SCREEN;
1112   cnf->tc_redundancy = TC_REDUNDANCY;
1113   cnf->mpr_coverage = MPR_COVERAGE;
1114   cnf->lq_level = DEF_LQ_LEVEL;
1115   cnf->lq_fish = DEF_LQ_FISH;
1116   cnf->lq_aging = DEF_LQ_AGING;
1117   cnf->lq_algorithm = NULL;
1118
1119   cnf->min_tc_vtime = 0.0;
1120
1121   cnf->set_ip_forward = true;
1122
1123   cnf->lock_file = NULL; /* derived config */
1124   cnf->use_niit = DEF_USE_NIIT;
1125
1126   cnf->smart_gw_active = DEF_SMART_GW;
1127   cnf->smart_gw_always_remove_server_tunnel = DEF_SMART_GW_ALWAYS_REMOVE_SERVER_TUNNEL;
1128   cnf->smart_gw_allow_nat = DEF_GW_ALLOW_NAT;
1129   cnf->smart_gw_uplink_nat = DEF_GW_UPLINK_NAT;
1130   cnf->smart_gw_use_count = DEF_GW_USE_COUNT;
1131   cnf->smart_gw_takedown_percentage = DEF_GW_TAKEDOWN_PERCENTAGE;
1132   cnf->smart_gw_instance_id = NULL;
1133   cnf->smart_gw_policyrouting_script = NULL;
1134   cnf->smart_gw_egress_interfaces = NULL;
1135   cnf->smart_gw_egress_interfaces_count = 0;
1136   cnf->smart_gw_egress_file = NULL;
1137   cnf->smart_gw_egress_file_period = DEF_GW_EGRESS_FILE_PERIOD;
1138   cnf->smart_gw_status_file = NULL;
1139   cnf->smart_gw_offset_tables = DEF_GW_OFFSET_TABLES;
1140   cnf->smart_gw_offset_rules = DEF_GW_OFFSET_RULES;
1141   cnf->smart_gw_period = DEF_GW_PERIOD;
1142   cnf->smart_gw_stablecount = DEF_GW_STABLE_COUNT;
1143   cnf->smart_gw_thresh = DEF_GW_THRESH;
1144   cnf->smart_gw_weight_exitlink_up = DEF_GW_WEIGHT_EXITLINK_UP;
1145   cnf->smart_gw_weight_exitlink_down = DEF_GW_WEIGHT_EXITLINK_DOWN;
1146   cnf->smart_gw_weight_etx = DEF_GW_WEIGHT_ETX;
1147   cnf->smart_gw_divider_etx = DEF_GW_DIVIDER_ETX;
1148   cnf->smart_gw_path_max_cost_etx_max = DEF_GW_MAX_COST_MAX_ETX;
1149   cnf->smart_gw_type = DEF_GW_TYPE;
1150   cnf->smart_gw_uplink = 0;
1151   cnf->smart_gw_downlink = 0;
1152   smartgw_set_uplink(cnf, DEF_UPLINK_SPEED);
1153   smartgw_set_downlink(cnf, DEF_DOWNLINK_SPEED);
1154   // cnf->smart_gateway_bandwidth_zero : derived config set by smartgw_set_(up|down)link
1155   memset(&cnf->smart_gw_prefix, 0, sizeof(cnf->smart_gw_prefix));
1156
1157
1158   memset(&cnf->main_addr, 0, sizeof(cnf->main_addr));
1159   memset(&cnf->unicast_src_ip, 0, sizeof(cnf->unicast_src_ip));
1160   cnf->use_src_ip_routes = DEF_USE_SRCIP_ROUTES;
1161
1162
1163   cnf->maxplen = 32;
1164   cnf->ipsize = sizeof(struct in_addr);
1165   cnf->del_gws = false;
1166   cnf->will_int = 10 * HELLO_INTERVAL;
1167   cnf->max_jitter = 0.0;
1168   cnf->exit_value = EXIT_SUCCESS;
1169   cnf->max_tc_vtime = 0.0;
1170
1171   cnf->niit4to6_if_index = 0;
1172   cnf->niit6to4_if_index = 0;
1173
1174
1175   cnf->has_ipv4_gateway = false;
1176   cnf->has_ipv6_gateway = false;
1177
1178   cnf->ioctl_s = 0;
1179 #ifdef __linux__
1180   cnf->rtnl_s = 0;
1181   cnf->rt_monitor_socket = -1;
1182 #endif /* __linux__ */
1183
1184 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
1185   cnf->rts = 0;
1186 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
1187   cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
1188
1189   cnf->pud_position = NULL;
1190 }
1191
1192 struct if_config_options *
1193 get_default_if_config(void)
1194 {
1195   struct if_config_options *io = malloc(sizeof(*io));
1196
1197   if (io == NULL) {
1198     return NULL;
1199   }
1200
1201   memset(io, 0, sizeof(*io));
1202
1203   io->mode = DEF_IF_MODE;
1204
1205   io->ipv6_multicast = ipv6_def_multicast;
1206
1207   io->lq_mult = NULL;
1208
1209   io->weight.fixed = false;
1210   io->weight.value = 0;
1211
1212   io->hello_params.emission_interval = HELLO_INTERVAL;
1213   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
1214   io->tc_params.emission_interval = TC_INTERVAL;
1215   io->tc_params.validity_time = TOP_HOLD_TIME;
1216   io->mid_params.emission_interval = MID_INTERVAL;
1217   io->mid_params.validity_time = MID_HOLD_TIME;
1218   io->hna_params.emission_interval = HNA_INTERVAL;
1219   io->hna_params.validity_time = HNA_HOLD_TIME;
1220   io->autodetect_chg = true;
1221
1222   return io;
1223
1224 }
1225
1226 void
1227 olsrd_print_cnf(struct olsrd_config *cnf)
1228 {
1229   struct ip_prefix_list *h = cnf->hna_entries;
1230   struct olsr_if *in = cnf->interfaces;
1231   struct plugin_entry *pe = cnf->plugins;
1232   struct ip_prefix_list *ie = cnf->ipc_nets;
1233
1234   printf(" *** olsrd configuration ***\n");
1235
1236   printf("Debug Level      : %d\n", cnf->debug_level);
1237   if (cnf->ip_version == AF_INET6)
1238     printf("IpVersion        : 6\n");
1239   else
1240     printf("IpVersion        : 4\n");
1241   if (cnf->allow_no_interfaces)
1242     printf("No interfaces    : ALLOWED\n");
1243   else
1244     printf("No interfaces    : NOT ALLOWED\n");
1245   printf("TOS              : 0x%02x\n", cnf->tos);
1246   printf("OlsrPort          : %d\n", cnf->olsrport);
1247   printf("RtTable          : %u\n", cnf->rt_table);
1248   printf("RtTableDefault   : %u\n", cnf->rt_table_default);
1249   printf("RtTableTunnel    : %u\n", cnf->rt_table_tunnel);
1250   if (cnf->willingness_auto)
1251     printf("Willingness      : AUTO\n");
1252   else
1253     printf("Willingness      : %d\n", cnf->willingness);
1254
1255   printf("IPC connections  : %d\n", cnf->ipc_connections);
1256   while (ie) {
1257     struct ipaddr_str strbuf;
1258     if (ie->net.prefix_len == olsr_cnf->maxplen) {
1259       printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
1260     } else {
1261       printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
1262     }
1263     ie = ie->next;
1264   }
1265
1266   printf("Pollrate         : %0.2f\n", (double)cnf->pollrate);
1267
1268   printf("NIC ChangPollrate: %0.2f\n", (double)cnf->nic_chgs_pollrate);
1269
1270   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
1271
1272   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
1273
1274   printf("LQ level         : %d\n", cnf->lq_level);
1275
1276   printf("LQ fish eye      : %d\n", cnf->lq_fish);
1277
1278   printf("LQ aging factor  : %f\n", (double)cnf->lq_aging);
1279
1280   printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default");
1281
1282   printf("NAT threshold    : %f\n", (double)cnf->lq_nat_thresh);
1283
1284   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
1285
1286   printf("Use niit         : %s\n", cnf->use_niit ? "yes" : "no");
1287
1288   printf("Smart Gateway    : %s\n", cnf->smart_gw_active ? "yes" : "no");
1289
1290   printf("SmGw. Del Srv Tun: %s\n", cnf->smart_gw_always_remove_server_tunnel ? "yes" : "no");
1291
1292   printf("SmGw. Use Count  : %u\n", cnf->smart_gw_use_count);
1293
1294   printf("SmGw. Takedown%%  : %u\n", cnf->smart_gw_takedown_percentage);
1295
1296   printf("SmGw. Instance Id: %s\n", cnf->smart_gw_instance_id);
1297
1298   printf("SmGw. Pol. Script: %s\n", cnf->smart_gw_policyrouting_script);
1299
1300   printf("SmGw. Egress I/Fs:");
1301   {
1302     struct sgw_egress_if * sgwegressif = cnf->smart_gw_egress_interfaces;
1303     while (sgwegressif) {
1304       printf(" %s", sgwegressif->name);
1305       sgwegressif = sgwegressif->next;
1306     }
1307   }
1308   printf("\n");
1309
1310   printf("SmGw. Egress File: %s\n", !cnf->smart_gw_egress_file ? DEF_GW_EGRESS_FILE : cnf->smart_gw_egress_file);
1311
1312   printf("SmGw. Egr Fl Per.: %u\n", cnf->smart_gw_egress_file_period);
1313
1314   printf("SmGw. Status File: %s\n", cnf->smart_gw_status_file);
1315
1316   printf("SmGw. Offst Tabls: %u\n", cnf->smart_gw_offset_tables);
1317
1318   printf("SmGw. Offst Rules: %u\n", cnf->smart_gw_offset_rules);
1319
1320   printf("SmGw. Allow NAT  : %s\n", cnf->smart_gw_allow_nat ? "yes" : "no");
1321
1322   printf("SmGw. period     : %d\n", cnf->smart_gw_period);
1323
1324   printf("SmGw. stablecount: %d\n", cnf->smart_gw_stablecount);
1325
1326   printf("SmGw. threshold  : %d%%\n", cnf->smart_gw_thresh);
1327
1328   printf("Smart Gw. Uplink : %s\n", GW_UPLINK_TXT[cnf->smart_gw_type]);
1329
1330   printf("SmGw. Uplink NAT : %s\n", cnf->smart_gw_uplink_nat ? "yes" : "no");
1331
1332   printf("Smart Gw. speed  : %d kbit/s up, %d kbit/s down\n",
1333       cnf->smart_gw_uplink, cnf->smart_gw_downlink);
1334
1335   if (olsr_cnf->smart_gw_prefix.prefix_len == 0) {
1336     printf("# Smart Gw. prefix : ::/0\n");
1337   }
1338   else {
1339     printf("Smart Gw. prefix : %s\n", olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
1340   }
1341
1342   /* Interfaces */
1343   if (in) {
1344     /*print interface default config*/
1345     printf(" InterfaceDefaults: \n");
1346     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, true);
1347
1348     while (in)
1349     { 
1350       if (cnf->interface_defaults!=in->cnf)
1351       {
1352         printf(" dev: \"%s\"\n", in->name);
1353
1354         olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
1355       }
1356       in = in->next;
1357     }
1358   }
1359
1360   /* Plugins */
1361   if (pe) {
1362     printf("Plugins:\n");
1363
1364     while (pe) {
1365       printf("\tName: \"%s\"\n", pe->name);
1366       pe = pe->next;
1367     }
1368   }
1369
1370   /* Hysteresis */
1371   if (cnf->use_hysteresis) {
1372     printf("Using hysteresis:\n");
1373     printf("\tScaling      : %0.2f\n", (double)cnf->hysteresis_param.scaling);
1374     printf("\tThr high/low : %0.2f/%0.2f\n", (double)cnf->hysteresis_param.thr_high, (double)cnf->hysteresis_param.thr_low);
1375   } else {
1376     printf("Not using hysteresis\n");
1377   }
1378
1379   /* HNA IPv4 and IPv6 */
1380   if (h) {
1381     printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6);
1382     while (h) {
1383       struct ipaddr_str buf;
1384       printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix));
1385       if (cnf->ip_version == AF_INET) {
1386         union olsr_ip_addr ip;
1387         olsr_prefix_to_netmask(&ip, h->net.prefix_len);
1388         printf("%s\n", olsr_ip_to_string(&buf, &ip));
1389       } else {
1390         printf("%d\n", h->net.prefix_len);
1391       }
1392       h = h->next;
1393     }
1394   }
1395 }
1396
1397 #if defined _WIN32
1398 struct ioinfo {
1399   unsigned int handle;
1400   unsigned char attr;
1401   char buff;
1402   int flag;
1403   CRITICAL_SECTION lock;
1404 };
1405
1406 void
1407 win32_stdio_hack(unsigned int handle)
1408 {
1409   HMODULE lib;
1410   struct ioinfo **info;
1411
1412   lib = LoadLibrary("msvcrt.dll");
1413
1414   info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
1415
1416   // (*info)[1].handle = handle;
1417   // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
1418
1419   (*info)[2].handle = handle;
1420   (*info)[2].attr = 0x89;
1421
1422   // stdout->_file = 1;
1423   stderr->_file = 2;
1424
1425   // setbuf(stdout, NULL);
1426   setbuf(stderr, NULL);
1427 }
1428
1429 void *
1430 win32_olsrd_malloc(size_t size)
1431 {
1432   return malloc(size);
1433 }
1434
1435 void
1436 win32_olsrd_free(void *ptr)
1437 {
1438   free(ptr);
1439 }
1440 #endif /* defined _WIN32 */
1441
1442 static void update_has_gateway_fields(void) {
1443   struct ip_prefix_list *h;
1444
1445   olsr_cnf->has_ipv4_gateway = false;
1446   olsr_cnf->has_ipv6_gateway = false;
1447
1448   for (h = olsr_cnf->hna_entries; h != NULL; h = h->next) {
1449     olsr_cnf->has_ipv4_gateway |= ip_prefix_is_v4_inetgw(&h->net) || ip_prefix_is_mappedv4_inetgw(&h->net);
1450     olsr_cnf->has_ipv6_gateway |= ip_prefix_is_v6_inetgw(&h->net);
1451   }
1452 }
1453
1454 void
1455 ip_prefix_list_add(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
1456 {
1457   struct ip_prefix_list *new_entry = malloc(sizeof(*new_entry));
1458
1459   new_entry->net.prefix = *net;
1460   new_entry->net.prefix_len = prefix_len;
1461
1462   /* Queue */
1463   new_entry->next = *list;
1464   *list = new_entry;
1465
1466   /* update gateway flags */
1467   update_has_gateway_fields();
1468 }
1469
1470 int
1471 ip_prefix_list_remove(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
1472 {
1473   struct ip_prefix_list *h = *list, *prev = NULL;
1474
1475   while (h != NULL) {
1476     if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
1477       /* Dequeue */
1478       if (prev == NULL) {
1479         *list = h->next;
1480       } else {
1481         prev->next = h->next;
1482       }
1483       free(h);
1484
1485       /* update gateway flags */
1486       update_has_gateway_fields();
1487       return 1;
1488     }
1489     prev = h;
1490     h = h->next;
1491   }
1492   return 0;
1493 }
1494
1495 void ip_prefix_list_clear(struct ip_prefix_list **list) {
1496   if (!list) {
1497     return;
1498   }
1499
1500   while (*list) {
1501     ip_prefix_list_remove(list, &((*list)->net.prefix), (*list)->net.prefix_len);
1502   }
1503 }
1504
1505 struct ip_prefix_list *
1506 ip_prefix_list_find(struct ip_prefix_list *list, const union olsr_ip_addr *net, uint8_t prefix_len)
1507 {
1508   struct ip_prefix_list *h;
1509   for (h = list; h != NULL; h = h->next) {
1510     if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {
1511       return h;
1512     }
1513   }
1514   return NULL;
1515 }
1516
1517 void set_derived_cnf(struct olsrd_config * cnf) {
1518   if (!cnf->lock_file) {
1519     cnf->lock_file = olsrd_get_default_lockfile(cnf);
1520   }
1521 }
1522
1523 /*
1524  * Local Variables:
1525  * c-basic-offset: 2
1526  * indent-tabs-mode: nil
1527  * End:
1528  */