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