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