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