c7cdd09f81c838b227a0ebd7850ab2e7913ab7c6
[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
50 #include <stddef.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <sys/types.h>
54 #include <sys/socket.h>
55 #include <netinet/in.h>
56 #include <arpa/inet.h>
57 #include <string.h>
58
59 #define PARSER_DEBUG 0
60
61 #if PARSER_DEBUG
62 #define PARSER_DEBUG_PRINTF(x, ...)   printf(x, ##args)
63 #else
64 #define PARSER_DEBUG_PRINTF(x, ...)   do { } while (0)
65 #endif
66
67 #define YYSTYPE struct conf_token *
68
69 void yyerror(const char *);
70 int yylex(void);
71
72 static int ifs_in_curr_cfg = 0;
73
74 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg);
75 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
76
77 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
78 {
79   union olsr_ip_addr addr;
80   int i;
81   struct olsr_if *walker;
82
83 #if PARSER_DEBUG > 0
84   printf("\tLinkQualityMult %s %0.2f\n",
85          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
86          mult_arg->floating);
87 #endif
88
89   memset(&addr, 0, sizeof(addr));
90
91   if (ip_addr_arg != NULL &&
92      inet_pton(olsr_cnf->ip_version, ip_addr_arg->string, &addr) <= 0) {
93     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
94     return -1;
95   }
96
97   walker = olsr_cnf->interfaces;
98
99   for (i = 0; i < ifs_in_curr_cfg; i++) {
100     struct olsr_lq_mult *mult = malloc(sizeof(*mult));
101     if (mult == NULL) {
102       fprintf(stderr, "Out of memory (LQ multiplier).\n");
103       return -1;
104     }
105
106     mult->addr = addr;
107     mult->value = (olsr_u32_t)(mult_arg->floating * LINK_LOSS_MULTIPLIER);
108
109     mult->next = walker->cnf->lq_mult;
110     walker->cnf->lq_mult = mult;
111
112     walker = walker->next;
113   }
114
115   if (ip_addr_arg != NULL) {
116     free(ip_addr_arg->string);
117     free(ip_addr_arg);
118   }
119
120   free(mult_arg);
121
122   return 0;
123 }
124
125 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
126 {
127   union olsr_ip_addr ipaddr;
128   PARSER_DEBUG_PRINTF("HNA IPv6 entry: %s/%d\n", ipaddr_arg->string, prefixlen_arg->integer);
129
130   if (olsr_cnf->ip_version != AF_INET6) {
131     fprintf(stderr, "IPv6 addresses can only be used if \"IpVersion\" == 6\n");
132     return 1;
133   }
134
135   if(inet_pton(AF_INET6, ipaddr_arg->string, &ipaddr) <= 0) {
136     fprintf(stderr, "ihna6entry: Failed converting IP address %s\n", ipaddr_arg->string);
137     return 1;
138   }
139
140   if (prefixlen_arg->integer > 128) {
141     fprintf(stderr, "ihna6entry: Illegal IPv6 prefix length %d\n", prefixlen_arg->integer);
142     return 1;
143   }
144
145   /* Queue */
146   ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, prefixlen_arg->integer);
147
148   free(ipaddr_arg->string);
149   free(ipaddr_arg);
150   free(prefixlen_arg);
151
152   return 0;
153 }
154
155 %}
156
157 %token TOK_SLASH
158 %token TOK_OPEN
159 %token TOK_CLOSE
160
161 %token TOK_STRING
162 %token TOK_INTEGER
163 %token TOK_FLOAT
164 %token TOK_BOOLEAN
165
166 %token TOK_IP6TYPE
167
168 %token TOK_DEBUGLEVEL
169 %token TOK_IPVERSION
170 %token TOK_HNA4
171 %token TOK_HNA6
172 %token TOK_PLUGIN
173 %token TOK_INTERFACE
174 %token TOK_NOINT
175 %token TOK_TOS
176 %token TOK_RTTABLE
177 %token TOK_RTTABLE_DEFAULT
178 %token TOK_WILLINGNESS
179 %token TOK_IPCCON
180 %token TOK_FIBMETRIC
181 %token TOK_USEHYST
182 %token TOK_HYSTSCALE
183 %token TOK_HYSTUPPER
184 %token TOK_HYSTLOWER
185 %token TOK_POLLRATE
186 %token TOK_NICCHGSPOLLRT
187 %token TOK_TCREDUNDANCY
188 %token TOK_MPRCOVERAGE
189 %token TOK_LQ_LEVEL
190 %token TOK_LQ_FISH
191 %token TOK_LQ_DLIMIT
192 %token TOK_LQ_WSIZE
193 %token TOK_LQ_AGING
194 %token TOK_LQ_PLUGIN
195 %token TOK_LQ_NAT_THRESH
196 %token TOK_LQ_MULT
197 %token TOK_CLEAR_SCREEN
198 %token TOK_PLPARAM
199
200 %token TOK_HOSTLABEL
201 %token TOK_NETLABEL
202 %token TOK_MAXIPC
203
204 %token TOK_IP4BROADCAST
205 %token TOK_IP6ADDRTYPE
206 %token TOK_IP6MULTISITE
207 %token TOK_IP6MULTIGLOBAL
208 %token TOK_IFWEIGHT
209 %token TOK_HELLOINT
210 %token TOK_HELLOVAL
211 %token TOK_TCINT
212 %token TOK_TCVAL
213 %token TOK_MIDINT
214 %token TOK_MIDVAL
215 %token TOK_HNAINT
216 %token TOK_HNAVAL
217 %token TOK_AUTODETCHG
218
219 %token TOK_IP4_ADDR
220 %token TOK_IP6_ADDR
221 %token TOK_DEFAULT
222
223 %token TOK_COMMENT
224
225 %%
226
227 conf:
228           | conf block
229           | conf stmt
230 ;
231
232 stmt:       idebug
233           | iipversion
234           | fibmetric
235           | bnoint
236           | atos
237           | arttable
238           | arttable_default
239           | awillingness
240           | busehyst
241           | fhystscale
242           | fhystupper
243           | fhystlower
244           | fpollrate
245           | fnicchgspollrt
246           | atcredundancy
247           | amprcoverage
248           | alq_level
249           | alq_plugin
250           | alq_fish
251           | alq_dlimit
252           | anat_thresh
253           | alq_wsize
254           | alq_aging
255           | bclear_screen
256           | vcomment
257 ;
258
259 block:      TOK_HNA4 hna4body
260           | TOK_HNA6 hna6body
261           | TOK_IPCCON ipcbody
262           | ifblock ifbody
263           | plblock plbody
264 ;
265
266 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
267 ;
268
269 hna4stmts: | hna4stmts hna4stmt
270 ;
271
272 hna4stmt:  vcomment
273          | ihna4entry
274 ;
275
276 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
277 ;
278
279 hna6stmts: | hna6stmts hna6stmt
280 ;
281
282 hna6stmt:  vcomment
283          | ihna6entry
284 ;
285
286 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
287 ;
288
289 ipcstmts: | ipcstmts ipcstmt
290 ;
291
292 ipcstmt:  vcomment
293           | imaxipc
294           | ipchost
295           | ipcnet
296 ;
297
298 ifblock:   ifstart ifnicks
299 ;
300
301 ifnicks:   | ifnicks ifnick
302 ;
303
304 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
305 ;
306
307 ifstmts:   | ifstmts ifstmt
308 ;
309
310 ifstmt:      vcomment
311              | iifweight
312              | isetip4br
313              | isetip6addrt
314              | isetip6mults
315              | isetip6multg
316              | isethelloint
317              | isethelloval
318              | isettcint
319              | isettcval
320              | isetmidint
321              | isetmidval
322              | isethnaint
323              | isethnaval
324              | isetautodetchg
325              | isetlqmult
326 ;
327
328 plbody:     TOK_OPEN plstmts TOK_CLOSE
329 ;
330
331 plstmts:   | plstmts plstmt
332 ;
333
334 plstmt:     plparam
335           | vcomment
336 ;
337
338 imaxipc: TOK_MAXIPC TOK_INTEGER
339 {
340   if ($2->integer > 255) {
341     fprintf(stderr, "\"MaxConnections\" must be >= 0 and <= 255 (and not %d)\n", $2->integer);
342     YYABORT;
343   }
344   olsr_cnf->ipc_connections = $2->integer;
345   free($2);
346 }
347 ;
348
349 ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
350 {
351   union olsr_ip_addr ipaddr;
352   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
353   
354   if (inet_aton($2->string, &ipaddr.v4) == 0) {
355     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
356     YYABORT;
357   }
358
359   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
360
361   free($2->string);
362   free($2);
363 }
364 ;
365
366 ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
367 {
368   union olsr_ip_addr ipaddr, netmask;
369
370   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
371   
372   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
373     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
374     YYABORT;
375   }
376
377   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
378     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
379     YYABORT;
380   }
381
382   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
383
384   free($2->string);
385   free($2);
386   free($3->string);
387   free($3);
388 }
389         |       TOK_NETLABEL TOK_IP4_ADDR TOK_SLASH TOK_INTEGER
390 {
391   union olsr_ip_addr ipaddr;
392
393   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
394   
395   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
396     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
397     YYABORT;
398   }
399
400   if ($4->integer > olsr_cnf->maxplen) {
401     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
402     YYABORT;
403   }
404
405   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
406
407   free($2->string);
408   free($2);
409   free($4);
410 }
411 ;
412
413 iifweight:       TOK_IFWEIGHT TOK_INTEGER
414 {
415   int ifcnt = ifs_in_curr_cfg;
416   struct olsr_if *ifs = olsr_cnf->interfaces;
417
418   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
419
420   while (ifcnt) {
421     ifs->cnf->weight.value = $2->integer;
422     ifs->cnf->weight.fixed = OLSR_TRUE;
423
424     ifs = ifs->next;
425     ifcnt--;
426   }
427
428   free($2);
429 }
430 ;
431
432 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
433 {
434   struct in_addr in;
435   int ifcnt = ifs_in_curr_cfg;
436   struct olsr_if *ifs = olsr_cnf->interfaces;
437
438   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
439
440   if (inet_aton($2->string, &in) == 0) {
441     fprintf(stderr, "isetip4br: Failed converting IP address %s\n", $2->string);
442     YYABORT;
443   }
444
445   while (ifcnt) {
446     ifs->cnf->ipv4_broadcast.v4 = in;
447
448     ifs = ifs->next;
449     ifcnt--;
450   }
451
452   free($2->string);
453   free($2);
454 }
455 ;
456
457 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
458 {
459   int ifcnt = ifs_in_curr_cfg;
460   struct olsr_if *ifs = olsr_cnf->interfaces;
461
462   while (ifcnt) {
463     ifs->cnf->ipv6_addrtype = $2->integer;
464
465     ifs = ifs->next;
466     ifcnt--;
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   if ($2->integer > 127) {
697     fprintf(stderr, "\"DebugLevel\" must be >= 0 and <= 127 (and not %d)\n", $2->integer);
698     YYABORT;
699   }
700   olsr_cnf->debug_level = $2->integer;
701   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
702   free($2);
703 }
704 ;
705
706
707 iipversion:    TOK_IPVERSION TOK_INTEGER
708 {
709   if ($2->integer == 4) {
710     olsr_cnf->ip_version = AF_INET;
711     olsr_cnf->ipsize = sizeof(struct in_addr);
712     olsr_cnf->maxplen = 32;
713   } else if ($2->integer == 6) {
714     olsr_cnf->ip_version = AF_INET6;
715     olsr_cnf->ipsize = sizeof(struct in6_addr);
716     olsr_cnf->maxplen = 128;
717   } else {
718     fprintf(stderr, "IPversion must be 4 or 6!\n");
719     YYABORT;
720   }
721
722   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
723   free($2);
724 }
725 ;
726
727 fibmetric:    TOK_FIBMETRIC TOK_STRING
728 {
729   PARSER_DEBUG_PRINTF("FIBMetric: %d\n", $2->string);
730   if (strcmp($2->string, CFG_FIBM_FLAT) == 0) {
731       olsr_cnf->fib_metric = FIBM_FLAT;
732   } else if (strcmp($2->string, CFG_FIBM_CORRECT) == 0) {
733       olsr_cnf->fib_metric = FIBM_CORRECT;
734   } else if (strcmp($2->string, CFG_FIBM_APPROX) == 0) {
735       olsr_cnf->fib_metric = FIBM_APPROX;
736   } else {
737     fprintf(stderr, "FIBMetric must be \"%s\", \"%s\", or \"%s\"!\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX);
738     YYABORT;
739   }
740   free($1);
741   free($2->string);
742   free($2);
743 }
744 ;
745
746 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
747 {
748   union olsr_ip_addr ipaddr, netmask;
749
750   PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
751
752   if (olsr_cnf->ip_version != AF_INET) {
753     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4\n");
754     YYABORT;
755   }
756
757   if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
758     fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
759     YYABORT;
760   }
761   if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
762     fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
763     YYABORT;
764   }
765
766   /* check that the given IP address is actually a network address */
767   if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
768     fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
769     YYABORT;
770   }
771
772   /* Queue */
773   ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
774
775   free($1->string);
776   free($1);
777   free($2->string);
778   free($2);
779 }
780         |       TOK_IP4_ADDR TOK_SLASH TOK_INTEGER
781 {
782   union olsr_ip_addr ipaddr, netmask;
783
784   PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
785
786   if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
787     fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
788     YYABORT;
789   }
790   if ($3->integer > olsr_cnf->maxplen) {
791     fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
792     YYABORT;
793   }
794
795   /* check that the given IP address is actually a network address */
796   olsr_prefix_to_netmask(&netmask, $3->integer);
797   if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
798     fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
799     YYABORT;
800   }
801
802   /* Queue */
803   ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
804
805   free($1->string);
806   free($1);
807   free($3);
808 }
809 ;
810
811 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
812 {
813   if (add_ipv6_addr($1, $2)) {
814     YYABORT;
815   }
816 }
817         |       TOK_IP6_ADDR TOK_SLASH TOK_INTEGER
818 {
819   if (add_ipv6_addr($1, $3)) {
820     YYABORT;
821   }
822 }
823 ;
824
825 ifstart: TOK_INTERFACE
826 {
827   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
828   ifs_in_curr_cfg = 0;
829 }
830 ;
831
832 ifnick: TOK_STRING
833 {
834   struct olsr_if *in = malloc(sizeof(*in));
835   
836   if (in == NULL) {
837     fprintf(stderr, "Out of memory(ADD IF)\n");
838     YYABORT;
839   }
840
841   in->cnf = get_default_if_config();
842   if (in->cnf == NULL) {
843     fprintf(stderr, "Out of memory(ADD IFRULE)\n");
844     YYABORT;
845   }
846
847   in->name = $1->string;
848
849   /* Queue */
850   in->next = olsr_cnf->interfaces;
851   olsr_cnf->interfaces = in;
852   ifs_in_curr_cfg++;
853   free($1);
854 }
855 ;
856
857 bnoint: TOK_NOINT TOK_BOOLEAN
858 {
859   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
860   olsr_cnf->allow_no_interfaces = $2->boolean;
861   free($2);
862 }
863 ;
864
865 atos: TOK_TOS TOK_INTEGER
866 {
867   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
868   olsr_cnf->tos = $2->integer;
869   free($2);
870
871 }
872 ;
873
874 arttable: TOK_RTTABLE TOK_INTEGER
875 {
876   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
877   olsr_cnf->rttable = $2->integer;
878   free($2);
879 }
880 ;
881
882 arttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
883 {
884   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
885   olsr_cnf->rttable_default = $2->integer;
886   free($2);
887 }
888 ;
889
890 awillingness: TOK_WILLINGNESS TOK_INTEGER
891 {
892   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
893   olsr_cnf->willingness_auto = OLSR_FALSE;
894   olsr_cnf->willingness = $2->integer;
895   free($2);
896 }
897 ;
898
899 busehyst: TOK_USEHYST TOK_BOOLEAN
900 {
901   olsr_cnf->use_hysteresis = $2->boolean;
902   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
903   free($2);
904 }
905 ;
906
907 fhystscale: TOK_HYSTSCALE TOK_FLOAT
908 {
909   olsr_cnf->hysteresis_param.scaling = $2->floating;
910   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", $2->floating);
911   free($2);
912 }
913 ;
914
915 fhystupper: TOK_HYSTUPPER TOK_FLOAT
916 {
917   olsr_cnf->hysteresis_param.thr_high = $2->floating;
918   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", $2->floating);
919   free($2);
920 }
921 ;
922
923 fhystlower: TOK_HYSTLOWER TOK_FLOAT
924 {
925   olsr_cnf->hysteresis_param.thr_low = $2->floating;
926   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", $2->floating);
927   free($2);
928 }
929 ;
930
931 fpollrate: TOK_POLLRATE TOK_FLOAT
932 {
933   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", $2->floating);
934   if (check_pollrate(&$2->floating) < 0) {
935     YYABORT;
936   }
937   olsr_cnf->pollrate = conv_pollrate_to_microsecs($2->floating);
938   free($2);
939 }
940 ;
941
942 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
943 {
944   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", $2->floating);
945   olsr_cnf->nic_chgs_pollrate = $2->floating;
946   free($2);
947 }
948 ;
949
950 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
951 {
952   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
953   olsr_cnf->tc_redundancy = $2->integer;
954   free($2);
955 }
956 ;
957
958 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
959 {
960   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
961   olsr_cnf->mpr_coverage = $2->integer;
962   free($2);
963 }
964 ;
965
966 alq_level: TOK_LQ_LEVEL TOK_INTEGER
967 {
968   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
969   olsr_cnf->lq_level = $2->integer;
970   free($2);
971 }
972 ;
973
974 alq_fish: TOK_LQ_FISH TOK_INTEGER
975 {
976   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
977   olsr_cnf->lq_fish = $2->integer;
978   free($2);
979 }
980 ;
981
982 alq_dlimit: TOK_LQ_DLIMIT TOK_INTEGER TOK_FLOAT
983 {
984   PARSER_DEBUG_PRINTF("Link quality dijkstra limit %d, %0.2f\n", $2->integer, $3->floating);
985   olsr_cnf->lq_dlimit = $2->integer;
986   olsr_cnf->lq_dinter = $3->floating;
987   free($2);
988 }
989 ;
990
991 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
992 {
993   free($2);
994 }
995 ;
996
997 alq_aging: TOK_LQ_AGING TOK_FLOAT
998 {
999   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", $2->floating);
1000   olsr_cnf->lq_aging = $2->floating;
1001   free($2);
1002 }
1003 ;
1004
1005 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1006 {
1007   olsr_cnf->lq_algorithm = $2->string;
1008   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1009   free($2);
1010 }
1011 ;
1012
1013 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1014 {
1015   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
1016   olsr_cnf->lq_nat_thresh = $2->floating;
1017   free($2);
1018 }
1019 ;
1020
1021 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1022 {
1023   PARSER_DEBUG_PRINTF("Clear screen %s\n", olsr_cnf->clear_screen ? "enabled" : "disabled");
1024   olsr_cnf->clear_screen = $2->boolean;
1025   free($2);
1026 }
1027 ;
1028
1029 plblock: TOK_PLUGIN TOK_STRING
1030 {
1031   struct plugin_entry *pe = malloc(sizeof(*pe));
1032   
1033   if (pe == NULL) {
1034     fprintf(stderr, "Out of memory(ADD PL)\n");
1035     YYABORT;
1036   }
1037
1038   pe->name = $2->string;
1039   pe->params = NULL;
1040   
1041   PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1042
1043   /* Queue */
1044   pe->next = olsr_cnf->plugins;
1045   olsr_cnf->plugins = pe;
1046
1047   free($2);
1048 }
1049 ;
1050
1051 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1052 {
1053   struct plugin_param *pp = malloc(sizeof(*pp));
1054   
1055   if (pp == NULL) {
1056     fprintf(stderr, "Out of memory(ADD PP)\n");
1057     YYABORT;
1058   }
1059   
1060   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1061   
1062   pp->key = $2->string;
1063   pp->value = $3->string;
1064
1065   /* Queue */
1066   pp->next = olsr_cnf->plugins->params;
1067   olsr_cnf->plugins->params = pp;
1068
1069   free($2);
1070   free($3);
1071 }
1072 ;
1073
1074 vcomment:       TOK_COMMENT
1075 {
1076     //PARSER_DEBUG_PRINTF("Comment\n");
1077 }
1078 ;
1079
1080
1081
1082 %%
1083
1084 void yyerror (const char *string)
1085 {
1086   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1087 }