Simplify NIIT configuration to boolean
[olsrd.git] / src / cfgparser / olsrd_conf.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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
16  *   distribution.
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.
20  *
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.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
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.
39  *
40  */
41
42 #include "olsrd_conf.h"
43 #include "ipcalc.h"
44 #include "olsr_cfg.h"
45 #include "defs.h"
46 #include "net_olsr.h"
47 #include "olsr.h"
48
49 #include <assert.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <stdlib.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <netinet/in.h>
57 #include <arpa/inet.h>
58
59 extern FILE *yyin;
60 extern int yyparse(void);
61
62 static char copyright_string[] __attribute__ ((unused)) =
63   "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
64
65 int current_line;
66
67 /* Global stuff externed in defs.h */
68 FILE *debug_handle;                    /* Where to send debug(defaults to stdout) */
69 struct olsrd_config *olsr_cnf;         /* The global configuration */
70
71 #ifdef MAKEBIN
72
73 /* Build as standalone binary */
74 int
75 main(int argc, char *argv[])
76 {
77   struct olsrd_config *cnf;
78
79   if (argc == 1) {
80     fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
81     exit(EXIT_FAILURE);
82   }
83
84   if ((cnf = olsrd_parse_cnf(argv[1])) != NULL) {
85     if ((argc > 2) && (!strcmp(argv[2], "-print"))) {
86       olsrd_print_cnf(cnf);
87       olsrd_write_cnf(cnf, "./out.conf");
88     } else
89       printf("Use -print to view parsed values\n");
90     printf("Configfile parsed OK\n");
91   } else {
92     printf("Failed parsing \"%s\"\n", argv[1]);
93   }
94
95   return 0;
96 }
97
98 #else
99
100 /* Build as part of olsrd */
101
102 #endif
103
104 int
105 olsrd_parse_cnf(const char *filename)
106 {
107   struct olsr_if *in, *new_ifqueue;
108   int rc;
109
110   fprintf(stderr, "Parsing file: \"%s\"\n", filename);
111
112   yyin = fopen(filename, "r");
113   if (yyin == NULL) {
114     fprintf(stderr, "Cannot open configuration file '%s': %s.\n", filename, strerror(errno));
115     return -1;
116   }
117
118   current_line = 1;
119   rc = yyparse();
120   fclose(yyin);
121   if (rc != 0) {
122     return -1;
123   }
124
125   /* Reverse the queue (added by user request) */
126   in = olsr_cnf->interfaces;
127   new_ifqueue = NULL;
128
129   while (in) {
130     struct olsr_if *in_tmp = in;
131     in = in->next;
132
133     in_tmp->next = new_ifqueue;
134     new_ifqueue = in_tmp;
135   }
136
137   olsr_cnf->interfaces = new_ifqueue;
138
139   for (in = olsr_cnf->interfaces; in != NULL; in = in->next) {
140     /* set various stuff */
141     in->configured = false;
142     in->interf = NULL;
143     in->host_emul = false;
144   }
145   return 0;
146 }
147
148 /* prints an interface (and checks it againt the default config) and the inverted config */
149 static void
150 olsrd_print_interface_cnf(struct if_config_options *cnf, struct if_config_options *cnfi, bool defcnf)
151 {
152   struct olsr_lq_mult *mult;
153   int lq_mult_cnt = 0;
154   char ipv6_buf[INET6_ADDRSTRLEN];                  /* buffer for IPv6 inet_htop */
155
156   if (cnf->ipv4_multicast.v4.s_addr) {
157     printf("\tIPv4 broadcast/multicast : %s%s\n", inet_ntoa(cnf->ipv4_multicast.v4),DEFAULT_STR(ipv4_multicast.v4.s_addr));
158   } else {
159     printf("\tIPv4 broadcast/multicast : AUTO%s\n",DEFAULT_STR(ipv4_multicast.v4.s_addr));
160   }
161
162   if (cnf->mode==IF_MODE_ETHER){
163     printf("\tMode           : ether%s\n",DEFAULT_STR(mode));
164   } else {
165     printf("\tMode           : mesh%s\n",DEFAULT_STR(mode));
166   }
167
168   printf("\tIPv6 multicast           : %s%s\n", inet_ntop(AF_INET6, &cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)),DEFAULT_STR(ipv6_multicast.v6));
169
170   printf("\tHELLO emission/validity  : %0.2f%s/%0.2f%s\n", cnf->hello_params.emission_interval, DEFAULT_STR(hello_params.emission_interval),
171          cnf->hello_params.validity_time,DEFAULT_STR(hello_params.validity_time));
172   printf("\tTC emission/validity     : %0.2f%s/%0.2f%s\n", cnf->tc_params.emission_interval, DEFAULT_STR(tc_params.emission_interval),
173          cnf->tc_params.validity_time,DEFAULT_STR(tc_params.validity_time));
174   printf("\tMID emission/validity    : %0.2f%s/%0.2f%s\n", cnf->mid_params.emission_interval, DEFAULT_STR(mid_params.emission_interval),
175          cnf->mid_params.validity_time,DEFAULT_STR(mid_params.validity_time));
176   printf("\tHNA emission/validity    : %0.2f%s/%0.2f%s\n", cnf->hna_params.emission_interval, DEFAULT_STR(hna_params.emission_interval),
177          cnf->hna_params.validity_time,DEFAULT_STR(hna_params.validity_time));
178
179   for (mult = cnf->lq_mult; mult != NULL; mult = mult->next) {
180     lq_mult_cnt++;
181     printf("\tLinkQualityMult          : %s %0.2f %s\n", inet_ntop(olsr_cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
182       (float)(mult->value) / 65536.0, ((lq_mult_cnt > cnf->orig_lq_mult_cnt)?" (d)":""));
183   }
184
185   printf("\tAutodetect changes       : %s%s\n", cnf->autodetect_chg ? "yes" : "no",DEFAULT_STR(autodetect_chg));
186 }
187
188 int
189 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
190 {
191   struct olsr_if *in = cnf->interfaces;
192   struct if_config_options *io;
193
194   /* Debug level */
195   if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) {
196     fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
197     return -1;
198   }
199
200   /* IP version */
201   if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) {
202     fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
203     return -1;
204   }
205
206   /* TOS */
207   if (                          //cnf->tos < MIN_TOS ||
208        cnf->tos > MAX_TOS) {
209     fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
210     return -1;
211   }
212
213   if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) {
214     fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
215     return -1;
216   }
217
218   /* Hysteresis */
219   if (cnf->use_hysteresis == true) {
220     if (cnf->hysteresis_param.scaling < MIN_HYST_PARAM || cnf->hysteresis_param.scaling > MAX_HYST_PARAM) {
221       fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
222       return -1;
223     }
224
225     if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) {
226       fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", cnf->hysteresis_param.thr_high,
227               cnf->hysteresis_param.thr_low);
228       return -1;
229     }
230
231     if (cnf->hysteresis_param.thr_high < MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > MAX_HYST_PARAM) {
232       fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
233       return -1;
234     }
235
236     if (cnf->hysteresis_param.thr_low < MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > MAX_HYST_PARAM) {
237       fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
238       return -1;
239     }
240   }
241
242   /* Check Link quality dijkstra limit */
243   if (olsr_cnf->lq_dinter < cnf->pollrate && olsr_cnf->lq_dlimit != 255) {
244     fprintf(stderr, "Link quality dijkstra limit must be higher than pollrate\n");
245     return -1;
246   }
247
248   /* Pollrate */
249
250   if (cnf->pollrate < MIN_POLLRATE || cnf->pollrate > MAX_POLLRATE) {
251     fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
252     return -1;
253   }
254
255   /* NIC Changes Pollrate */
256
257   if (cnf->nic_chgs_pollrate < MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > MAX_NICCHGPOLLRT) {
258     fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", cnf->nic_chgs_pollrate);
259     return -1;
260   }
261
262   /* TC redundancy */
263   if (cnf->tc_redundancy != 2) {
264     fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. "
265         "It was discovered late in the stable tree development and cannot "
266         "be solved without a difficult change in the dijkstra code. "
267         "Feel free to contact the olsr-user mailinglist "
268         "(http://www.olsr.org/?q=mailing-lists) to learn more "
269         "about the problem. The next version of OLSR will have working "
270         "tc-redundancy again.\n");
271     return -1;
272   }
273
274   /* MPR coverage */
275   if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) {
276     fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
277     return -1;
278   }
279
280   /* Link Q and hysteresis cannot be activated at the same time */
281   if (cnf->use_hysteresis == true && cnf->lq_level) {
282     fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
283     return -1;
284   }
285
286   /* Link quality level */
287
288   if (cnf->lq_level > MAX_LQ_LEVEL) {
289     fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
290     return -1;
291   }
292
293   /* Link quality window size */
294   if (cnf->lq_level && (cnf->lq_aging < MIN_LQ_AGING || cnf->lq_aging > MAX_LQ_AGING)) {
295     fprintf(stderr, "LQ aging factor %f is not allowed\n", cnf->lq_aging);
296     return -1;
297   }
298
299   /* NAT threshold value */
300   if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0)) {
301     fprintf(stderr, "NAT threshold %f is not allowed\n", cnf->lq_nat_thresh);
302     return -1;
303   }
304
305   if (in == NULL) {
306     fprintf(stderr, "No interfaces configured!\n");
307     return -1;
308   }
309
310   if (cnf->min_tc_vtime < 0.0) {
311         fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
312         return -1;
313   }
314   if (cnf->min_tc_vtime > 0.0) {
315           fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
316   }
317
318   if (cnf->interface_defaults == NULL) {
319     /* get a default configuration if the user did not specify one */
320     cnf->interface_defaults = get_default_if_config();
321   }
322
323   /* Interfaces */
324   while (in) {
325     struct olsr_lq_mult *mult, *mult_orig;
326
327     io = in->cnf;
328
329     olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
330
331     /*apply defaults (if this is not the default interface stub)*/
332     if (in->cnf != cnf->interface_defaults)
333     {
334       size_t pos;
335       struct olsr_lq_mult *mult_temp, *mult_orig_walk;
336       uint8_t *cnfptr = (uint8_t*)in->cnf;
337       uint8_t *cnfiptr = (uint8_t*)in->cnfi;
338       uint8_t *defptr = (uint8_t*)cnf->interface_defaults;
339
340       /*save interface specific lqmults, as they are merged togehter later*/
341       mult_orig = io->lq_mult;
342
343       assert(in->cnf);
344       assert(in->cnfi);
345       for (pos = 0; pos < sizeof(*in->cnf); pos++) {
346         if (cnfptr[pos] != cnfiptr[pos]) {
347           cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00;
348         }
349         else cnfiptr[pos]=0xFF;
350       }
351
352       io->lq_mult=NULL;
353       /*copy default lqmults into this interface*/
354       for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
355         /*search same lqmult in orig_list*/
356         for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
357           if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
358             break;
359           }
360         }
361         if (mult_orig_walk == NULL) {
362           mult_temp=malloc(sizeof(struct olsr_lq_mult));
363           memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
364           mult_temp->next=io->lq_mult;
365           io->lq_mult=mult_temp;
366         }
367       }
368     }
369     else
370     { /* check if there are no lqmults
371        *  as copying the pointer to the interfaces, 
372        *  would lead 1. to unexpected results if this interface defines its own lqmults 
373        *  2. to problems when freeing lqmult structures them) 
374       if (io->lq_mult!=NULL) {
375         fprintf(stderr, "LinkQualityMult directives are not supported within InterfaceDefaults section!\n", in->name);
376         return -1;
377       }*/
378       mult_orig = NULL;
379     }
380
381     if (in->name == NULL || !strlen(in->name)) {
382       fprintf(stderr, "Interface has no name!\n");
383       return -1;
384     }
385
386     if (io == NULL) {
387       fprintf(stderr, "Interface %s has no configuration!\n", in->name);
388       return -1;
389     }
390
391     /* HELLO interval */
392
393     if (io->hello_params.validity_time < 0.0) {
394       if (cnf->lq_level == 0)
395         io->hello_params.validity_time = NEIGHB_HOLD_TIME;
396
397       else
398         io->hello_params.validity_time = (int)(REFRESH_INTERVAL / cnf->lq_aging);
399     }
400
401     if (io->hello_params.emission_interval < cnf->pollrate || io->hello_params.emission_interval > io->hello_params.validity_time) {
402       fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->hello_params.emission_interval,
403               io->hello_params.validity_time, in->name);
404       return -1;
405     }
406
407     /* TC interval */
408     if (io->tc_params.emission_interval < cnf->pollrate || io->tc_params.emission_interval > io->tc_params.validity_time) {
409       fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->tc_params.emission_interval,
410           io->tc_params.validity_time, in->name);
411       return -1;
412     }
413
414     if (cnf->min_tc_vtime > 0.0 && (io->tc_params.validity_time / io->tc_params.emission_interval) < 128) {
415       fprintf(stderr, "Please use a tc vtime at least 128 times the emission interval while using the min_tc_vtime hack.\n");
416       return -1;
417     }
418     /* MID interval */
419     if (io->mid_params.emission_interval < cnf->pollrate || io->mid_params.emission_interval > io->mid_params.validity_time) {
420       fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->mid_params.emission_interval,
421               io->mid_params.validity_time, in->name);
422       return -1;
423     }
424
425     /* HNA interval */
426     if (io->hna_params.emission_interval < cnf->pollrate || io->hna_params.emission_interval > io->hna_params.validity_time) {
427       fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->hna_params.emission_interval,
428               io->hna_params.validity_time, in->name);
429       return -1;
430     }
431
432     /*merge lqmults*/
433     if (mult_orig!=NULL) {
434       io->orig_lq_mult_cnt=1;
435       /*search last of interface specific lqmults*/
436       mult = mult_orig;
437       while (mult->next!=NULL) {
438         mult=mult->next;
439       }
440       /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
441       mult->next=io->lq_mult;
442       io->lq_mult=mult_orig;
443     }
444
445     for (mult = io->lq_mult; mult; mult=mult->next) {
446       if (mult->value > LINK_LOSS_MULTIPLIER) {
447         struct ipaddr_str buf;
448
449         fprintf(stderr, "Bad Linkquality multiplier ('%s' on IP %s: %0.2f)\n",
450             in->name, olsr_ip_to_string(&buf, &mult->addr), (float)mult->value / (float)LINK_LOSS_MULTIPLIER);
451         return -1;
452       }
453     }
454     in = in->next;
455   }
456
457   return 0;
458 }
459
460 void
461 olsrd_free_cnf(struct olsrd_config *cnf)
462 {
463   struct ip_prefix_list *hd, *h = cnf->hna_entries;
464   struct olsr_if *ind, *in = cnf->interfaces;
465   struct plugin_entry *ped, *pe = cnf->plugins;
466   struct olsr_lq_mult *mult, *next_mult;
467
468   while (h) {
469     hd = h;
470     h = h->next;
471     free(hd);
472   }
473
474   while (in) {
475     for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult) {
476       next_mult = mult->next;
477       free(mult);
478     }
479
480     free(in->cnf);
481     free(in->cnfi);
482
483     ind = in;
484     in = in->next;
485
486     free(ind);
487   }
488
489   while (pe) {
490     ped = pe;
491     pe = pe->next;
492     free(ped->name);
493     free(ped);
494   }
495
496   return;
497 }
498
499 struct olsrd_config *
500 olsrd_get_default_cnf(void)
501 {
502   struct olsrd_config *c = malloc(sizeof(struct olsrd_config));
503   if (c == NULL) {
504     fprintf(stderr, "Out of memory %s\n", __func__);
505     return NULL;
506   }
507
508   set_default_cnf(c);
509   return c;
510 }
511
512 void
513 set_default_cnf(struct olsrd_config *cnf)
514 {
515   memset(cnf, 0, sizeof(*cnf));
516
517   cnf->debug_level = DEF_DEBUGLVL;
518   cnf->no_fork = false;
519   cnf->host_emul = false;
520   cnf->ip_version = AF_INET;
521   cnf->ipsize = sizeof(struct in_addr);
522   cnf->maxplen = 32;
523   cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
524   cnf->tos = DEF_TOS;
525   cnf->olsrport = DEF_OLSRPORT;
526   cnf->rttable = DEF_RTTABLE;
527   cnf->rtproto = DEF_RTPROTO;
528   cnf->rttable_default = 0;
529   cnf->willingness_auto = DEF_WILL_AUTO;
530   cnf->willingness = DEF_WILLINGNESS;
531   cnf->ipc_connections = DEF_IPC_CONNECTIONS;
532   cnf->fib_metric = DEF_FIB_METRIC;
533
534   cnf->use_hysteresis = DEF_USE_HYST;
535   cnf->hysteresis_param.scaling = HYST_SCALING;
536   cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
537   cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
538
539   cnf->pollrate = DEF_POLLRATE;
540   cnf->nic_chgs_pollrate = DEF_NICCHGPOLLRT;
541
542   cnf->tc_redundancy = TC_REDUNDANCY;
543   cnf->mpr_coverage = MPR_COVERAGE;
544   cnf->lq_level = DEF_LQ_LEVEL;
545   cnf->lq_fish = DEF_LQ_FISH;
546   cnf->lq_dlimit = DEF_LQ_DIJK_LIMIT;
547   cnf->lq_dinter = DEF_LQ_DIJK_INTER;
548   cnf->lq_aging = DEF_LQ_AGING;
549   cnf->lq_algorithm = NULL;
550   cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
551   cnf->clear_screen = DEF_CLEAR_SCREEN;
552
553   cnf->del_gws = false;
554   cnf->will_int = 10 * HELLO_INTERVAL;
555   cnf->max_jitter = 0.0;
556   cnf->exit_value = EXIT_SUCCESS;
557   cnf->max_tc_vtime = 0.0;
558   cnf->ioctl_s = 0;
559   cnf->use_niit = DEF_USE_NIIT;
560   cnf->niit_if_index = 0;
561
562 #if LINUX_POLICY_ROUTING
563   cnf->rtnl_s = 0;
564 #endif
565
566 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
567   cnf->rts = 0;
568 #endif
569 }
570
571 struct if_config_options *
572 get_default_if_config(void)
573 {
574   struct in6_addr in6;
575   struct if_config_options *io = malloc(sizeof(*io));
576
577   if (io == NULL) {
578     fprintf(stderr, "Out of memory %s\n", __func__);
579     return NULL;
580   }
581
582   memset(io, 0, sizeof(*io));
583
584   inet_pton(AF_INET6, OLSR_IPV6_MCAST, &in6);
585   io->ipv6_multicast.v6 = in6;
586
587   io->lq_mult = NULL;
588
589   io->weight.fixed = false;
590   io->weight.value = 0;
591
592   io->hello_params.emission_interval = HELLO_INTERVAL;
593   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
594   io->tc_params.emission_interval = TC_INTERVAL;
595   io->tc_params.validity_time = TOP_HOLD_TIME;
596   io->mid_params.emission_interval = MID_INTERVAL;
597   io->mid_params.validity_time = MID_HOLD_TIME;
598   io->hna_params.emission_interval = HNA_INTERVAL;
599   io->hna_params.validity_time = HNA_HOLD_TIME;
600   io->autodetect_chg = true;
601
602   return io;
603
604 }
605
606 void
607 olsrd_print_cnf(struct olsrd_config *cnf)
608 {
609   struct ip_prefix_list *h = cnf->hna_entries;
610   struct olsr_if *in = cnf->interfaces;
611   struct plugin_entry *pe = cnf->plugins;
612   struct ip_prefix_list *ie = cnf->ipc_nets;
613
614   printf(" *** olsrd configuration ***\n");
615
616   printf("Debug Level      : %d\n", cnf->debug_level);
617   if (cnf->ip_version == AF_INET6)
618     printf("IpVersion        : 6\n");
619   else
620     printf("IpVersion        : 4\n");
621   if (cnf->allow_no_interfaces)
622     printf("No interfaces    : ALLOWED\n");
623   else
624     printf("No interfaces    : NOT ALLOWED\n");
625   printf("TOS              : 0x%02x\n", cnf->tos);
626   printf("OlsrPort          : 0x%03x\n", cnf->olsrport);
627   printf("RtTable          : 0x%02x\n", cnf->rttable);
628   printf("RtTableDefault   : 0x%02x\n", cnf->rttable_default);
629   if (cnf->willingness_auto)
630     printf("Willingness      : AUTO\n");
631   else
632     printf("Willingness      : %d\n", cnf->willingness);
633
634   printf("IPC connections  : %d\n", cnf->ipc_connections);
635   while (ie) {
636     struct ipaddr_str strbuf;
637     if (ie->net.prefix_len == olsr_cnf->maxplen) {
638       printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
639     } else {
640       printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
641     }
642     ie = ie->next;
643   }
644
645   printf("Pollrate         : %0.2f\n", cnf->pollrate);
646
647   printf("NIC ChangPollrate: %0.2f\n", cnf->nic_chgs_pollrate);
648
649   printf("TC redundancy    : %d\n", cnf->tc_redundancy);
650
651   printf("MPR coverage     : %d\n", cnf->mpr_coverage);
652
653   printf("LQ level         : %d\n", cnf->lq_level);
654
655   printf("LQ fish eye      : %d\n", cnf->lq_fish);
656
657   printf("LQ Dijkstra limit: %d, %0.2f\n", cnf->lq_dlimit, cnf->lq_dinter);
658
659   printf("LQ aging factor  : %f\n", cnf->lq_aging);
660
661   printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default");
662
663   printf("NAT threshold    : %f\n", cnf->lq_nat_thresh);
664
665   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
666
667   printf("Use niit:        : %s\n", cnf->use_niit ? "yes" : "no");
668
669   /* Interfaces */
670   if (in) {
671     /*print interface default config*/
672     printf(" InterfaceDefaults: \n");
673     olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, true);
674
675     while (in)
676     { 
677       if (cnf->interface_defaults!=in->cnf)
678       {
679         printf(" dev: \"%s\"\n", in->name);
680
681         olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
682       }
683       in = in->next;
684     }
685   }
686
687   /* Plugins */
688   if (pe) {
689     printf("Plugins:\n");
690
691     while (pe) {
692       printf("\tName: \"%s\"\n", pe->name);
693       pe = pe->next;
694     }
695   }
696
697   /* Hysteresis */
698   if (cnf->use_hysteresis) {
699     printf("Using hysteresis:\n");
700     printf("\tScaling      : %0.2f\n", cnf->hysteresis_param.scaling);
701     printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low);
702   } else {
703     printf("Not using hysteresis\n");
704   }
705
706   /* HNA IPv4 and IPv6 */
707   if (h) {
708     printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6);
709     while (h) {
710       struct ipaddr_str buf;
711       printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix));
712       if (cnf->ip_version == AF_INET) {
713         union olsr_ip_addr ip;
714         olsr_prefix_to_netmask(&ip, h->net.prefix_len);
715         printf("%s\n", olsr_ip_to_string(&buf, &ip));
716       } else {
717         printf("%d\n", h->net.prefix_len);
718       }
719       h = h->next;
720     }
721   }
722 }
723
724 #if defined WIN32
725 struct ioinfo {
726   unsigned int handle;
727   unsigned char attr;
728   char buff;
729   int flag;
730   CRITICAL_SECTION lock;
731 };
732
733 void
734 win32_stdio_hack(unsigned int handle)
735 {
736   HMODULE lib;
737   struct ioinfo **info;
738
739   lib = LoadLibrary("msvcrt.dll");
740
741   info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
742
743   // (*info)[1].handle = handle;
744   // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
745
746   (*info)[2].handle = handle;
747   (*info)[2].attr = 0x89;
748
749   // stdout->_file = 1;
750   stderr->_file = 2;
751
752   // setbuf(stdout, NULL);
753   setbuf(stderr, NULL);
754 }
755
756 void *
757 win32_olsrd_malloc(size_t size)
758 {
759   return malloc(size);
760 }
761
762 void
763 win32_olsrd_free(void *ptr)
764 {
765   free(ptr);
766 }
767 #endif
768
769 void
770 ip_prefix_list_add(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
771 {
772   struct ip_prefix_list *new_entry = malloc(sizeof(*new_entry));
773
774   new_entry->net.prefix = *net;
775   new_entry->net.prefix_len = prefix_len;
776
777   /* Queue */
778   new_entry->next = *list;
779   *list = new_entry;
780 }
781
782 int
783 ip_prefix_list_remove(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
784 {
785   struct ip_prefix_list *h = *list, *prev = NULL;
786
787   while (h != NULL) {
788     if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
789       /* Dequeue */
790       if (prev == NULL) {
791         *list = h->next;
792       } else {
793         prev->next = h->next;
794       }
795       free(h);
796       return 1;
797     }
798     prev = h;
799     h = h->next;
800   }
801   return 0;
802 }
803
804 struct ip_prefix_list *
805 ip_prefix_list_find(struct ip_prefix_list *list, const union olsr_ip_addr *net, uint8_t prefix_len)
806 {
807   struct ip_prefix_list *h;
808   for (h = list; h != NULL; h = h->next) {
809     if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {
810       return h;
811     }
812   }
813   return NULL;
814 }
815
816 /*
817  * Local Variables:
818  * c-basic-offset: 2
819  * indent-tabs-mode: nil
820  * End:
821  */