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