Add OLSR support for NIIT (IP 4to6 tunnel device)
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * The olsr.org Optimized Link-State Routing daemon(olsrd)
5  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions 
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright 
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in 
16  *   the documentation and/or other materials provided with the 
17  *   distribution.
18  * * Neither the name of olsr.org, olsrd nor the names of its 
19  *   contributors may be used to endorse or promote products derived 
20  *   from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Visit http://www.olsr.org for more information.
36  *
37  * If you find this software useful feel free to make a donation
38  * to the project. For more information see the website or contact
39  * the copyright holders.
40  *
41  */
42
43
44 #include "olsrd_conf.h"
45 #include "../defs.h"
46 #include "../ipcalc.h"
47 #include "../net_olsr.h"
48 #include "../link_set.h"
49 #include "../olsr.h"
50
51 #include <stddef.h>
52 #include <stdio.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 #include <string.h>
59
60 #define PARSER_DEBUG 0
61
62 #if PARSER_DEBUG
63 #define PARSER_DEBUG_PRINTF(x, args...)   printf(x, ##args)
64 #else
65 #define PARSER_DEBUG_PRINTF(x, args...)   do { } while (0)
66 #endif
67
68 static char interface_defaults_name[] = "[InterfaceDefaults]";
69
70 #define SET_IFS_CONF(ifs, ifcnt, field, value) do { \
71         for (; ifcnt>0; ifs=ifs->next, ifcnt--) { \
72     ifs->cnfi->field = (value); \
73     ifs->cnf->field = (value); \
74         } \
75 } while (0)
76
77 #define YYSTYPE struct conf_token *
78
79 void yyerror(const char *);
80 int yylex(void);
81
82 static int ifs_in_curr_cfg = 0;
83
84 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
85
86 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
87 {
88   union olsr_ip_addr addr;
89   int i;
90   struct olsr_if *walker;
91
92 #if PARSER_DEBUG > 0
93   printf("\tLinkQualityMult %s %0.2f\n",
94          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
95          mult_arg->floating);
96 #endif
97
98   memset(&addr, 0, sizeof(addr));
99
100   if (ip_addr_arg != NULL &&
101      inet_pton(olsr_cnf->ip_version, ip_addr_arg->string, &addr) <= 0) {
102     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
103     return -1;
104   }
105
106   walker = olsr_cnf->interfaces;
107
108   for (i = 0; i < ifs_in_curr_cfg; i++) {
109     struct olsr_lq_mult *mult = malloc(sizeof(*mult));
110     if (mult == NULL) {
111       fprintf(stderr, "Out of memory (LQ multiplier).\n");
112       return -1;
113     }
114
115     mult->addr = addr;
116     mult->value = (uint32_t)(mult_arg->floating * LINK_LOSS_MULTIPLIER);
117
118     mult->next = walker->cnf->lq_mult;
119     walker->cnfi->lq_mult = walker->cnf->lq_mult = mult;
120     walker->cnf->orig_lq_mult_cnt++;
121     walker->cnfi->orig_lq_mult_cnt=walker->cnf->orig_lq_mult_cnt;
122
123     walker = walker->next;
124   }
125
126   if (ip_addr_arg != NULL) {
127     free(ip_addr_arg->string);
128     free(ip_addr_arg);
129   }
130
131   free(mult_arg);
132
133   return 0;
134 }
135
136 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
137 {
138   union olsr_ip_addr ipaddr;
139   PARSER_DEBUG_PRINTF("HNA IPv6 entry: %s/%d\n", ipaddr_arg->string, prefixlen_arg->integer);
140
141   if (olsr_cnf->ip_version != AF_INET6) {
142     fprintf(stderr, "IPv6 addresses can only be used if \"IpVersion\" == 6, skipping HNA6.\n");
143     olsr_startup_sleep(3);
144   }
145         else {
146           if(inet_pton(AF_INET6, ipaddr_arg->string, &ipaddr) <= 0) {
147       fprintf(stderr, "ihna6entry: Failed converting IP address %s\n", ipaddr_arg->string);
148       return 1;
149     }
150
151                 if (prefixlen_arg->integer > 128) {
152                         fprintf(stderr, "ihna6entry: Illegal IPv6 prefix length %d\n", prefixlen_arg->integer);
153                         return 1;
154                 }
155
156                 /* Queue */
157                 ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, prefixlen_arg->integer);
158         }
159   free(ipaddr_arg->string);
160   free(ipaddr_arg);
161   free(prefixlen_arg);
162
163   return 0;
164 }
165
166 %}
167
168 %token TOK_SLASH
169 %token TOK_OPEN
170 %token TOK_CLOSE
171
172 %token TOK_STRING
173 %token TOK_INTEGER
174 %token TOK_FLOAT
175 %token TOK_BOOLEAN
176
177 %token TOK_IPV6TYPE
178
179 %token TOK_DEBUGLEVEL
180 %token TOK_IPVERSION
181 %token TOK_HNA4
182 %token TOK_HNA6
183 %token TOK_PLUGIN
184 %token TOK_INTERFACE_DEFAULTS
185 %token TOK_INTERFACE
186 %token TOK_NOINT
187 %token TOK_TOS
188 %token TOK_RTTABLE
189 %token TOK_OLSRPORT
190 %token TOK_RTPROTO
191 %token TOK_RTTABLE_DEFAULT
192 %token TOK_WILLINGNESS
193 %token TOK_IPCCON
194 %token TOK_FIBMETRIC
195 %token TOK_USEHYST
196 %token TOK_HYSTSCALE
197 %token TOK_HYSTUPPER
198 %token TOK_HYSTLOWER
199 %token TOK_POLLRATE
200 %token TOK_NICCHGSPOLLRT
201 %token TOK_TCREDUNDANCY
202 %token TOK_MPRCOVERAGE
203 %token TOK_LQ_LEVEL
204 %token TOK_LQ_FISH
205 %token TOK_LQ_DLIMIT
206 %token TOK_LQ_WSIZE
207 %token TOK_LQ_AGING
208 %token TOK_LQ_PLUGIN
209 %token TOK_LQ_NAT_THRESH
210 %token TOK_LQ_MULT
211 %token TOK_CLEAR_SCREEN
212 %token TOK_PLPARAM
213 %token TOK_MIN_TC_VTIME
214 %token TOK_LOCK_FILE
215 %token TOK_USE_NIIT
216
217 %token TOK_HOSTLABEL
218 %token TOK_NETLABEL
219 %token TOK_MAXIPC
220
221 %token TOK_IFMODE
222 %token TOK_IPV4BROADCAST
223 %token TOK_IPV4MULTICAST
224 %token TOK_IPV6MULTICAST
225 %token TOK_IPV4SRC
226 %token TOK_IPV6SRC
227 %token TOK_IFWEIGHT
228 %token TOK_HELLOINT
229 %token TOK_HELLOVAL
230 %token TOK_TCINT
231 %token TOK_TCVAL
232 %token TOK_MIDINT
233 %token TOK_MIDVAL
234 %token TOK_HNAINT
235 %token TOK_HNAVAL
236 %token TOK_AUTODETCHG
237
238 %token TOK_IPV4_ADDR
239 %token TOK_IPV6_ADDR
240 %token TOK_DEFAULT
241
242 %token TOK_COMMENT
243
244 %%
245
246 conf:
247           | conf block
248           | conf stmt
249 ;
250
251 stmt:       idebug
252           | iipversion
253           | fibmetric
254           | bnoint
255           | atos
256           | aolsrport
257           | arttable
258           | artproto
259           | arttable_default
260           | awillingness
261           | busehyst
262           | fhystscale
263           | fhystupper
264           | fhystlower
265           | fpollrate
266           | fnicchgspollrt
267           | atcredundancy
268           | amprcoverage
269           | alq_level
270           | alq_plugin
271           | alq_fish
272           | alq_dlimit
273           | anat_thresh
274           | alq_wsize
275           | alq_aging
276           | bclear_screen
277           | vcomment
278           | amin_tc_vtime
279           | alock_file
280           | suse_niit
281 ;
282
283 block:      TOK_HNA4 hna4body
284           | TOK_HNA6 hna6body
285           | TOK_IPCCON ipcbody
286           | ifdblock ifbody
287           | ifblock ifbody
288           | plblock plbody
289 ;
290
291 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
292 ;
293
294 hna4stmts: | hna4stmts hna4stmt
295 ;
296
297 hna4stmt:  vcomment
298          | ihna4entry
299 ;
300
301 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
302 ;
303
304 hna6stmts: | hna6stmts hna6stmt
305 ;
306
307 hna6stmt:  vcomment
308          | ihna6entry
309 ;
310
311 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
312 ;
313
314 ipcstmts: | ipcstmts ipcstmt
315 ;
316
317 ipcstmt:  vcomment
318           | imaxipc
319           | ipchost
320           | ipcnet
321 ;
322
323 ifblock:   ifstart ifnicks
324 ;
325
326 ifnicks:   | ifnicks ifnick
327 ;
328
329 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
330 ;
331
332 ifstmts:   | ifstmts ifstmt
333 ;
334
335 ifstmt:      vcomment
336              | iifweight
337              | isetifmode
338              | isetipv4br
339              | isetipv4mc
340              | isetipv6mc
341              | isetipv4src
342              | isetipv6src
343              | isethelloint
344              | isethelloval
345              | isettcint
346              | isettcval
347              | isetmidint
348              | isetmidval
349              | isethnaint
350              | isethnaval
351              | isetautodetchg
352              | isetlqmult
353 ;
354
355 plbody:     TOK_OPEN plstmts TOK_CLOSE
356 ;
357
358 plstmts:   | plstmts plstmt
359 ;
360
361 plstmt:     plparam
362           | vcomment
363 ;
364
365 ifdblock: TOK_INTERFACE_DEFAULTS
366 {
367   struct olsr_if *in = malloc(sizeof(*in));
368
369   if (in == NULL) {
370     fprintf(stderr, "Out of memory(ADD IF)\n");
371     YYABORT;
372   }
373
374   in->cnf = get_default_if_config();
375   in->cnfi = get_default_if_config();
376
377   if (in->cnf == NULL || in->cnfi == NULL) {
378     fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
379     YYABORT;
380   }
381
382   in->name = strdup(interface_defaults_name);
383
384   olsr_cnf->interface_defaults = in->cnf;
385
386   /* Queue */
387   in->next = olsr_cnf->interfaces;
388   olsr_cnf->interfaces = in;
389   ifs_in_curr_cfg=1;
390 }
391 ;
392
393 imaxipc: TOK_MAXIPC TOK_INTEGER
394 {
395   olsr_cnf->ipc_connections = $2->integer;
396   free($2);
397 }
398 ;
399
400 ipchost: TOK_HOSTLABEL TOK_IPV4_ADDR
401 {
402   union olsr_ip_addr ipaddr;
403   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
404   
405   if (inet_aton($2->string, &ipaddr.v4) == 0) {
406     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
407     YYABORT;
408   }
409
410   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
411
412   free($2->string);
413   free($2);
414 }
415 ;
416
417 ipcnet: TOK_NETLABEL TOK_IPV4_ADDR TOK_IPV4_ADDR
418 {
419   union olsr_ip_addr ipaddr, netmask;
420
421   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
422   
423   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
424     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
425     YYABORT;
426   }
427
428   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
429     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
430     YYABORT;
431   }
432
433   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
434
435   free($2->string);
436   free($2);
437   free($3->string);
438   free($3);
439 }
440         |       TOK_NETLABEL TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
441 {
442   union olsr_ip_addr ipaddr;
443
444   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
445   
446   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
447     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
448     YYABORT;
449   }
450
451   if ($4->integer > olsr_cnf->maxplen) {
452     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
453     YYABORT;
454   }
455
456   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
457
458   free($2->string);
459   free($2);
460   free($4);
461 }
462 ;
463
464 iifweight:       TOK_IFWEIGHT TOK_INTEGER
465 {
466   int ifcnt = ifs_in_curr_cfg;
467   struct olsr_if *ifs = olsr_cnf->interfaces;
468
469   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
470
471   while (ifcnt) {
472     ifs->cnf->weight.value = $2->integer;
473     ifs->cnf->weight.fixed = true;
474     ifs->cnfi->weight.value = $2->integer;
475     ifs->cnfi->weight.fixed = true;
476
477     ifs = ifs->next;
478     ifcnt--;
479   }
480
481   free($2);
482 }
483 ;
484
485 isetifmode: TOK_IFMODE TOK_STRING
486 {
487   int ifcnt = ifs_in_curr_cfg;
488   struct olsr_if *ifs = olsr_cnf->interfaces;
489         int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
490
491   PARSER_DEBUG_PRINTF("\tMode: %s\n", $2->string);
492
493         SET_IFS_CONF(ifs, ifcnt, mode, mode);
494         
495   free($2->string);
496   free($2);
497 }
498 ;
499
500 isetipv4br: TOK_IPV4BROADCAST TOK_IPV4_ADDR
501 {
502   struct in_addr in;
503   int ifcnt = ifs_in_curr_cfg;
504   struct olsr_if *ifs = olsr_cnf->interfaces;
505
506   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
507
508   if (inet_aton($2->string, &in) == 0) {
509     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $2->string);
510     YYABORT;
511   }
512
513         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
514
515   free($2->string);
516   free($2);
517 }
518 ;
519
520 isetipv4mc: TOK_IPV4MULTICAST TOK_IPV4_ADDR
521 {
522   struct in_addr in;
523   int ifcnt = ifs_in_curr_cfg;
524   struct olsr_if *ifs = olsr_cnf->interfaces;
525
526   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
527
528   if (inet_aton($2->string, &in) == 0) {
529     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $2->string);
530     YYABORT;
531   }
532
533         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
534
535   free($2->string);
536   free($2);
537 }
538 ;
539
540 isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
541 {
542   struct in6_addr in6;
543   int ifcnt = ifs_in_curr_cfg;
544   struct olsr_if *ifs = olsr_cnf->interfaces;
545
546   PARSER_DEBUG_PRINTF("\tIPv6 multicast: %s\n", $2->string);
547
548   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
549     fprintf(stderr, "isetipv6mc: Failed converting IP address %s\n", $2->string);
550     YYABORT;
551   }
552
553         SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
554
555   free($2->string);
556   free($2);
557 }
558 ;
559
560 isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
561 {
562   struct in_addr in;
563   int ifcnt = ifs_in_curr_cfg;
564   struct olsr_if *ifs = olsr_cnf->interfaces;
565
566   PARSER_DEBUG_PRINTF("\tIPv4 src: %s\n", $2->string);
567
568   if (inet_aton($2->string, &in) == 0) {
569     fprintf(stderr, "isetipv4src: Failed converting IP address %s\n", $2->string);
570     YYABORT;
571   }
572
573         SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
574
575   free($2->string);
576   free($2);
577 }
578 ;
579
580 isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR
581 {
582   struct olsr_ip_prefix pr6;
583   int ifcnt = ifs_in_curr_cfg;
584   struct olsr_if *ifs = olsr_cnf->interfaces;
585
586   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s\n", $2->string);
587
588   if (olsr_string_to_prefix(AF_INET6, &pr6, $2->string) <= 0) {
589     fprintf(stderr, "isetipv6src: Failed converting IP prefix %s\n", $2->string);
590     YYABORT;
591   }
592
593         SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
594
595   free($2->string);
596   free($2);
597 }
598 ;
599
600 isethelloint: TOK_HELLOINT TOK_FLOAT
601 {
602   int ifcnt = ifs_in_curr_cfg;
603   struct olsr_if *ifs = olsr_cnf->interfaces;
604
605   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", $2->floating);
606
607         SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
608
609   free($2);
610 }
611 ;
612 isethelloval: TOK_HELLOVAL TOK_FLOAT
613 {
614   int ifcnt = ifs_in_curr_cfg;
615   struct olsr_if *ifs = olsr_cnf->interfaces;
616
617   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", $2->floating);
618
619         SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
620
621   free($2);
622 }
623 ;
624 isettcint: TOK_TCINT TOK_FLOAT
625 {
626   int ifcnt = ifs_in_curr_cfg;
627   struct olsr_if *ifs = olsr_cnf->interfaces;
628
629   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", $2->floating);
630
631         SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
632
633   free($2);
634 }
635 ;
636 isettcval: TOK_TCVAL TOK_FLOAT
637 {
638   int ifcnt = ifs_in_curr_cfg;
639   struct olsr_if *ifs = olsr_cnf->interfaces;
640   
641   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", $2->floating);
642   
643  SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
644
645   free($2);
646 }
647 ;
648 isetmidint: TOK_MIDINT TOK_FLOAT
649 {
650   int ifcnt = ifs_in_curr_cfg;
651   struct olsr_if *ifs = olsr_cnf->interfaces;
652
653
654   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", $2->floating);
655   
656   SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
657
658   free($2);
659 }
660 ;
661 isetmidval: TOK_MIDVAL TOK_FLOAT
662 {
663   int ifcnt = ifs_in_curr_cfg;
664   struct olsr_if *ifs = olsr_cnf->interfaces;
665
666   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", $2->floating);
667   
668   SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
669
670   free($2);
671 }
672 ;
673 isethnaint: TOK_HNAINT TOK_FLOAT
674 {
675   int ifcnt = ifs_in_curr_cfg;
676   struct olsr_if *ifs = olsr_cnf->interfaces;
677   
678   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", $2->floating);
679
680   SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
681
682   free($2);
683 }
684 ;
685 isethnaval: TOK_HNAVAL TOK_FLOAT
686 {
687   int ifcnt = ifs_in_curr_cfg;
688   struct olsr_if *ifs = olsr_cnf->interfaces;
689
690   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", $2->floating);
691
692   SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
693
694   free($2);
695 }
696 ;
697 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
698 {
699   int ifcnt = ifs_in_curr_cfg;
700   struct olsr_if *ifs = olsr_cnf->interfaces;
701
702   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
703
704   SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
705
706   free($2);
707 }
708 ;
709
710 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
711 {
712   if (lq_mult_helper($2, $3) < 0) {
713     YYABORT;
714   }
715 }
716
717           | TOK_LQ_MULT TOK_IPV4_ADDR TOK_FLOAT
718 {
719   if (lq_mult_helper($2, $3) < 0) {
720     YYABORT;
721   }
722 }
723
724           | TOK_LQ_MULT TOK_IPV6_ADDR TOK_FLOAT
725 {
726   if (lq_mult_helper($2, $3) < 0) {
727     YYABORT;
728   }
729 }
730 ;
731
732 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
733 {
734   olsr_cnf->debug_level = $2->integer;
735   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
736   free($2);
737 }
738 ;
739
740
741 iipversion:    TOK_IPVERSION TOK_INTEGER
742 {
743   if ($2->integer == 4) {
744     olsr_cnf->ip_version = AF_INET;
745     olsr_cnf->ipsize = sizeof(struct in_addr);
746     olsr_cnf->maxplen = 32;
747   } else if ($2->integer == 6) {
748     olsr_cnf->ip_version = AF_INET6;
749     olsr_cnf->ipsize = sizeof(struct in6_addr);
750     olsr_cnf->maxplen = 128;
751   } else {
752     fprintf(stderr, "IPversion must be 4 or 6!\n");
753     YYABORT;
754   }
755
756   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
757   free($2);
758 }
759 ;
760
761 fibmetric:    TOK_FIBMETRIC TOK_STRING
762 {
763   PARSER_DEBUG_PRINTF("FIBMetric: %s\n", $2->string);
764   if (strcmp($2->string, CFG_FIBM_FLAT) == 0) {
765       olsr_cnf->fib_metric = FIBM_FLAT;
766   } else if (strcmp($2->string, CFG_FIBM_CORRECT) == 0) {
767       olsr_cnf->fib_metric = FIBM_CORRECT;
768   } else if (strcmp($2->string, CFG_FIBM_APPROX) == 0) {
769       olsr_cnf->fib_metric = FIBM_APPROX;
770   } else {
771     fprintf(stderr, "FIBMetric must be \"%s\", \"%s\", or \"%s\"!\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX);
772     YYABORT;
773   }
774   free($1);
775   free($2->string);
776   free($2);
777 }
778 ;
779
780 ihna4entry:     TOK_IPV4_ADDR TOK_IPV4_ADDR
781 {
782   union olsr_ip_addr ipaddr, netmask;
783
784   if (olsr_cnf->ip_version == AF_INET6) {
785     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
786     olsr_startup_sleep(3);
787   }
788   else {
789     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
790
791     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
792       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
793       YYABORT;
794     }
795     if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
796       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
797       YYABORT;
798     }
799
800     /* check that the given IP address is actually a network address */
801     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
802       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
803       YYABORT;
804     }
805
806     /* Queue */
807     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
808   }
809   free($1->string);
810   free($1);
811   free($2->string);
812   free($2);
813 }
814         |       TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
815 {
816   union olsr_ip_addr ipaddr, netmask;
817
818   if (olsr_cnf->ip_version == AF_INET6) {
819     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
820     olsr_startup_sleep(3);
821   }
822   else {
823     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
824
825     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
826       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
827       YYABORT;
828     }
829     if ($3->integer > olsr_cnf->maxplen) {
830       fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
831       YYABORT;
832     }
833
834     /* check that the given IP address is actually a network address */
835     olsr_prefix_to_netmask(&netmask, $3->integer);
836     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
837       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
838       YYABORT;
839     }
840
841     /* Queue */
842     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
843   }
844   free($1->string);
845   free($1);
846   free($3);
847 }
848 ;
849
850 ihna6entry:     TOK_IPV6_ADDR TOK_INTEGER
851 {
852   if (add_ipv6_addr($1, $2)) {
853     YYABORT;
854   }
855 }
856         |       TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
857 {
858   if (add_ipv6_addr($1, $3)) {
859     YYABORT;
860   }
861 }
862 ;
863
864 ifstart: TOK_INTERFACE
865 {
866   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
867   ifs_in_curr_cfg = 0;
868 }
869 ;
870
871 ifnick: TOK_STRING
872 {
873   struct olsr_if *in, *last;
874   in = olsr_cnf->interfaces;
875   last = NULL;
876   while (in != NULL) {
877     if (strcmp(in->name, $1->string) == 0) {
878       free ($1->string);
879       break;
880     }
881     last = in;
882     in = in->next;
883   }
884
885   if (in != NULL) {
886     /* remove old interface from list to add it later at the beginning */
887     if (last) {
888       last->next = in->next;
889     }
890     else {
891       olsr_cnf->interfaces = in->next;
892     }
893   }
894   else {
895     in = malloc(sizeof(*in));
896     if (in == NULL) {
897       fprintf(stderr, "Out of memory(ADD IF)\n");
898       YYABORT;
899     }
900     memset(in, 0, sizeof(*in));
901
902     in->cnf = malloc(sizeof(*in->cnf));
903     if (in->cnf == NULL) {
904       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
905       YYABORT;
906     }
907     memset(in->cnf, 0x00, sizeof(*in->cnf));
908
909     in->cnfi = malloc(sizeof(*in->cnfi));
910     if (in->cnf == NULL) {
911       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
912       YYABORT;
913     }
914     memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
915     in->cnfi->orig_lq_mult_cnt=0;
916
917     in->name = $1->string;
918   }
919   /* Queue */
920   in->next = olsr_cnf->interfaces;
921   olsr_cnf->interfaces = in;
922   ifs_in_curr_cfg++;
923   free($1);
924 }
925 ;
926
927 bnoint: TOK_NOINT TOK_BOOLEAN
928 {
929   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
930   olsr_cnf->allow_no_interfaces = $2->boolean;
931   free($2);
932 }
933 ;
934
935 atos: TOK_TOS TOK_INTEGER
936 {
937   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
938   olsr_cnf->tos = $2->integer;
939   free($2);
940
941 }
942 ;
943
944 aolsrport: TOK_OLSRPORT TOK_INTEGER
945 {
946   PARSER_DEBUG_PRINTF("OlsrPort: %d\n", $2->integer);
947   if ($2->integer>=1000) olsr_cnf->olsrport = $2->integer;
948   else olsr_cnf->olsrport = DEF_OLSRPORT;
949   free($2);
950 }
951 ;
952
953 arttable: TOK_RTTABLE TOK_INTEGER
954 {
955   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
956   olsr_cnf->rttable = $2->integer;
957   free($2);
958 }
959 ;
960
961 artproto: TOK_RTPROTO TOK_INTEGER
962 {
963   PARSER_DEBUG_PRINTF("RtProto: %d\n", $2->integer);
964   olsr_cnf->rtproto = $2->integer;
965   free($2);
966 }
967 ;
968
969 arttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
970 {
971   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
972   olsr_cnf->rttable_default = $2->integer;
973   free($2);
974 }
975 ;
976
977 awillingness: TOK_WILLINGNESS TOK_INTEGER
978 {
979   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
980   olsr_cnf->willingness_auto = false;
981   olsr_cnf->willingness = $2->integer;
982   free($2);
983 }
984 ;
985
986 busehyst: TOK_USEHYST TOK_BOOLEAN
987 {
988   olsr_cnf->use_hysteresis = $2->boolean;
989   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
990   free($2);
991 }
992 ;
993
994 fhystscale: TOK_HYSTSCALE TOK_FLOAT
995 {
996   olsr_cnf->hysteresis_param.scaling = $2->floating;
997   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", $2->floating);
998   free($2);
999 }
1000 ;
1001
1002 fhystupper: TOK_HYSTUPPER TOK_FLOAT
1003 {
1004   olsr_cnf->hysteresis_param.thr_high = $2->floating;
1005   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", $2->floating);
1006   free($2);
1007 }
1008 ;
1009
1010 fhystlower: TOK_HYSTLOWER TOK_FLOAT
1011 {
1012   olsr_cnf->hysteresis_param.thr_low = $2->floating;
1013   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", $2->floating);
1014   free($2);
1015 }
1016 ;
1017
1018 fpollrate: TOK_POLLRATE TOK_FLOAT
1019 {
1020   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", $2->floating);
1021   olsr_cnf->pollrate = $2->floating;
1022   free($2);
1023 }
1024 ;
1025
1026 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
1027 {
1028   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", $2->floating);
1029   olsr_cnf->nic_chgs_pollrate = $2->floating;
1030   free($2);
1031 }
1032 ;
1033
1034 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
1035 {
1036   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
1037   olsr_cnf->tc_redundancy = $2->integer;
1038   free($2);
1039 }
1040 ;
1041
1042 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
1043 {
1044   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
1045   olsr_cnf->mpr_coverage = $2->integer;
1046   free($2);
1047 }
1048 ;
1049
1050 alq_level: TOK_LQ_LEVEL TOK_INTEGER
1051 {
1052   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
1053   olsr_cnf->lq_level = $2->integer;
1054   free($2);
1055 }
1056 ;
1057
1058 alq_fish: TOK_LQ_FISH TOK_INTEGER
1059 {
1060   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
1061   olsr_cnf->lq_fish = $2->integer;
1062   free($2);
1063 }
1064 ;
1065
1066 alq_dlimit: TOK_LQ_DLIMIT TOK_INTEGER TOK_FLOAT
1067 {
1068   PARSER_DEBUG_PRINTF("Link quality dijkstra limit %d, %0.2f\n", $2->integer, $3->floating);
1069   olsr_cnf->lq_dlimit = $2->integer;
1070   olsr_cnf->lq_dinter = $3->floating;
1071   free($2);
1072 }
1073 ;
1074
1075 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
1076 {
1077   free($2);
1078 }
1079 ;
1080
1081 alq_aging: TOK_LQ_AGING TOK_FLOAT
1082 {
1083   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", $2->floating);
1084   olsr_cnf->lq_aging = $2->floating;
1085   free($2);
1086 }
1087 ;
1088
1089 amin_tc_vtime: TOK_MIN_TC_VTIME TOK_FLOAT
1090 {
1091   PARSER_DEBUG_PRINTF("Minimum TC validity time %f\n", $2->floating);
1092   olsr_cnf->min_tc_vtime = $2->floating;
1093   free($2);
1094 }
1095 ;
1096
1097 alock_file: TOK_LOCK_FILE TOK_STRING
1098 {
1099   PARSER_DEBUG_PRINTF("Lock file %s\n", $2->string);
1100   olsr_cnf->lock_file = $2->string;
1101   free($2);
1102 }
1103 ;
1104 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1105 {
1106   olsr_cnf->lq_algorithm = $2->string;
1107   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1108   free($2);
1109 }
1110 ;
1111
1112 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1113 {
1114   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
1115   olsr_cnf->lq_nat_thresh = $2->floating;
1116   free($2);
1117 }
1118 ;
1119
1120 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1121 {
1122   PARSER_DEBUG_PRINTF("Clear screen %s\n", $2->boolean ? "enabled" : "disabled");
1123   olsr_cnf->clear_screen = $2->boolean;
1124   free($2);
1125 }
1126 ;
1127
1128 suse_niit: TOK_USE_NIIT TOK_BOOLEAN
1129 {
1130   PARSER_DEBUG_PRINTF("Use NIIT ip translation: %s\n", $2->boolean ? "enabled" : "disabled");
1131   olsr_cnf->use_niit = $2->boolean;
1132   free($2);
1133 }
1134 ;
1135
1136
1137 plblock: TOK_PLUGIN TOK_STRING
1138 {
1139   struct plugin_entry *pe, *last;
1140   
1141   pe = olsr_cnf->plugins;
1142   last = NULL;
1143   while (pe != NULL) {
1144     if (strcmp(pe->name, $2->string) == 0) {
1145       free ($2->string);
1146       break;
1147     }
1148     last = pe;
1149     pe = pe->next;
1150   }
1151
1152   if (pe != NULL) {
1153     /* remove old plugin from list to add it later at the beginning */
1154     if (last) {
1155       last->next = pe->next;
1156     }
1157     else {
1158       olsr_cnf->plugins = pe->next;
1159     }
1160   }
1161   else {
1162     pe = malloc(sizeof(*pe));
1163
1164     if (pe == NULL) {
1165       fprintf(stderr, "Out of memory(ADD PL)\n");
1166       YYABORT;
1167     }
1168
1169     pe->name = $2->string;
1170     pe->params = NULL;
1171
1172     PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1173   }
1174   
1175   /* Queue */
1176   pe->next = olsr_cnf->plugins;
1177   olsr_cnf->plugins = pe;
1178
1179   free($2);
1180 }
1181 ;
1182
1183 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1184 {
1185   struct plugin_param *pp = malloc(sizeof(*pp));
1186   
1187   if (pp == NULL) {
1188     fprintf(stderr, "Out of memory(ADD PP)\n");
1189     YYABORT;
1190   }
1191   
1192   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1193   
1194   pp->key = $2->string;
1195   pp->value = $3->string;
1196
1197   /* Queue */
1198   pp->next = olsr_cnf->plugins->params;
1199   olsr_cnf->plugins->params = pp;
1200
1201   free($2);
1202   free($3);
1203 }
1204 ;
1205
1206 vcomment:       TOK_COMMENT
1207 {
1208     //PARSER_DEBUG_PRINTF("Comment\n");
1209 }
1210 ;
1211
1212
1213
1214 %%
1215
1216 void yyerror (const char *string)
1217 {
1218   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1219 }