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