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