3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
42 #include "olsrd_conf.h"
53 #include <sys/types.h>
54 #include <sys/socket.h>
55 #include <netinet/in.h>
56 #include <arpa/inet.h>
59 extern int yyparse(void);
61 static char copyright_string[] __attribute__ ((unused)) =
62 "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
66 /* Global stuff externed in defs.h */
67 FILE *debug_handle; /* Where to send debug(defaults to stdout) */
68 struct olsrd_config *olsr_cnf; /* The global configuration */
72 /* Build as standalone binary */
74 main(int argc, char *argv[])
76 struct olsrd_config *cnf;
79 fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
83 if ((cnf = olsrd_parse_cnf(argv[1])) != NULL) {
84 if ((argc > 2) && (!strcmp(argv[2], "-print"))) {
86 olsrd_write_cnf(cnf, "./out.conf");
88 printf("Use -print to view parsed values\n");
89 printf("Configfile parsed OK\n");
91 printf("Failed parsing \"%s\"\n", argv[1]);
99 /* Build as part of olsrd */
103 struct olsrd_config *
104 olsrd_parse_cnf(const char *filename)
106 struct olsr_if *in, *new_ifqueue;
109 /* Initialize the global varibles - oparse.y needs it there */
110 olsr_cnf = malloc(sizeof(*olsr_cnf));
111 if (olsr_cnf == NULL) {
112 fprintf(stderr, "Out of memory %s\n", __func__);
116 set_default_cnf(olsr_cnf);
118 printf("Parsing file: \"%s\"\n", filename);
120 yyin = fopen(filename, "r");
122 fprintf(stderr, "Cannot open configuration file '%s': %s.\n", filename, strerror(errno));
123 olsrd_free_cnf(olsr_cnf);
132 olsrd_free_cnf(olsr_cnf);
137 /* Reverse the queue (added by user request) */
138 in = olsr_cnf->interfaces;
142 struct olsr_if *in_tmp = in;
145 in_tmp->next = new_ifqueue;
146 new_ifqueue = in_tmp;
149 olsr_cnf->interfaces = new_ifqueue;
151 for (in = olsr_cnf->interfaces; in != NULL; in = in->next) {
152 /* set various stuff */
153 in->configured = false;
155 in->host_emul = false;
161 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
163 struct olsr_if *in = cnf->interfaces;
164 struct if_config_options *io;
167 if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) {
168 fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
173 if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) {
174 fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
179 if ( //cnf->tos < MIN_TOS ||
180 cnf->tos > MAX_TOS) {
181 fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
185 if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) {
186 fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
191 if (cnf->use_hysteresis == true) {
192 if (cnf->hysteresis_param.scaling < MIN_HYST_PARAM || cnf->hysteresis_param.scaling > MAX_HYST_PARAM) {
193 fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
197 if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) {
198 fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", cnf->hysteresis_param.thr_high,
199 cnf->hysteresis_param.thr_low);
203 if (cnf->hysteresis_param.thr_high < MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > MAX_HYST_PARAM) {
204 fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
208 if (cnf->hysteresis_param.thr_low < MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > MAX_HYST_PARAM) {
209 fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
214 /* Check Link quality dijkstra limit */
215 if (olsr_cnf->lq_dinter < cnf->pollrate && olsr_cnf->lq_dlimit != 255) {
216 fprintf(stderr, "Link quality dijkstra limit must be higher than pollrate\n");
222 if (cnf->pollrate < MIN_POLLRATE || cnf->pollrate > MAX_POLLRATE) {
223 fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
227 /* NIC Changes Pollrate */
229 if (cnf->nic_chgs_pollrate < MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > MAX_NICCHGPOLLRT) {
230 fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", cnf->nic_chgs_pollrate);
236 if ( //cnf->tc_redundancy < MIN_TC_REDUNDANCY ||
237 cnf->tc_redundancy > MAX_TC_REDUNDANCY) {
238 fprintf(stderr, "TC redundancy %d is not allowed\n", cnf->tc_redundancy);
243 if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) {
244 fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
248 /* Link Q and hysteresis cannot be activated at the same time */
249 if (cnf->use_hysteresis == true && cnf->lq_level) {
250 fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
254 /* Link quality level */
256 if (cnf->lq_level > MAX_LQ_LEVEL) {
257 fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
261 /* Link quality window size */
262 if (cnf->lq_level && (cnf->lq_aging < MIN_LQ_AGING || cnf->lq_aging > MAX_LQ_AGING)) {
263 fprintf(stderr, "LQ aging factor %f is not allowed\n", cnf->lq_aging);
267 /* NAT threshold value */
268 if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0)) {
269 fprintf(stderr, "NAT threshold %f is not allowed\n", cnf->lq_nat_thresh);
274 fprintf(stderr, "No interfaces configured!\n");
278 if (cnf->min_tc_vtime < 0.0) {
279 fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
282 if (cnf->min_tc_vtime > 0.0) {
283 fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
290 if (in->name == NULL || !strlen(in->name)) {
291 fprintf(stderr, "Interface has no name!\n");
296 fprintf(stderr, "Interface %s has no configuration!\n", in->name);
302 if (io->hello_params.validity_time < 0.0) {
303 if (cnf->lq_level == 0)
304 io->hello_params.validity_time = NEIGHB_HOLD_TIME;
307 io->hello_params.validity_time = (int)(REFRESH_INTERVAL / cnf->lq_aging);
310 if (io->hello_params.emission_interval < cnf->pollrate || io->hello_params.emission_interval > io->hello_params.validity_time) {
311 fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f)\n", io->hello_params.emission_interval,
312 io->hello_params.validity_time);
317 if (io->tc_params.emission_interval < cnf->pollrate || io->tc_params.emission_interval > io->tc_params.validity_time) {
318 fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f)\n", io->tc_params.emission_interval, io->tc_params.validity_time);
322 if (cnf->min_tc_vtime > 0.0 && (io->tc_params.validity_time / io->tc_params.emission_interval) < 128) {
323 fprintf(stderr, "Please use a tc vtime at least 128 times the emission interval while using the min_tc_vtime hack.\n");
327 if (io->mid_params.emission_interval < cnf->pollrate || io->mid_params.emission_interval > io->mid_params.validity_time) {
328 fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f)\n", io->mid_params.emission_interval,
329 io->mid_params.validity_time);
334 if (io->hna_params.emission_interval < cnf->pollrate || io->hna_params.emission_interval > io->hna_params.validity_time) {
335 fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f)\n", io->hna_params.emission_interval,
336 io->hna_params.validity_time);
347 olsrd_free_cnf(struct olsrd_config *cnf)
349 struct ip_prefix_list *hd, *h = cnf->hna_entries;
350 struct olsr_if *ind, *in = cnf->interfaces;
351 struct plugin_entry *ped, *pe = cnf->plugins;
352 struct olsr_lq_mult *mult, *next_mult;
361 for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult) {
362 next_mult = mult->next;
384 struct olsrd_config *
385 olsrd_get_default_cnf(void)
387 struct olsrd_config *c = malloc(sizeof(struct olsrd_config));
389 fprintf(stderr, "Out of memory %s\n", __func__);
398 set_default_cnf(struct olsrd_config *cnf)
400 memset(cnf, 0, sizeof(*cnf));
402 cnf->debug_level = DEF_DEBUGLVL;
403 cnf->no_fork = false;
404 cnf->host_emul = false;
405 cnf->ip_version = AF_INET;
406 cnf->ipsize = sizeof(struct in_addr);
408 cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
410 cnf->olsrport = DEF_OLSRPORT;
411 cnf->rttable = DEF_RTTABLE;
412 cnf->rtproto = DEF_RTPROTO;
413 cnf->rttable_default = 0;
414 cnf->willingness_auto = DEF_WILL_AUTO;
415 cnf->ipc_connections = DEF_IPC_CONNECTIONS;
416 cnf->fib_metric = DEF_FIB_METRIC;
418 cnf->use_hysteresis = DEF_USE_HYST;
419 cnf->hysteresis_param.scaling = HYST_SCALING;
420 cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
421 cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
423 cnf->pollrate = DEF_POLLRATE;
424 cnf->nic_chgs_pollrate = DEF_NICCHGPOLLRT;
426 cnf->tc_redundancy = TC_REDUNDANCY;
427 cnf->mpr_coverage = MPR_COVERAGE;
428 cnf->lq_level = DEF_LQ_LEVEL;
429 cnf->lq_fish = DEF_LQ_FISH;
430 cnf->lq_dlimit = DEF_LQ_DIJK_LIMIT;
431 cnf->lq_dinter = DEF_LQ_DIJK_INTER;
432 cnf->lq_aging = DEF_LQ_AGING;
433 cnf->lq_algorithm = NULL;
434 cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
435 cnf->clear_screen = DEF_CLEAR_SCREEN;
437 cnf->del_gws = false;
438 cnf->will_int = 10 * HELLO_INTERVAL;
439 cnf->max_jitter = 0.0;
440 cnf->exit_value = EXIT_SUCCESS;
441 cnf->max_tc_vtime = 0.0;
443 #if LINUX_POLICY_ROUTING
447 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
452 struct if_config_options *
453 get_default_if_config(void)
456 struct if_config_options *io = malloc(sizeof(*io));
459 fprintf(stderr, "Out of memory %s\n", __func__);
463 memset(io, 0, sizeof(*io));
465 io->ipv6_addrtype = 1; /* XXX - FixMe */
467 inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6);
468 io->ipv6_multi_site.v6 = in6;
470 inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6);
471 io->ipv6_multi_glbl.v6 = in6;
475 io->weight.fixed = false;
476 io->weight.value = 0;
478 io->ipv6_addrtype = 0; /* global */
480 io->hello_params.emission_interval = HELLO_INTERVAL;
481 io->hello_params.validity_time = NEIGHB_HOLD_TIME;
482 io->tc_params.emission_interval = TC_INTERVAL;
483 io->tc_params.validity_time = TOP_HOLD_TIME;
484 io->mid_params.emission_interval = MID_INTERVAL;
485 io->mid_params.validity_time = MID_HOLD_TIME;
486 io->hna_params.emission_interval = HNA_INTERVAL;
487 io->hna_params.validity_time = HNA_HOLD_TIME;
488 io->autodetect_chg = true;
495 olsrd_print_cnf(struct olsrd_config *cnf)
497 struct ip_prefix_list *h = cnf->hna_entries;
498 struct olsr_if *in = cnf->interfaces;
499 struct plugin_entry *pe = cnf->plugins;
500 struct ip_prefix_list *ie = cnf->ipc_nets;
501 struct olsr_lq_mult *mult;
502 char ipv6_buf[100]; /* buffer for IPv6 inet_htop */
504 printf(" *** olsrd configuration ***\n");
506 printf("Debug Level : %d\n", cnf->debug_level);
507 if (cnf->ip_version == AF_INET6)
508 printf("IpVersion : 6\n");
510 printf("IpVersion : 4\n");
511 if (cnf->allow_no_interfaces)
512 printf("No interfaces : ALLOWED\n");
514 printf("No interfaces : NOT ALLOWED\n");
515 printf("TOS : 0x%02x\n", cnf->tos);
516 printf("OlsrPort : 0x%03x\n", cnf->olsrport);
517 printf("RtTable : 0x%02x\n", cnf->rttable);
518 printf("RtTableDefault : 0x%02x\n", cnf->rttable_default);
519 if (cnf->willingness_auto)
520 printf("Willingness : AUTO\n");
522 printf("Willingness : %d\n", cnf->willingness);
524 printf("IPC connections : %d\n", cnf->ipc_connections);
526 struct ipaddr_str strbuf;
527 if (ie->net.prefix_len == olsr_cnf->maxplen) {
528 printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
530 printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
535 printf("Pollrate : %0.2f\n", cnf->pollrate);
537 printf("NIC ChangPollrate: %0.2f\n", cnf->nic_chgs_pollrate);
539 printf("TC redundancy : %d\n", cnf->tc_redundancy);
541 printf("MPR coverage : %d\n", cnf->mpr_coverage);
543 printf("LQ level : %d\n", cnf->lq_level);
545 printf("LQ fish eye : %d\n", cnf->lq_fish);
547 printf("LQ Dijkstra limit: %d, %0.2f\n", cnf->lq_dlimit, cnf->lq_dinter);
549 printf("LQ aging factor : %f\n", cnf->lq_aging);
551 printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default");
553 printf("NAT threshold : %f\n", cnf->lq_nat_thresh);
555 printf("Clear screen : %s\n", cnf->clear_screen ? "yes" : "no");
559 printf("Interfaces:\n");
561 printf(" dev: \"%s\"\n", in->name);
563 if (in->cnf->ipv4_broadcast.v4.s_addr) {
564 printf("\tIPv4 broadcast : %s\n", inet_ntoa(in->cnf->ipv4_broadcast.v4));
566 printf("\tIPv4 broadcast : AUTO\n");
569 if (in->cnf->mode==IF_MODE_ETHER){
570 printf("\tMode : ether\n");
572 printf("\tMode : mesh\n");
575 printf("\tIPv6 addrtype : %s\n", in->cnf->ipv6_addrtype ? "site-local" : "global");
577 //union olsr_ip_addr ipv6_multi_site;
578 //union olsr_ip_addr ipv6_multi_glbl;
579 printf("\tIPv6 multicast site/glbl : %s", inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
580 printf("/%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
582 printf("\tHELLO emission/validity : %0.2f/%0.2f\n", in->cnf->hello_params.emission_interval,
583 in->cnf->hello_params.validity_time);
584 printf("\tTC emission/validity : %0.2f/%0.2f\n", in->cnf->tc_params.emission_interval, in->cnf->tc_params.validity_time);
585 printf("\tMID emission/validity : %0.2f/%0.2f\n", in->cnf->mid_params.emission_interval,
586 in->cnf->mid_params.validity_time);
587 printf("\tHNA emission/validity : %0.2f/%0.2f\n", in->cnf->hna_params.emission_interval,
588 in->cnf->hna_params.validity_time);
590 for (mult = in->cnf->lq_mult; mult != NULL; mult = mult->next) {
591 printf("\tLinkQualityMult : %s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
592 (float)(mult->value) / 65536.0);
595 printf("\tAutodetetc changes : %s\n", in->cnf->autodetect_chg ? "yes" : "no");
603 printf("Plugins:\n");
606 printf("\tName: \"%s\"\n", pe->name);
612 if (cnf->use_hysteresis) {
613 printf("Using hysteresis:\n");
614 printf("\tScaling : %0.2f\n", cnf->hysteresis_param.scaling);
615 printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
617 printf("Not using hysteresis\n");
620 /* HNA IPv4 and IPv6 */
622 printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6);
624 struct ipaddr_str buf;
625 printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix));
626 if (cnf->ip_version == AF_INET) {
627 union olsr_ip_addr ip;
628 olsr_prefix_to_netmask(&ip, h->net.prefix_len);
629 printf("%s\n", olsr_ip_to_string(&buf, &ip));
631 printf("%d\n", h->net.prefix_len);
644 CRITICAL_SECTION lock;
648 win32_stdio_hack(unsigned int handle)
651 struct ioinfo **info;
653 lib = LoadLibrary("msvcrt.dll");
655 info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
657 // (*info)[1].handle = handle;
658 // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
660 (*info)[2].handle = handle;
661 (*info)[2].attr = 0x89;
663 // stdout->_file = 1;
666 // setbuf(stdout, NULL);
667 setbuf(stderr, NULL);
671 win32_olsrd_malloc(size_t size)
677 win32_olsrd_free(void *ptr)
684 ip_prefix_list_add(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
686 struct ip_prefix_list *new_entry = malloc(sizeof(*new_entry));
688 new_entry->net.prefix = *net;
689 new_entry->net.prefix_len = prefix_len;
692 new_entry->next = *list;
697 ip_prefix_list_remove(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
699 struct ip_prefix_list *h = *list, *prev = NULL;
702 if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
707 prev->next = h->next;
718 struct ip_prefix_list *
719 ip_prefix_list_find(struct ip_prefix_list *list, const union olsr_ip_addr *net, uint8_t prefix_len)
721 struct ip_prefix_list *h;
722 for (h = list; h != NULL; h = h->next) {
723 if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {
733 * indent-tabs-mode: nil