rttable-default: (from otti) configures a new policy routing table for the default...
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * The olsr.org Optimized Link-State Routing daemon(olsrd)
5  * Copyright (c) 2004, Andreas T√łnnesen(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
49 #include <stddef.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 #include <string.h>
57
58 #define PARSER_DEBUG 0
59
60 #if PARSER_DEBUG
61 #define PARSER_DEBUG_PRINTF(x, ...)   printf(x, ##args)
62 #else
63 #define PARSER_DEBUG_PRINTF(x, ...)   do { } while (0)
64 #endif
65
66 #define YYSTYPE struct conf_token *
67
68 void yyerror(const char *);
69 int yylex(void);
70
71 static int ifs_in_curr_cfg = 0;
72
73 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg);
74 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
75
76 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
77 {
78   union olsr_ip_addr addr;
79   int i;
80   struct olsr_if *walker;
81
82 #if PARSER_DEBUG > 0
83   printf("\tLinkQualityMult %s %0.2f\n",
84          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
85          mult_arg->floating);
86 #endif
87
88   memset(&addr, 0, sizeof(addr));
89
90   if (ip_addr_arg != NULL &&
91      inet_pton(olsr_cnf->ip_version, ip_addr_arg->string, &addr) <= 0) {
92     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
93     return -1;
94   }
95
96   walker = olsr_cnf->interfaces;
97
98   for (i = 0; i < ifs_in_curr_cfg; i++) {
99     struct olsr_lq_mult *mult = malloc(sizeof(*mult));
100     if (mult == NULL) {
101       fprintf(stderr, "Out of memory (LQ multiplier).\n");
102       return -1;
103     }
104
105     mult->addr = addr;
106     mult->val = mult_arg->floating;
107
108     mult->next = walker->cnf->lq_mult;
109     walker->cnf->lq_mult = mult;
110
111     walker = walker->next;
112   }
113
114   if (ip_addr_arg != NULL) {
115     free(ip_addr_arg->string);
116     free(ip_addr_arg);
117   }
118
119   free(mult_arg);
120
121   return 0;
122 }
123
124 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
125 {
126   union olsr_ip_addr ipaddr;
127   PARSER_DEBUG_PRINTF("HNA IPv6 entry: %s/%d\n", ipaddr_arg->string, prefixlen_arg->integer);
128
129   if (olsr_cnf->ip_version != AF_INET6) {
130     fprintf(stderr, "IPv6 addresses can only be used if \"IpVersion\" == 6\n");
131     return 1;
132   }
133
134   if(inet_pton(AF_INET6, ipaddr_arg->string, &ipaddr) <= 0) {
135     fprintf(stderr, "ihna6entry: Failed converting IP address %s\n", ipaddr_arg->string);
136     return 1;
137   }
138
139   if (prefixlen_arg->integer > 128) {
140     fprintf(stderr, "ihna6entry: Illegal IPv6 prefix length %d\n", prefixlen_arg->integer);
141     return 1;
142   }
143
144   /* Queue */
145   ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, prefixlen_arg->integer);
146
147   free(ipaddr_arg->string);
148   free(ipaddr_arg);
149   free(prefixlen_arg);
150
151   return 0;
152 }
153
154 %}
155
156 %token TOK_SLASH
157 %token TOK_OPEN
158 %token TOK_CLOSE
159
160 %token TOK_STRING
161 %token TOK_INTEGER
162 %token TOK_FLOAT
163 %token TOK_BOOLEAN
164
165 %token TOK_IP6TYPE
166
167 %token TOK_DEBUGLEVEL
168 %token TOK_IPVERSION
169 %token TOK_HNA4
170 %token TOK_HNA6
171 %token TOK_PLUGIN
172 %token TOK_INTERFACE
173 %token TOK_NOINT
174 %token TOK_TOS
175 %token TOK_RTTABLE
176 %token TOK_RTTABLE_DEFAULT
177 %token TOK_WILLINGNESS
178 %token TOK_IPCCON
179 %token TOK_FIBMETRIC
180 %token TOK_USEHYST
181 %token TOK_HYSTSCALE
182 %token TOK_HYSTUPPER
183 %token TOK_HYSTLOWER
184 %token TOK_POLLRATE
185 %token TOK_NICCHGSPOLLRT
186 %token TOK_TCREDUNDANCY
187 %token TOK_MPRCOVERAGE
188 %token TOK_LQ_LEVEL
189 %token TOK_LQ_FISH
190 %token TOK_LQ_DLIMIT
191 %token TOK_LQ_WSIZE
192 %token TOK_LQ_NAT_THRESH
193 %token TOK_LQ_MULT
194 %token TOK_CLEAR_SCREEN
195 %token TOK_PLPARAM
196
197 %token TOK_HOSTLABEL
198 %token TOK_NETLABEL
199 %token TOK_MAXIPC
200
201 %token TOK_IP4BROADCAST
202 %token TOK_IP6ADDRTYPE
203 %token TOK_IP6MULTISITE
204 %token TOK_IP6MULTIGLOBAL
205 %token TOK_IFWEIGHT
206 %token TOK_HELLOINT
207 %token TOK_HELLOVAL
208 %token TOK_TCINT
209 %token TOK_TCVAL
210 %token TOK_MIDINT
211 %token TOK_MIDVAL
212 %token TOK_HNAINT
213 %token TOK_HNAVAL
214 %token TOK_AUTODETCHG
215
216 %token TOK_IP4_ADDR
217 %token TOK_IP6_ADDR
218 %token TOK_DEFAULT
219
220 %token TOK_COMMENT
221
222 %%
223
224 conf:
225           | conf block
226           | conf stmt
227 ;
228
229 stmt:       idebug
230           | iipversion
231           | fibmetric
232           | bnoint
233           | atos
234           | arttable
235           | arttable_default
236           | awillingness
237           | busehyst
238           | fhystscale
239           | fhystupper
240           | fhystlower
241           | fpollrate
242           | fnicchgspollrt
243           | atcredundancy
244           | amprcoverage
245           | alq_level
246           | alq_fish
247           | alq_dlimit
248           | anat_thresh
249           | alq_wsize
250           | bclear_screen
251           | vcomment
252 ;
253
254 block:      TOK_HNA4 hna4body
255           | TOK_HNA6 hna6body
256           | TOK_IPCCON ipcbody
257           | ifblock ifbody
258           | plblock plbody
259 ;
260
261 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
262 ;
263
264 hna4stmts: | hna4stmts hna4stmt
265 ;
266
267 hna4stmt:  vcomment
268          | ihna4entry
269 ;
270
271 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
272 ;
273
274 hna6stmts: | hna6stmts hna6stmt
275 ;
276
277 hna6stmt:  vcomment
278          | ihna6entry
279 ;
280
281 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
282 ;
283
284 ipcstmts: | ipcstmts ipcstmt
285 ;
286
287 ipcstmt:  vcomment
288           | imaxipc
289           | ipchost
290           | ipcnet
291 ;
292
293 ifblock:   ifstart ifnicks
294 ;
295
296 ifnicks:   | ifnicks ifnick
297 ;
298
299 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
300 ;
301
302 ifstmts:   | ifstmts ifstmt
303 ;
304
305 ifstmt:      vcomment
306              | iifweight
307              | isetip4br
308              | isetip6addrt
309              | isetip6mults
310              | isetip6multg
311              | isethelloint
312              | isethelloval
313              | isettcint
314              | isettcval
315              | isetmidint
316              | isetmidval
317              | isethnaint
318              | isethnaval
319              | isetautodetchg
320              | isetlqmult
321 ;
322
323 plbody:     TOK_OPEN plstmts TOK_CLOSE
324 ;
325
326 plstmts:   | plstmts plstmt
327 ;
328
329 plstmt:     plparam
330           | vcomment
331 ;
332
333 imaxipc: TOK_MAXIPC TOK_INTEGER
334 {
335   olsr_cnf->ipc_connections = $2->integer;
336   free($2);
337 }
338 ;
339
340 ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
341 {
342   union olsr_ip_addr ipaddr;
343   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
344   
345   if (inet_aton($2->string, &ipaddr.v4) == 0) {
346     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
347     YYABORT;
348   }
349
350   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
351
352   free($2->string);
353   free($2);
354 }
355 ;
356
357 ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
358 {
359   union olsr_ip_addr ipaddr, netmask;
360
361   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
362   
363   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
364     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
365     YYABORT;
366   }
367
368   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
369     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
370     YYABORT;
371   }
372
373   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
374
375   free($2->string);
376   free($2);
377   free($3->string);
378   free($3);
379 }
380         |       TOK_NETLABEL TOK_IP4_ADDR TOK_SLASH TOK_INTEGER
381 {
382   union olsr_ip_addr ipaddr;
383
384   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
385   
386   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
387     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
388     YYABORT;
389   }
390
391   if ($4->integer > olsr_cnf->maxplen) {
392     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
393     YYABORT;
394   }
395
396   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
397
398   free($2->string);
399   free($2);
400   free($4);
401 }
402 ;
403
404 iifweight:       TOK_IFWEIGHT TOK_INTEGER
405 {
406   int ifcnt = ifs_in_curr_cfg;
407   struct olsr_if *ifs = olsr_cnf->interfaces;
408
409   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
410
411   while (ifcnt) {
412     ifs->cnf->weight.value = $2->integer;
413     ifs->cnf->weight.fixed = OLSR_TRUE;
414
415     ifs = ifs->next;
416     ifcnt--;
417   }
418
419   free($2);
420 }
421 ;
422
423 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
424 {
425   struct in_addr in;
426   int ifcnt = ifs_in_curr_cfg;
427   struct olsr_if *ifs = olsr_cnf->interfaces;
428
429   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
430
431   if (inet_aton($2->string, &in) == 0) {
432     fprintf(stderr, "isetip4br: Failed converting IP address %s\n", $2->string);
433     YYABORT;
434   }
435
436   while (ifcnt) {
437     ifs->cnf->ipv4_broadcast.v4 = in;
438
439     ifs = ifs->next;
440     ifcnt--;
441   }
442
443   free($2->string);
444   free($2);
445 }
446 ;
447
448 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
449 {
450   int ifcnt = ifs_in_curr_cfg;
451   struct olsr_if *ifs = olsr_cnf->interfaces;
452
453   if ($2->boolean) {
454     while (ifcnt) {
455       ifs->cnf->ipv6_addrtype = IPV6_ADDR_SITELOCAL;
456           
457       ifs = ifs->next;
458       ifcnt--;
459     }
460   } else {
461     while (ifcnt) {
462       ifs->cnf->ipv6_addrtype = 0;
463           
464       ifs = ifs->next;
465       ifcnt--;
466     }
467   }
468
469   free($2);
470 }
471 ;
472
473 isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
474 {
475   struct in6_addr in6;
476   int ifcnt = ifs_in_curr_cfg;
477   struct olsr_if *ifs = olsr_cnf->interfaces;
478
479   PARSER_DEBUG_PRINTF("\tIPv6 site-local multicast: %s\n", $2->string);
480
481   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
482     fprintf(stderr, "isetip6mults: Failed converting IP address %s\n", $2->string);
483     YYABORT;
484   }
485
486   while (ifcnt) {
487     ifs->cnf->ipv6_multi_site.v6 = in6;
488       
489     ifs = ifs->next;
490     ifcnt--;
491   }
492
493   free($2->string);
494   free($2);
495 }
496 ;
497
498
499 isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
500 {
501   struct in6_addr in6;
502   int ifcnt = ifs_in_curr_cfg;
503   struct olsr_if *ifs = olsr_cnf->interfaces;
504
505   PARSER_DEBUG_PRINTF("\tIPv6 global multicast: %s\n", $2->string);
506
507   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
508     fprintf(stderr, "isetip6multg: Failed converting IP address %s\n", $2->string);
509     YYABORT;
510   }
511
512   while (ifcnt) {
513     //memcpy(&ifs->cnf->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
514     ifs->cnf->ipv6_multi_glbl.v6 = in6;
515       
516     ifs = ifs->next;
517     ifcnt--;
518   }
519
520   free($2->string);
521   free($2);
522 }
523 ;
524 isethelloint: TOK_HELLOINT TOK_FLOAT
525 {
526   int ifcnt = ifs_in_curr_cfg;
527   struct olsr_if *ifs = olsr_cnf->interfaces;
528
529   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", $2->floating);
530
531   while (ifcnt) {
532     ifs->cnf->hello_params.emission_interval = $2->floating;
533       
534     ifs = ifs->next;
535     ifcnt--;
536   }
537
538   free($2);
539 }
540 ;
541 isethelloval: TOK_HELLOVAL TOK_FLOAT
542 {
543   int ifcnt = ifs_in_curr_cfg;
544   struct olsr_if *ifs = olsr_cnf->interfaces;
545
546   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", $2->floating);
547
548   while (ifcnt) {
549     ifs->cnf->hello_params.validity_time = $2->floating;
550       
551     ifs = ifs->next;
552     ifcnt--;
553   }
554
555   free($2);
556 }
557 ;
558 isettcint: TOK_TCINT TOK_FLOAT
559 {
560   int ifcnt = ifs_in_curr_cfg;
561   struct olsr_if *ifs = olsr_cnf->interfaces;
562
563   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", $2->floating);
564
565   while (ifcnt) {
566     ifs->cnf->tc_params.emission_interval = $2->floating;
567       
568     ifs = ifs->next;
569     ifcnt--;
570   }
571   free($2);
572 }
573 ;
574 isettcval: TOK_TCVAL TOK_FLOAT
575 {
576   int ifcnt = ifs_in_curr_cfg;
577   struct olsr_if *ifs = olsr_cnf->interfaces;
578   
579   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", $2->floating);
580   while (ifcnt) {
581     ifs->cnf->tc_params.validity_time = $2->floating;
582       
583     ifs = ifs->next;
584     ifcnt--;
585   }
586
587   free($2);
588 }
589 ;
590 isetmidint: TOK_MIDINT TOK_FLOAT
591 {
592   int ifcnt = ifs_in_curr_cfg;
593   struct olsr_if *ifs = olsr_cnf->interfaces;
594
595
596   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", $2->floating);
597   while (ifcnt) {
598     ifs->cnf->mid_params.emission_interval = $2->floating;
599       
600     ifs = ifs->next;
601     ifcnt--;
602   }
603
604   free($2);
605 }
606 ;
607 isetmidval: TOK_MIDVAL TOK_FLOAT
608 {
609   int ifcnt = ifs_in_curr_cfg;
610   struct olsr_if *ifs = olsr_cnf->interfaces;
611
612   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", $2->floating);
613   while (ifcnt) {
614     ifs->cnf->mid_params.validity_time = $2->floating;
615       
616     ifs = ifs->next;
617     ifcnt--;
618   }
619
620   free($2);
621 }
622 ;
623 isethnaint: TOK_HNAINT TOK_FLOAT
624 {
625   int ifcnt = ifs_in_curr_cfg;
626   struct olsr_if *ifs = olsr_cnf->interfaces;
627   
628   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", $2->floating);
629   while (ifcnt) {
630     ifs->cnf->hna_params.emission_interval = $2->floating;
631       
632     ifs = ifs->next;
633     ifcnt--;
634   }
635
636   free($2);
637 }
638 ;
639 isethnaval: TOK_HNAVAL TOK_FLOAT
640 {
641   int ifcnt = ifs_in_curr_cfg;
642   struct olsr_if *ifs = olsr_cnf->interfaces;
643
644   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", $2->floating);
645   while (ifcnt) {
646     ifs->cnf->hna_params.validity_time = $2->floating;
647       
648     ifs = ifs->next;
649     ifcnt--;
650   }
651
652   free($2);
653 }
654 ;
655 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
656 {
657   int ifcnt = ifs_in_curr_cfg;
658   struct olsr_if *ifs = olsr_cnf->interfaces;
659
660   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
661   while (ifcnt) {
662     ifs->cnf->autodetect_chg = $2->boolean;
663       
664     ifs = ifs->next;
665     ifcnt--;
666   }
667
668   free($2);
669 }
670 ;
671
672 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
673 {
674   if (lq_mult_helper($2, $3) < 0) {
675     YYABORT;
676   }
677 }
678
679           | TOK_LQ_MULT TOK_IP4_ADDR TOK_FLOAT
680 {
681   if (lq_mult_helper($2, $3) < 0) {
682     YYABORT;
683   }
684 }
685
686           | TOK_LQ_MULT TOK_IP6_ADDR TOK_FLOAT
687 {
688   if (lq_mult_helper($2, $3) < 0) {
689     YYABORT;
690   }
691 }
692 ;
693
694 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
695 {
696   olsr_cnf->debug_level = $2->integer;
697   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
698   free($2);
699 }
700 ;
701
702
703 iipversion:    TOK_IPVERSION TOK_INTEGER
704 {
705   if ($2->integer == 4) {
706     olsr_cnf->ip_version = AF_INET;
707     olsr_cnf->ipsize = sizeof(struct in_addr);
708     olsr_cnf->maxplen = 32;
709   } else if ($2->integer == 6) {
710     olsr_cnf->ip_version = AF_INET6;
711     olsr_cnf->ipsize = sizeof(struct in6_addr);
712     olsr_cnf->maxplen = 128;
713   } else {
714     fprintf(stderr, "IPversion must be 4 or 6!\n");
715     YYABORT;
716   }
717
718   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
719   free($2);
720 }
721 ;
722
723 fibmetric:    TOK_FIBMETRIC TOK_STRING
724 {
725   PARSER_DEBUG_PRINTF("FIBMetric: %d\n", $2->string);
726   if (strcmp($2->string, CFG_FIBM_FLAT) == 0) {
727       olsr_cnf->fib_metric = FIBM_FLAT;
728   } else if (strcmp($2->string, CFG_FIBM_CORRECT) == 0) {
729       olsr_cnf->fib_metric = FIBM_CORRECT;
730   } else if (strcmp($2->string, CFG_FIBM_APPROX) == 0) {
731       olsr_cnf->fib_metric = FIBM_APPROX;
732   } else {
733     fprintf(stderr, "FIBMetric must be \"%s\", \"%s\", or \"%s\"!\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX);
734     YYABORT;
735   }
736   free($1);
737   free($2->string);
738   free($2);
739 }
740 ;
741
742 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
743 {
744   union olsr_ip_addr ipaddr, netmask;
745
746   PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
747
748   if (olsr_cnf->ip_version != AF_INET) {
749     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4\n");
750     YYABORT;
751   }
752
753   if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
754     fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
755     YYABORT;
756   }
757   if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
758     fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
759     YYABORT;
760   }
761
762   /* check that the given IP address is actually a network address */
763   if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
764     fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
765     YYABORT;
766   }
767
768   /* Queue */
769   ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
770
771   free($1->string);
772   free($1);
773   free($2->string);
774   free($2);
775 }
776         |       TOK_IP4_ADDR TOK_SLASH TOK_INTEGER
777 {
778   union olsr_ip_addr ipaddr, netmask;
779
780   PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
781
782   if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
783     fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
784     YYABORT;
785   }
786   if ($3->integer > olsr_cnf->maxplen) {
787     fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
788     YYABORT;
789   }
790
791   /* check that the given IP address is actually a network address */
792   olsr_prefix_to_netmask(&netmask, $3->integer);
793   if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
794     fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
795     YYABORT;
796   }
797
798   /* Queue */
799   ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
800
801   free($1->string);
802   free($1);
803   free($3);
804 }
805 ;
806
807 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
808 {
809   if (add_ipv6_addr($1, $2)) {
810     YYABORT;
811   }
812 }
813         |       TOK_IP6_ADDR TOK_SLASH TOK_INTEGER
814 {
815   if (add_ipv6_addr($1, $3)) {
816     YYABORT;
817   }
818 }
819 ;
820
821 ifstart: TOK_INTERFACE
822 {
823   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
824   ifs_in_curr_cfg = 0;
825 }
826 ;
827
828 ifnick: TOK_STRING
829 {
830   struct olsr_if *in = malloc(sizeof(*in));
831   
832   if (in == NULL) {
833     fprintf(stderr, "Out of memory(ADD IF)\n");
834     YYABORT;
835   }
836
837   in->cnf = get_default_if_config();
838
839   if (in->cnf == NULL) {
840     fprintf(stderr, "Out of memory(ADD IFRULE)\n");
841     YYABORT;
842   }
843
844   in->name = $1->string;
845
846   /* Queue */
847   in->next = olsr_cnf->interfaces;
848   olsr_cnf->interfaces = in;
849   ifs_in_curr_cfg++;
850   free($1);
851 }
852 ;
853
854 bnoint: TOK_NOINT TOK_BOOLEAN
855 {
856   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
857   olsr_cnf->allow_no_interfaces = $2->boolean;
858   free($2);
859 }
860 ;
861
862 atos: TOK_TOS TOK_INTEGER
863 {
864   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
865   olsr_cnf->tos = $2->integer;
866   free($2);
867
868 }
869 ;
870
871 arttable: TOK_RTTABLE TOK_INTEGER
872 {
873   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
874   olsr_cnf->rttable = $2->integer;
875   free($2);
876 }
877 ;
878
879 arttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
880 {
881   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
882   olsr_cnf->rttable_default = $2->integer;
883   free($2);
884 }
885 ;
886
887 awillingness: TOK_WILLINGNESS TOK_INTEGER
888 {
889   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
890   olsr_cnf->willingness_auto = OLSR_FALSE;
891   olsr_cnf->willingness = $2->integer;
892   free($2);
893 }
894 ;
895
896 busehyst: TOK_USEHYST TOK_BOOLEAN
897 {
898   olsr_cnf->use_hysteresis = $2->boolean;
899   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
900   free($2);
901 }
902 ;
903
904 fhystscale: TOK_HYSTSCALE TOK_FLOAT
905 {
906   olsr_cnf->hysteresis_param.scaling = $2->floating;
907   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", $2->floating);
908   free($2);
909 }
910 ;
911
912 fhystupper: TOK_HYSTUPPER TOK_FLOAT
913 {
914   olsr_cnf->hysteresis_param.thr_high = $2->floating;
915   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", $2->floating);
916   free($2);
917 }
918 ;
919
920 fhystlower: TOK_HYSTLOWER TOK_FLOAT
921 {
922   olsr_cnf->hysteresis_param.thr_low = $2->floating;
923   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", $2->floating);
924   free($2);
925 }
926 ;
927
928 fpollrate: TOK_POLLRATE TOK_FLOAT
929 {
930   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", $2->floating);
931   olsr_cnf->pollrate = $2->floating;
932   free($2);
933 }
934 ;
935
936 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
937 {
938   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", $2->floating);
939   olsr_cnf->nic_chgs_pollrate = $2->floating;
940   free($2);
941 }
942 ;
943
944 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
945 {
946   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
947   olsr_cnf->tc_redundancy = $2->integer;
948   free($2);
949 }
950 ;
951
952 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
953 {
954   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
955   olsr_cnf->mpr_coverage = $2->integer;
956   free($2);
957 }
958 ;
959
960 alq_level: TOK_LQ_LEVEL TOK_INTEGER
961 {
962   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
963   olsr_cnf->lq_level = $2->integer;
964   free($2);
965 }
966 ;
967
968 alq_fish: TOK_LQ_FISH TOK_INTEGER
969 {
970   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
971   olsr_cnf->lq_fish = $2->integer;
972   free($2);
973 }
974 ;
975
976 alq_dlimit: TOK_LQ_DLIMIT TOK_INTEGER TOK_FLOAT
977 {
978   PARSER_DEBUG_PRINTF("Link quality dijkstra limit %d, %0.2f\n", $2->integer, $3->floating);
979   olsr_cnf->lq_dlimit = $2->integer;
980   olsr_cnf->lq_dinter = $3->floating;
981   free($2);
982 }
983 ;
984
985 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
986 {
987   PARSER_DEBUG_PRINTF("Link quality window size %d\n", $2->integer);
988   olsr_cnf->lq_wsize = $2->integer;
989   free($2);
990 }
991 ;
992
993 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
994 {
995   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
996   olsr_cnf->lq_nat_thresh = $2->floating;
997   free($2);
998 }
999 ;
1000
1001 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1002 {
1003   PARSER_DEBUG_PRINTF("Clear screen %s\n", olsr_cnf->clear_screen ? "enabled" : "disabled");
1004   olsr_cnf->clear_screen = $2->boolean;
1005   free($2);
1006 }
1007 ;
1008
1009 plblock: TOK_PLUGIN TOK_STRING
1010 {
1011   struct plugin_entry *pe = malloc(sizeof(*pe));
1012   
1013   if (pe == NULL) {
1014     fprintf(stderr, "Out of memory(ADD PL)\n");
1015     YYABORT;
1016   }
1017
1018   pe->name = $2->string;
1019   pe->params = NULL;
1020   
1021   PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1022
1023   /* Queue */
1024   pe->next = olsr_cnf->plugins;
1025   olsr_cnf->plugins = pe;
1026
1027   free($2);
1028 }
1029 ;
1030
1031 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1032 {
1033   struct plugin_param *pp = malloc(sizeof(*pp));
1034   
1035   if (pp == NULL) {
1036     fprintf(stderr, "Out of memory(ADD PP)\n");
1037     YYABORT;
1038   }
1039   
1040   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1041   
1042   pp->key = $2->string;
1043   pp->value = $3->string;
1044
1045   /* Queue */
1046   pp->next = olsr_cnf->plugins->params;
1047   olsr_cnf->plugins->params = pp;
1048
1049   free($2);
1050   free($3);
1051 }
1052 ;
1053
1054 vcomment:       TOK_COMMENT
1055 {
1056     //PARSER_DEBUG_PRINTF("Comment\n");
1057 }
1058 ;
1059
1060
1061
1062 %%
1063
1064 void yyerror (const char *string)
1065 {
1066   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1067 }