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