e084baac4d7b0b4ff89d508c048944e72d9b3f74
[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, ...)   printf(x, ##args)
64 #else
65 #define PARSER_DEBUG_PRINTF(x, ...)   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
216 %token TOK_HOSTLABEL
217 %token TOK_NETLABEL
218 %token TOK_MAXIPC
219
220 %token TOK_IFMODE
221 %token TOK_IPV4BROADCAST
222 %token TOK_IPV4MULTICAST
223 %token TOK_IPV6MULTICAST
224 %token TOK_IPV4SRC
225 %token TOK_IPV6SRC
226 %token TOK_IFWEIGHT
227 %token TOK_HELLOINT
228 %token TOK_HELLOVAL
229 %token TOK_TCINT
230 %token TOK_TCVAL
231 %token TOK_MIDINT
232 %token TOK_MIDVAL
233 %token TOK_HNAINT
234 %token TOK_HNAVAL
235 %token TOK_AUTODETCHG
236
237 %token TOK_IPV4_ADDR
238 %token TOK_IPV6_ADDR
239 %token TOK_DEFAULT
240
241 %token TOK_COMMENT
242
243 %%
244
245 conf:
246           | conf block
247           | conf stmt
248 ;
249
250 stmt:       idebug
251           | iipversion
252           | fibmetric
253           | bnoint
254           | atos
255           | aolsrport
256           | arttable
257           | artproto
258           | arttable_default
259           | awillingness
260           | busehyst
261           | fhystscale
262           | fhystupper
263           | fhystlower
264           | fpollrate
265           | fnicchgspollrt
266           | atcredundancy
267           | amprcoverage
268           | alq_level
269           | alq_plugin
270           | alq_fish
271           | alq_dlimit
272           | anat_thresh
273           | alq_wsize
274           | alq_aging
275           | bclear_screen
276           | vcomment
277           | amin_tc_vtime
278           | alock_file
279 ;
280
281 block:      TOK_HNA4 hna4body
282           | TOK_HNA6 hna6body
283           | TOK_IPCCON ipcbody
284           | ifdblock ifbody
285           | ifblock ifbody
286           | plblock plbody
287 ;
288
289 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
290 ;
291
292 hna4stmts: | hna4stmts hna4stmt
293 ;
294
295 hna4stmt:  vcomment
296          | ihna4entry
297 ;
298
299 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
300 ;
301
302 hna6stmts: | hna6stmts hna6stmt
303 ;
304
305 hna6stmt:  vcomment
306          | ihna6entry
307 ;
308
309 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
310 ;
311
312 ipcstmts: | ipcstmts ipcstmt
313 ;
314
315 ipcstmt:  vcomment
316           | imaxipc
317           | ipchost
318           | ipcnet
319 ;
320
321 ifblock:   ifstart ifnicks
322 ;
323
324 ifnicks:   | ifnicks ifnick
325 ;
326
327 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
328 ;
329
330 ifstmts:   | ifstmts ifstmt
331 ;
332
333 ifstmt:      vcomment
334              | iifweight
335              | isetifmode
336              | isetipv4br
337              | isetipv4mc
338              | isetipv6mc
339              | isetipv4src
340              | isetipv6src
341              | isethelloint
342              | isethelloval
343              | isettcint
344              | isettcval
345              | isetmidint
346              | isetmidval
347              | isethnaint
348              | isethnaval
349              | isetautodetchg
350              | isetlqmult
351 ;
352
353 plbody:     TOK_OPEN plstmts TOK_CLOSE
354 ;
355
356 plstmts:   | plstmts plstmt
357 ;
358
359 plstmt:     plparam
360           | vcomment
361 ;
362
363 ifdblock: TOK_INTERFACE_DEFAULTS
364 {
365   struct olsr_if *in = malloc(sizeof(*in));
366
367   if (in == NULL) {
368     fprintf(stderr, "Out of memory(ADD IF)\n");
369     YYABORT;
370   }
371
372   in->cnf = get_default_if_config();
373   in->cnfi = get_default_if_config();
374
375   if (in->cnf == NULL || in->cnfi == NULL) {
376     fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
377     YYABORT;
378   }
379
380   in->name = strdup(interface_defaults_name);
381
382   olsr_cnf->interface_defaults = in->cnf;
383
384   /* Queue */
385   in->next = olsr_cnf->interfaces;
386   olsr_cnf->interfaces = in;
387   ifs_in_curr_cfg=1;
388 }
389 ;
390
391 imaxipc: TOK_MAXIPC TOK_INTEGER
392 {
393   olsr_cnf->ipc_connections = $2->integer;
394   free($2);
395 }
396 ;
397
398 ipchost: TOK_HOSTLABEL TOK_IPV4_ADDR
399 {
400   union olsr_ip_addr ipaddr;
401   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
402   
403   if (inet_aton($2->string, &ipaddr.v4) == 0) {
404     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
405     YYABORT;
406   }
407
408   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
409
410   free($2->string);
411   free($2);
412 }
413 ;
414
415 ipcnet: TOK_NETLABEL TOK_IPV4_ADDR TOK_IPV4_ADDR
416 {
417   union olsr_ip_addr ipaddr, netmask;
418
419   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
420   
421   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
422     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
423     YYABORT;
424   }
425
426   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
427     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
428     YYABORT;
429   }
430
431   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
432
433   free($2->string);
434   free($2);
435   free($3->string);
436   free($3);
437 }
438         |       TOK_NETLABEL TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
439 {
440   union olsr_ip_addr ipaddr;
441
442   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
443   
444   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
445     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
446     YYABORT;
447   }
448
449   if ($4->integer > olsr_cnf->maxplen) {
450     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
451     YYABORT;
452   }
453
454   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
455
456   free($2->string);
457   free($2);
458   free($4);
459 }
460 ;
461
462 iifweight:       TOK_IFWEIGHT TOK_INTEGER
463 {
464   int ifcnt = ifs_in_curr_cfg;
465   struct olsr_if *ifs = olsr_cnf->interfaces;
466
467   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
468
469   while (ifcnt) {
470     ifs->cnf->weight.value = $2->integer;
471     ifs->cnf->weight.fixed = true;
472     ifs->cnfi->weight.value = $2->integer;
473     ifs->cnfi->weight.fixed = true;
474
475     ifs = ifs->next;
476     ifcnt--;
477   }
478
479   free($2);
480 }
481 ;
482
483 isetifmode: TOK_IFMODE TOK_STRING
484 {
485   int ifcnt = ifs_in_curr_cfg;
486   struct olsr_if *ifs = olsr_cnf->interfaces;
487         int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
488
489   PARSER_DEBUG_PRINTF("\tMode: %d\n", $2->string);
490
491         SET_IFS_CONF(ifs, ifcnt, mode, mode);
492         
493   free($2->string);
494   free($2);
495 }
496 ;
497
498 isetipv4br: TOK_IPV4BROADCAST TOK_IPV4_ADDR
499 {
500   struct in_addr in;
501   int ifcnt = ifs_in_curr_cfg;
502   struct olsr_if *ifs = olsr_cnf->interfaces;
503
504   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
505
506   if (inet_aton($2->string, &in) == 0) {
507     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $2->string);
508     YYABORT;
509   }
510
511         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
512
513   free($2->string);
514   free($2);
515 }
516 ;
517
518 isetipv4mc: TOK_IPV4MULTICAST TOK_IPV4_ADDR
519 {
520   struct in_addr in;
521   int ifcnt = ifs_in_curr_cfg;
522   struct olsr_if *ifs = olsr_cnf->interfaces;
523
524   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
525
526   if (inet_aton($2->string, &in) == 0) {
527     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $2->string);
528     YYABORT;
529   }
530
531         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
532
533   free($2->string);
534   free($2);
535 }
536 ;
537
538 isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
539 {
540   struct in6_addr in6;
541   int ifcnt = ifs_in_curr_cfg;
542   struct olsr_if *ifs = olsr_cnf->interfaces;
543
544   PARSER_DEBUG_PRINTF("\tIPv6 multicast: %s\n", $2->string);
545
546   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
547     fprintf(stderr, "isetipv6mc: Failed converting IP address %s\n", $2->string);
548     YYABORT;
549   }
550
551         SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
552
553   free($2->string);
554   free($2);
555 }
556 ;
557
558 isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
559 {
560   struct in_addr in;
561   int ifcnt = ifs_in_curr_cfg;
562   struct olsr_if *ifs = olsr_cnf->interfaces;
563
564   PARSER_DEBUG_PRINTF("\tIPv4 src: %s\n", $2->string);
565
566   if (inet_aton($2->string, &in) == 0) {
567     fprintf(stderr, "isetipv4src: Failed converting IP address %s\n", $2->string);
568     YYABORT;
569   }
570
571         SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
572
573   free($2->string);
574   free($2);
575 }
576 ;
577
578 isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR
579 {
580   struct olsr_ip_prefix pr6;
581   int ifcnt = ifs_in_curr_cfg;
582   struct olsr_if *ifs = olsr_cnf->interfaces;
583
584   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s\n", $2->string);
585
586   if (olsr_string_to_prefix(AF_INET6, &pr6, $2->string) <= 0) {
587     fprintf(stderr, "isetipv6src: Failed converting IP prefix %s\n", $2->string);
588     YYABORT;
589   }
590
591         SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
592
593   free($2->string);
594   free($2);
595 }
596 ;
597
598 isethelloint: TOK_HELLOINT TOK_FLOAT
599 {
600   int ifcnt = ifs_in_curr_cfg;
601   struct olsr_if *ifs = olsr_cnf->interfaces;
602
603   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", $2->floating);
604
605         SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
606
607   free($2);
608 }
609 ;
610 isethelloval: TOK_HELLOVAL TOK_FLOAT
611 {
612   int ifcnt = ifs_in_curr_cfg;
613   struct olsr_if *ifs = olsr_cnf->interfaces;
614
615   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", $2->floating);
616
617         SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
618
619   free($2);
620 }
621 ;
622 isettcint: TOK_TCINT TOK_FLOAT
623 {
624   int ifcnt = ifs_in_curr_cfg;
625   struct olsr_if *ifs = olsr_cnf->interfaces;
626
627   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", $2->floating);
628
629         SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
630
631   free($2);
632 }
633 ;
634 isettcval: TOK_TCVAL TOK_FLOAT
635 {
636   int ifcnt = ifs_in_curr_cfg;
637   struct olsr_if *ifs = olsr_cnf->interfaces;
638   
639   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", $2->floating);
640   
641  SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
642
643   free($2);
644 }
645 ;
646 isetmidint: TOK_MIDINT TOK_FLOAT
647 {
648   int ifcnt = ifs_in_curr_cfg;
649   struct olsr_if *ifs = olsr_cnf->interfaces;
650
651
652   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", $2->floating);
653   
654   SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
655
656   free($2);
657 }
658 ;
659 isetmidval: TOK_MIDVAL TOK_FLOAT
660 {
661   int ifcnt = ifs_in_curr_cfg;
662   struct olsr_if *ifs = olsr_cnf->interfaces;
663
664   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", $2->floating);
665   
666   SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
667
668   free($2);
669 }
670 ;
671 isethnaint: TOK_HNAINT TOK_FLOAT
672 {
673   int ifcnt = ifs_in_curr_cfg;
674   struct olsr_if *ifs = olsr_cnf->interfaces;
675   
676   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", $2->floating);
677
678   SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
679
680   free($2);
681 }
682 ;
683 isethnaval: TOK_HNAVAL TOK_FLOAT
684 {
685   int ifcnt = ifs_in_curr_cfg;
686   struct olsr_if *ifs = olsr_cnf->interfaces;
687
688   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", $2->floating);
689
690   SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
691
692   free($2);
693 }
694 ;
695 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
696 {
697   int ifcnt = ifs_in_curr_cfg;
698   struct olsr_if *ifs = olsr_cnf->interfaces;
699
700   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
701
702   SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
703
704   free($2);
705 }
706 ;
707
708 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
709 {
710   if (lq_mult_helper($2, $3) < 0) {
711     YYABORT;
712   }
713 }
714
715           | TOK_LQ_MULT TOK_IPV4_ADDR TOK_FLOAT
716 {
717   if (lq_mult_helper($2, $3) < 0) {
718     YYABORT;
719   }
720 }
721
722           | TOK_LQ_MULT TOK_IPV6_ADDR TOK_FLOAT
723 {
724   if (lq_mult_helper($2, $3) < 0) {
725     YYABORT;
726   }
727 }
728 ;
729
730 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
731 {
732   olsr_cnf->debug_level = $2->integer;
733   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
734   free($2);
735 }
736 ;
737
738
739 iipversion:    TOK_IPVERSION TOK_INTEGER
740 {
741   if ($2->integer == 4) {
742     olsr_cnf->ip_version = AF_INET;
743     olsr_cnf->ipsize = sizeof(struct in_addr);
744     olsr_cnf->maxplen = 32;
745   } else if ($2->integer == 6) {
746     olsr_cnf->ip_version = AF_INET6;
747     olsr_cnf->ipsize = sizeof(struct in6_addr);
748     olsr_cnf->maxplen = 128;
749   } else {
750     fprintf(stderr, "IPversion must be 4 or 6!\n");
751     YYABORT;
752   }
753
754   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
755   free($2);
756 }
757 ;
758
759 fibmetric:    TOK_FIBMETRIC TOK_STRING
760 {
761   PARSER_DEBUG_PRINTF("FIBMetric: %d\n", $2->string);
762   if (strcmp($2->string, CFG_FIBM_FLAT) == 0) {
763       olsr_cnf->fib_metric = FIBM_FLAT;
764   } else if (strcmp($2->string, CFG_FIBM_CORRECT) == 0) {
765       olsr_cnf->fib_metric = FIBM_CORRECT;
766   } else if (strcmp($2->string, CFG_FIBM_APPROX) == 0) {
767       olsr_cnf->fib_metric = FIBM_APPROX;
768   } else {
769     fprintf(stderr, "FIBMetric must be \"%s\", \"%s\", or \"%s\"!\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX);
770     YYABORT;
771   }
772   free($1);
773   free($2->string);
774   free($2);
775 }
776 ;
777
778 ihna4entry:     TOK_IPV4_ADDR TOK_IPV4_ADDR
779 {
780   union olsr_ip_addr ipaddr, netmask;
781
782   if (olsr_cnf->ip_version == AF_INET6) {
783     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
784     olsr_startup_sleep(3);
785   }
786   else {
787     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
788
789     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
790       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
791       YYABORT;
792     }
793     if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
794       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
795       YYABORT;
796     }
797
798     /* check that the given IP address is actually a network address */
799     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
800       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
801       YYABORT;
802     }
803
804     /* Queue */
805     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
806   }
807   free($1->string);
808   free($1);
809   free($2->string);
810   free($2);
811 }
812         |       TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
813 {
814   union olsr_ip_addr ipaddr, netmask;
815
816   if (olsr_cnf->ip_version == AF_INET6) {
817     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
818     olsr_startup_sleep(3);
819   }
820   else {
821     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
822
823     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
824       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
825       YYABORT;
826     }
827     if ($3->integer > olsr_cnf->maxplen) {
828       fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
829       YYABORT;
830     }
831
832     /* check that the given IP address is actually a network address */
833     olsr_prefix_to_netmask(&netmask, $3->integer);
834     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
835       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
836       YYABORT;
837     }
838
839     /* Queue */
840     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
841   }
842   free($1->string);
843   free($1);
844   free($3);
845 }
846 ;
847
848 ihna6entry:     TOK_IPV6_ADDR TOK_INTEGER
849 {
850   if (add_ipv6_addr($1, $2)) {
851     YYABORT;
852   }
853 }
854         |       TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
855 {
856   if (add_ipv6_addr($1, $3)) {
857     YYABORT;
858   }
859 }
860 ;
861
862 ifstart: TOK_INTERFACE
863 {
864   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
865   ifs_in_curr_cfg = 0;
866 }
867 ;
868
869 ifnick: TOK_STRING
870 {
871   struct olsr_if *in, *last;
872   in = olsr_cnf->interfaces;
873   last = NULL;
874   while (in != NULL) {
875     if (strcmp(in->name, $1->string) == 0) {
876       free ($1->string);
877       break;
878     }
879     last = in;
880     in = in->next;
881   }
882
883   if (in != NULL) {
884     /* remove old interface from list to add it later at the beginning */
885     if (last) {
886       last->next = in->next;
887     }
888     else {
889       olsr_cnf->interfaces = in->next;
890     }
891   }
892   else {
893     in = malloc(sizeof(*in));
894     if (in == NULL) {
895       fprintf(stderr, "Out of memory(ADD IF)\n");
896       YYABORT;
897     }
898     memset(in, 0, sizeof(*in));
899
900     in->cnf = malloc(sizeof(*in->cnf));
901     if (in->cnf == NULL) {
902       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
903       YYABORT;
904     }
905     memset(in->cnf, 0x00, sizeof(*in->cnf));
906
907     in->cnfi = malloc(sizeof(*in->cnfi));
908     if (in->cnf == NULL) {
909       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
910       YYABORT;
911     }
912     memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
913     in->cnfi->orig_lq_mult_cnt=0;
914
915     in->name = $1->string;
916   }
917   /* Queue */
918   in->next = olsr_cnf->interfaces;
919   olsr_cnf->interfaces = in;
920   ifs_in_curr_cfg++;
921   free($1);
922 }
923 ;
924
925 bnoint: TOK_NOINT TOK_BOOLEAN
926 {
927   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
928   olsr_cnf->allow_no_interfaces = $2->boolean;
929   free($2);
930 }
931 ;
932
933 atos: TOK_TOS TOK_INTEGER
934 {
935   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
936   olsr_cnf->tos = $2->integer;
937   free($2);
938
939 }
940 ;
941
942 aolsrport: TOK_OLSRPORT TOK_INTEGER
943 {
944   PARSER_DEBUG_PRINTF("OlsrPort: %d\n", $2->integer);
945   if ($2->integer>=1000) olsr_cnf->olsrport = $2->integer;
946   else olsr_cnf->olsrport = DEF_OLSRPORT;
947   free($2);
948 }
949 ;
950
951 arttable: TOK_RTTABLE TOK_INTEGER
952 {
953   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
954   olsr_cnf->rttable = $2->integer;
955   free($2);
956 }
957 ;
958
959 artproto: TOK_RTPROTO TOK_INTEGER
960 {
961   PARSER_DEBUG_PRINTF("RtProto: %d\n", $2->integer);
962   olsr_cnf->rtproto = $2->integer;
963   free($2);
964 }
965 ;
966
967 arttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
968 {
969   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
970   olsr_cnf->rttable_default = $2->integer;
971   free($2);
972 }
973 ;
974
975 awillingness: TOK_WILLINGNESS TOK_INTEGER
976 {
977   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
978   olsr_cnf->willingness_auto = false;
979   olsr_cnf->willingness = $2->integer;
980   free($2);
981 }
982 ;
983
984 busehyst: TOK_USEHYST TOK_BOOLEAN
985 {
986   olsr_cnf->use_hysteresis = $2->boolean;
987   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
988   free($2);
989 }
990 ;
991
992 fhystscale: TOK_HYSTSCALE TOK_FLOAT
993 {
994   olsr_cnf->hysteresis_param.scaling = $2->floating;
995   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", $2->floating);
996   free($2);
997 }
998 ;
999
1000 fhystupper: TOK_HYSTUPPER TOK_FLOAT
1001 {
1002   olsr_cnf->hysteresis_param.thr_high = $2->floating;
1003   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", $2->floating);
1004   free($2);
1005 }
1006 ;
1007
1008 fhystlower: TOK_HYSTLOWER TOK_FLOAT
1009 {
1010   olsr_cnf->hysteresis_param.thr_low = $2->floating;
1011   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", $2->floating);
1012   free($2);
1013 }
1014 ;
1015
1016 fpollrate: TOK_POLLRATE TOK_FLOAT
1017 {
1018   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", $2->floating);
1019   olsr_cnf->pollrate = $2->floating;
1020   free($2);
1021 }
1022 ;
1023
1024 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
1025 {
1026   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", $2->floating);
1027   olsr_cnf->nic_chgs_pollrate = $2->floating;
1028   free($2);
1029 }
1030 ;
1031
1032 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
1033 {
1034   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
1035   olsr_cnf->tc_redundancy = $2->integer;
1036   free($2);
1037 }
1038 ;
1039
1040 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
1041 {
1042   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
1043   olsr_cnf->mpr_coverage = $2->integer;
1044   free($2);
1045 }
1046 ;
1047
1048 alq_level: TOK_LQ_LEVEL TOK_INTEGER
1049 {
1050   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
1051   olsr_cnf->lq_level = $2->integer;
1052   free($2);
1053 }
1054 ;
1055
1056 alq_fish: TOK_LQ_FISH TOK_INTEGER
1057 {
1058   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
1059   olsr_cnf->lq_fish = $2->integer;
1060   free($2);
1061 }
1062 ;
1063
1064 alq_dlimit: TOK_LQ_DLIMIT TOK_INTEGER TOK_FLOAT
1065 {
1066   PARSER_DEBUG_PRINTF("Link quality dijkstra limit %d, %0.2f\n", $2->integer, $3->floating);
1067   olsr_cnf->lq_dlimit = $2->integer;
1068   olsr_cnf->lq_dinter = $3->floating;
1069   free($2);
1070 }
1071 ;
1072
1073 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
1074 {
1075   free($2);
1076 }
1077 ;
1078
1079 alq_aging: TOK_LQ_AGING TOK_FLOAT
1080 {
1081   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", $2->floating);
1082   olsr_cnf->lq_aging = $2->floating;
1083   free($2);
1084 }
1085 ;
1086
1087 amin_tc_vtime: TOK_MIN_TC_VTIME TOK_FLOAT
1088 {
1089   PARSER_DEBUG_PRINTF("Minimum TC validity time %f\n", $2->floating);
1090   olsr_cnf->min_tc_vtime = $2->floating;
1091   free($2);
1092 }
1093 ;
1094
1095 alock_file: TOK_LOCK_FILE TOK_STRING
1096 {
1097   PARSER_DEBUG_PRINTF("Lock file %s\n", $2->string);
1098   olsr_cnf->lock_file = $2->string;
1099   free($2);
1100 }
1101 ;
1102 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1103 {
1104   olsr_cnf->lq_algorithm = $2->string;
1105   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1106   free($2);
1107 }
1108 ;
1109
1110 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1111 {
1112   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
1113   olsr_cnf->lq_nat_thresh = $2->floating;
1114   free($2);
1115 }
1116 ;
1117
1118 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1119 {
1120   PARSER_DEBUG_PRINTF("Clear screen %s\n", olsr_cnf->clear_screen ? "enabled" : "disabled");
1121   olsr_cnf->clear_screen = $2->boolean;
1122   free($2);
1123 }
1124 ;
1125
1126 plblock: TOK_PLUGIN TOK_STRING
1127 {
1128   struct plugin_entry *pe, *last;
1129   
1130   pe = olsr_cnf->plugins;
1131   last = NULL;
1132   while (pe != NULL) {
1133     if (strcmp(pe->name, $2->string) == 0) {
1134       free ($2->string);
1135       break;
1136     }
1137     last = pe;
1138     pe = pe->next;
1139   }
1140
1141   if (pe != NULL) {
1142     /* remove old plugin from list to add it later at the beginning */
1143     if (last) {
1144       last->next = pe->next;
1145     }
1146     else {
1147       olsr_cnf->plugins = pe->next;
1148     }
1149   }
1150   else {
1151     pe = malloc(sizeof(*pe));
1152
1153     if (pe == NULL) {
1154       fprintf(stderr, "Out of memory(ADD PL)\n");
1155       YYABORT;
1156     }
1157
1158     pe->name = $2->string;
1159     pe->params = NULL;
1160
1161     PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1162   }
1163   
1164   /* Queue */
1165   pe->next = olsr_cnf->plugins;
1166   olsr_cnf->plugins = pe;
1167
1168   free($2);
1169 }
1170 ;
1171
1172 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1173 {
1174   struct plugin_param *pp = malloc(sizeof(*pp));
1175   
1176   if (pp == NULL) {
1177     fprintf(stderr, "Out of memory(ADD PP)\n");
1178     YYABORT;
1179   }
1180   
1181   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1182   
1183   pp->key = $2->string;
1184   pp->value = $3->string;
1185
1186   /* Queue */
1187   pp->next = olsr_cnf->plugins->params;
1188   olsr_cnf->plugins->params = pp;
1189
1190   free($2);
1191   free($3);
1192 }
1193 ;
1194
1195 vcomment:       TOK_COMMENT
1196 {
1197     //PARSER_DEBUG_PRINTF("Comment\n");
1198 }
1199 ;
1200
1201
1202
1203 %%
1204
1205 void yyerror (const char *string)
1206 {
1207   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1208 }