2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
16 * * Neither the name of olsr.org, olsrd nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * Visit http://www.olsr.org for more information.
35 * If you find this software useful feel free to make a donation
36 * to the project. For more information see the website or contact
37 * 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>
60 extern int yyparse(void);
62 static char copyright_string[] __attribute__((unused)) = "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tønnesen(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;
80 fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
84 if((cnf = olsrd_parse_cnf(argv[1])) != NULL)
86 if((argc > 2) && (!strcmp(argv[2], "-print")))
89 olsrd_write_cnf(cnf, "./out.conf");
92 printf("Use -print to view parsed values\n");
93 printf("Configfile parsed OK\n");
97 printf("Failed parsing \"%s\"\n", argv[1]);
105 /* Build as part of olsrd */
110 struct olsrd_config *
111 olsrd_parse_cnf(const char *filename)
113 struct olsr_if *in, *new_ifqueue;
116 /* Initialize the global varibles - oparse.y needs it there */
117 olsr_cnf = malloc(sizeof(*olsr_cnf));
118 if (olsr_cnf == NULL) {
119 fprintf(stderr, "Out of memory %s\n", __func__);
123 set_default_cnf(olsr_cnf);
125 printf("Parsing file: \"%s\"\n", filename);
127 yyin = fopen(filename, "r");
129 fprintf(stderr, "Cannot open configuration file '%s': %s.\n",
130 filename, strerror(errno));
131 olsrd_free_cnf(olsr_cnf);
140 olsrd_free_cnf(olsr_cnf);
145 /* Reverse the queue (added by user request) */
146 in = olsr_cnf->interfaces;
150 struct olsr_if *in_tmp = in;
153 in_tmp->next = new_ifqueue;
154 new_ifqueue = in_tmp;
157 olsr_cnf->interfaces = new_ifqueue;
159 for (in = olsr_cnf->interfaces; in != NULL; in = in->next) {
160 /* set various stuff */
161 in->configured = OLSR_FALSE;
163 in->host_emul = OLSR_FALSE;
170 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
172 struct olsr_if *in = cnf->interfaces;
173 struct if_config_options *io;
176 if(cnf->debug_level < MIN_DEBUGLVL ||
177 cnf->debug_level > MAX_DEBUGLVL)
179 fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
184 if(cnf->ip_version != AF_INET &&
185 cnf->ip_version != AF_INET6)
187 fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
192 if(//cnf->tos < MIN_TOS ||
195 fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
199 if(cnf->willingness_auto == OLSR_FALSE &&
200 (cnf->willingness > MAX_WILLINGNESS))
202 fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
207 if(cnf->use_hysteresis == OLSR_TRUE)
209 if(cnf->hysteresis_param.scaling < MIN_HYST_PARAM ||
210 cnf->hysteresis_param.scaling > MAX_HYST_PARAM)
212 fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
216 if(cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low)
218 fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
222 if(cnf->hysteresis_param.thr_high < MIN_HYST_PARAM ||
223 cnf->hysteresis_param.thr_high > MAX_HYST_PARAM)
225 fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
229 if(cnf->hysteresis_param.thr_low < MIN_HYST_PARAM ||
230 cnf->hysteresis_param.thr_low > MAX_HYST_PARAM)
232 fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
237 /* Check Link quality dijkstra limit */
238 if (olsr_cnf->lq_dinter < cnf->pollrate && olsr_cnf->lq_dlimit != 255) {
239 fprintf(stderr, "Link quality dijkstra limit must be higher than pollrate\n");
245 if(cnf->pollrate < MIN_POLLRATE ||
246 cnf->pollrate > MAX_POLLRATE)
248 fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
252 /* NIC Changes Pollrate */
254 if(cnf->nic_chgs_pollrate < MIN_NICCHGPOLLRT ||
255 cnf->nic_chgs_pollrate > MAX_NICCHGPOLLRT)
257 fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", cnf->nic_chgs_pollrate);
263 if(//cnf->tc_redundancy < MIN_TC_REDUNDANCY ||
264 cnf->tc_redundancy > MAX_TC_REDUNDANCY)
266 fprintf(stderr, "TC redundancy %d is not allowed\n", cnf->tc_redundancy);
271 if(cnf->mpr_coverage < MIN_MPR_COVERAGE ||
272 cnf->mpr_coverage > MAX_MPR_COVERAGE)
274 fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
278 /* Link Q and hysteresis cannot be activated at the same time */
279 if(cnf->use_hysteresis == OLSR_TRUE && cnf->lq_level)
281 fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
285 /* Link quality level */
287 if(cnf->lq_level > MAX_LQ_LEVEL)
289 fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
293 /* Link quality window size */
294 if(cnf->lq_level && (cnf->lq_wsize < MIN_LQ_WSIZE || cnf->lq_wsize > MAX_LQ_WSIZE))
296 fprintf(stderr, "LQ window size %d is not allowed\n", cnf->lq_wsize);
300 /* NAT threshold value */
301 if(cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0))
303 fprintf(stderr, "NAT threshold %f is not allowed\n", cnf->lq_nat_thresh);
309 fprintf(stderr, "No interfaces configured!\n");
318 if(in->name == NULL || !strlen(in->name))
320 fprintf(stderr, "Interface has no name!\n");
326 fprintf(stderr, "Interface %s has no configuration!\n", in->name);
332 if (io->hello_params.validity_time < 0.0)
334 if (cnf->lq_level == 0)
335 io->hello_params.validity_time = NEIGHB_HOLD_TIME;
338 io->hello_params.validity_time = cnf->lq_wsize * io->hello_params.emission_interval;
341 if(io->hello_params.emission_interval < cnf->pollrate ||
342 io->hello_params.emission_interval > io->hello_params.validity_time)
344 fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f)\n", io->hello_params.emission_interval, io->hello_params.validity_time);
349 if(io->tc_params.emission_interval < cnf->pollrate ||
350 io->tc_params.emission_interval > io->tc_params.validity_time)
352 fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f)\n", io->tc_params.emission_interval, io->tc_params.validity_time);
357 if(io->mid_params.emission_interval < cnf->pollrate ||
358 io->mid_params.emission_interval > io->mid_params.validity_time)
360 fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f)\n", io->mid_params.emission_interval, io->mid_params.validity_time);
365 if(io->hna_params.emission_interval < cnf->pollrate ||
366 io->hna_params.emission_interval > io->hna_params.validity_time)
368 fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f)\n", io->hna_params.emission_interval, io->hna_params.validity_time);
380 olsrd_free_cnf(struct olsrd_config *cnf)
382 struct ip_prefix_list *hd, *h = cnf->hna_entries;
383 struct olsr_if *ind, *in = cnf->interfaces;
384 struct plugin_entry *ped, *pe = cnf->plugins;
385 struct olsr_lq_mult *mult, *next_mult;
396 for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult)
398 next_mult = mult->next;
423 struct olsrd_config *
424 olsrd_get_default_cnf(void)
426 struct olsrd_config *c = malloc(sizeof(struct olsrd_config));
428 fprintf(stderr, "Out of memory %s\n", __func__);
440 set_default_cnf(struct olsrd_config *cnf)
442 memset(cnf, 0, sizeof(*cnf));
444 cnf->debug_level = DEF_DEBUGLVL;
445 cnf->no_fork = OLSR_FALSE;
446 cnf->host_emul = OLSR_FALSE;
447 cnf->ip_version = AF_INET;
448 cnf->ipsize = sizeof(struct in_addr);
450 cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
453 cnf->rttable_default = 0;
454 cnf->willingness_auto = DEF_WILL_AUTO;
455 cnf->ipc_connections = DEF_IPC_CONNECTIONS;
456 cnf->fib_metric = DEF_FIB_METRIC;
458 cnf->use_hysteresis = DEF_USE_HYST;
459 cnf->hysteresis_param.scaling = HYST_SCALING;
460 cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
461 cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
463 cnf->pollrate = DEF_POLLRATE;
464 cnf->nic_chgs_pollrate = DEF_NICCHGPOLLRT;
466 cnf->tc_redundancy = TC_REDUNDANCY;
467 cnf->mpr_coverage = MPR_COVERAGE;
468 cnf->lq_level = DEF_LQ_LEVEL;
469 cnf->lq_fish = DEF_LQ_FISH;
470 cnf->lq_dlimit = DEF_LQ_DIJK_LIMIT;
471 cnf->lq_dinter = DEF_LQ_DIJK_INTER;
472 cnf->lq_wsize = DEF_LQ_WSIZE;
473 cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
474 cnf->clear_screen = DEF_CLEAR_SCREEN;
476 cnf->del_gws = OLSR_FALSE;
477 cnf->will_int = 10 * HELLO_INTERVAL;
478 cnf->max_jitter = 0.0;
479 cnf->exit_value = EXIT_SUCCESS;
480 cnf->max_tc_vtime = 0.0;
482 #if LINUX_POLICY_ROUTING
486 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
494 struct if_config_options *
495 get_default_if_config(void)
498 struct if_config_options *io = malloc(sizeof(*io));
501 fprintf(stderr, "Out of memory %s\n", __func__);
505 memset(io, 0, sizeof(*io));
507 io->ipv6_addrtype = 1; /* XXX - FixMe */
509 inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6);
510 io->ipv6_multi_site.v6 = in6;
512 inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6);
513 io->ipv6_multi_glbl.v6 = in6;
517 io->weight.fixed = OLSR_FALSE;
518 io->weight.value = 0;
520 io->ipv6_addrtype = 0; /* global */
522 io->hello_params.emission_interval = HELLO_INTERVAL;
523 io->hello_params.validity_time = NEIGHB_HOLD_TIME;
524 io->tc_params.emission_interval = TC_INTERVAL;
525 io->tc_params.validity_time = TOP_HOLD_TIME;
526 io->mid_params.emission_interval = MID_INTERVAL;
527 io->mid_params.validity_time = MID_HOLD_TIME;
528 io->hna_params.emission_interval = HNA_INTERVAL;
529 io->hna_params.validity_time = HNA_HOLD_TIME;
530 io->autodetect_chg = OLSR_TRUE;
539 olsrd_print_cnf(struct olsrd_config *cnf)
541 struct ip_prefix_list *h = cnf->hna_entries;
542 struct olsr_if *in = cnf->interfaces;
543 struct plugin_entry *pe = cnf->plugins;
544 struct ip_prefix_list *ie = cnf->ipc_nets;
545 struct olsr_lq_mult *mult;
546 char ipv6_buf[100]; /* buffer for IPv6 inet_htop */
548 printf(" *** olsrd configuration ***\n");
550 printf("Debug Level : %d\n", cnf->debug_level);
551 if(cnf->ip_version == AF_INET6)
552 printf("IpVersion : 6\n");
554 printf("IpVersion : 4\n");
555 if(cnf->allow_no_interfaces)
556 printf("No interfaces : ALLOWED\n");
558 printf("No interfaces : NOT ALLOWED\n");
559 printf("TOS : 0x%02x\n", cnf->tos);
560 printf("RtTable : 0x%02x\n", cnf->rttable);
561 printf("RtTableDefault : 0x%02x\n", cnf->rttable_default);
562 if(cnf->willingness_auto)
563 printf("Willingness : AUTO\n");
565 printf("Willingness : %d\n", cnf->willingness);
567 printf("IPC connections : %d\n", cnf->ipc_connections);
570 struct ipaddr_str strbuf;
571 if (ie->net.prefix_len == olsr_cnf->maxplen) {
572 printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
574 printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
580 printf("Pollrate : %0.2f\n", cnf->pollrate);
582 printf("NIC ChangPollrate: %0.2f\n", cnf->nic_chgs_pollrate);
584 printf("TC redundancy : %d\n", cnf->tc_redundancy);
586 printf("MPR coverage : %d\n", cnf->mpr_coverage);
588 printf("LQ level : %d\n", cnf->lq_level);
590 printf("LQ fish eye : %d\n", cnf->lq_fish);
592 printf("LQ Dijkstra limit: %d, %0.2f\n", cnf->lq_dlimit, cnf->lq_dinter);
594 printf("LQ window size : %d\n", cnf->lq_wsize);
596 printf("NAT threshold : %f\n", cnf->lq_nat_thresh);
598 printf("Clear screen : %s\n", cnf->clear_screen ? "yes" : "no");
603 printf("Interfaces:\n");
606 printf(" dev: \"%s\"\n", in->name);
608 if(in->cnf->ipv4_broadcast.v4.s_addr)
610 printf("\tIPv4 broadcast : %s\n", inet_ntoa(in->cnf->ipv4_broadcast.v4));
614 printf("\tIPv4 broadcast : AUTO\n");
617 printf("\tIPv6 addrtype : %s\n", in->cnf->ipv6_addrtype ? "site-local" : "global");
619 //union olsr_ip_addr ipv6_multi_site;
620 //union olsr_ip_addr ipv6_multi_glbl;
621 printf("\tIPv6 multicast site/glbl : %s", inet_ntop(AF_INET6, &in->cnf->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
622 printf("/%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
624 printf("\tHELLO emission/validity : %0.2f/%0.2f\n", in->cnf->hello_params.emission_interval, in->cnf->hello_params.validity_time);
625 printf("\tTC emission/validity : %0.2f/%0.2f\n", in->cnf->tc_params.emission_interval, in->cnf->tc_params.validity_time);
626 printf("\tMID emission/validity : %0.2f/%0.2f\n", in->cnf->mid_params.emission_interval, in->cnf->mid_params.validity_time);
627 printf("\tHNA emission/validity : %0.2f/%0.2f\n", in->cnf->hna_params.emission_interval, in->cnf->hna_params.validity_time);
629 for (mult = in->cnf->lq_mult; mult != NULL; mult = mult->next)
631 printf("\tLinkQualityMult : %s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof (ipv6_buf)), mult->val);
634 printf("\tAutodetetc changes : %s\n", in->cnf->autodetect_chg ? "yes" : "no");
646 printf("Plugins:\n");
650 printf("\tName: \"%s\"\n", pe->name);
656 if(cnf->use_hysteresis) {
657 printf("Using hysteresis:\n");
658 printf("\tScaling : %0.2f\n", cnf->hysteresis_param.scaling);
659 printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
661 printf("Not using hysteresis\n");
664 /* HNA IPv4 and IPv6 */
666 printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6);
668 struct ipaddr_str buf;
669 printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix));
670 if (cnf->ip_version == AF_INET) {
671 union olsr_ip_addr ip;
672 olsr_prefix_to_netmask(&ip, h->net.prefix_len);
673 printf("%s\n", olsr_ip_to_string(&buf, &ip));
675 printf("%d\n", h->net.prefix_len);
689 CRITICAL_SECTION lock;
692 void win32_stdio_hack(unsigned int handle)
695 struct ioinfo **info;
697 lib = LoadLibrary("msvcrt.dll");
699 info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
701 // (*info)[1].handle = handle;
702 // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
704 (*info)[2].handle = handle;
705 (*info)[2].attr = 0x89;
707 // stdout->_file = 1;
710 // setbuf(stdout, NULL);
711 setbuf(stderr, NULL);
715 win32_olsrd_malloc(size_t size)
721 win32_olsrd_free(void* ptr)
727 void ip_prefix_list_add(struct ip_prefix_list **list,
728 const union olsr_ip_addr *net,
729 olsr_u8_t prefix_len)
731 struct ip_prefix_list *new_entry = malloc(sizeof(*new_entry));
733 new_entry->net.prefix = *net;
734 new_entry->net.prefix_len = prefix_len;
737 new_entry->next = *list;
741 int ip_prefix_list_remove(struct ip_prefix_list **list,
742 const union olsr_ip_addr *net,
743 olsr_u8_t prefix_len)
745 struct ip_prefix_list *h = *list, *prev = NULL;
748 if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
753 prev->next = h->next;
764 struct ip_prefix_list *ip_prefix_list_find(struct ip_prefix_list *list,
765 const union olsr_ip_addr *net,
766 olsr_u8_t prefix_len)
768 struct ip_prefix_list *h;
769 for (h = list; h != NULL; h = h->next) {
770 if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {