53015989907bb372f53603ff917141be85da6f5c
[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 #include "../egressTypes.h"
51
52 #include <stddef.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <sys/types.h>
56 #include <sys/socket.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.h>
59 #include <string.h>
60 #include <ctype.h>
61
62 #define PARSER_DEBUG 1
63
64 #if defined PARSER_DEBUG && PARSER_DEBUG
65 #define PARSER_DEBUG_PRINTF(x, args...)   printf(x, ##args)
66 #else
67 #define PARSER_DEBUG_PRINTF(x, args...)   do { } while (0)
68 #endif
69
70 #define SET_IFS_CONF(ifs, ifcnt, field, value) do { \
71         for (; ifcnt>0; ifs=ifs->next, ifcnt--) { \
72     ifs->cnfi->field = (value); \
73     ifs->cnf->field = (value); \
74         } \
75 } while (0)
76
77 #define YYSTYPE struct conf_token *
78
79 void yyerror(const char *);
80 int yylex(void);
81
82 static int ifs_in_curr_cfg = 0;
83
84 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
85
86 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
87 {
88   union olsr_ip_addr addr;
89   int i;
90   struct olsr_if *walker;
91
92 #if defined PARSER_DEBUG && PARSER_DEBUG > 0
93   printf("\tLinkQualityMult %s %0.2f\n",
94          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
95          (double)mult_arg->floating);
96 #endif
97
98   memset(&addr, 0, sizeof(addr));
99
100   if (ip_addr_arg != NULL &&
101      inet_pton(olsr_cnf->ip_version, ip_addr_arg->string, &addr) <= 0) {
102     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
103     return -1;
104   }
105
106   walker = olsr_cnf->interfaces;
107
108   for (i = 0; i < ifs_in_curr_cfg; i++) {
109     struct olsr_lq_mult *mult = malloc(sizeof(*mult));
110     if (mult == NULL) {
111       fprintf(stderr, "Out of memory (LQ multiplier).\n");
112       return -1;
113     }
114
115     mult->addr = addr;
116     mult->value = (uint32_t)(mult_arg->floating * LINK_LOSS_MULTIPLIER);
117
118     mult->next = walker->cnf->lq_mult;
119     walker->cnfi->lq_mult = walker->cnf->lq_mult = mult;
120     walker->cnf->orig_lq_mult_cnt++;
121     walker->cnfi->orig_lq_mult_cnt=walker->cnf->orig_lq_mult_cnt;
122
123     walker = walker->next;
124   }
125
126   if (ip_addr_arg != NULL) {
127     free(ip_addr_arg->string);
128     free(ip_addr_arg);
129   }
130
131   free(mult_arg);
132
133   return 0;
134 }
135
136 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
137 {
138   union olsr_ip_addr ipaddr;
139   PARSER_DEBUG_PRINTF("HNA IPv6 entry: %s/%d\n", ipaddr_arg->string, prefixlen_arg->integer);
140
141   if (olsr_cnf->ip_version != AF_INET6) {
142     fprintf(stderr, "IPv6 addresses can only be used if \"IpVersion\" == 6, skipping HNA6.\n");
143     olsr_startup_sleep(3);
144   }
145         else {
146           if(inet_pton(AF_INET6, ipaddr_arg->string, &ipaddr) <= 0) {
147       fprintf(stderr, "ihna6entry: Failed converting IP address %s\n", ipaddr_arg->string);
148       return 1;
149     }
150
151                 if (prefixlen_arg->integer > 128) {
152                         fprintf(stderr, "ihna6entry: Illegal IPv6 prefix length %d\n", prefixlen_arg->integer);
153                         return 1;
154                 }
155
156                 /* Queue */
157                 ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, prefixlen_arg->integer);
158         }
159   free(ipaddr_arg->string);
160   free(ipaddr_arg);
161   free(prefixlen_arg);
162
163   return 0;
164 }
165
166 %}
167
168 %token TOK_SLASH
169 %token TOK_OPEN
170 %token TOK_CLOSE
171
172 %token TOK_STRING
173 %token TOK_INTEGER
174 %token TOK_FLOAT
175 %token TOK_BOOLEAN
176
177 %token TOK_IPV6TYPE
178
179 %token TOK_DEBUGLEVEL
180 %token TOK_IPVERSION
181 %token TOK_HNA4
182 %token TOK_HNA6
183 %token TOK_PLUGIN
184 %token TOK_INTERFACE_DEFAULTS
185 %token TOK_INTERFACE
186 %token TOK_NOINT
187 %token TOK_TOS
188 %token TOK_OLSRPORT
189 %token TOK_RTPROTO
190 %token TOK_RTTABLE
191 %token TOK_RTTABLE_DEFAULT
192 %token TOK_RTTABLE_TUNNEL
193 %token TOK_RTTABLE_PRIORITY
194 %token TOK_RTTABLE_DEFAULTOLSR_PRIORITY
195 %token TOK_RTTABLE_TUNNEL_PRIORITY
196 %token TOK_RTTABLE_DEFAULT_PRIORITY
197 %token TOK_WILLINGNESS
198 %token TOK_IPCCON
199 %token TOK_FIBMETRIC
200 %token TOK_FIBMETRICDEFAULT
201 %token TOK_USEHYST
202 %token TOK_HYSTSCALE
203 %token TOK_HYSTUPPER
204 %token TOK_HYSTLOWER
205 %token TOK_POLLRATE
206 %token TOK_NICCHGSPOLLRT
207 %token TOK_TCREDUNDANCY
208 %token TOK_MPRCOVERAGE
209 %token TOK_LQ_LEVEL
210 %token TOK_LQ_FISH
211 %token TOK_LQ_AGING
212 %token TOK_LQ_PLUGIN
213 %token TOK_LQ_NAT_THRESH
214 %token TOK_LQ_MULT
215 %token TOK_CLEAR_SCREEN
216 %token TOK_PLPARAM
217 %token TOK_MIN_TC_VTIME
218 %token TOK_LOCK_FILE
219 %token TOK_USE_NIIT
220 %token TOK_SMART_GW
221 %token TOK_SMART_GW_ALWAYS_REMOVE_SERVER_TUNNEL
222 %token TOK_SMART_GW_USE_COUNT
223 %token TOK_SMART_GW_TAKEDOWN_PERCENTAGE
224 %token TOK_SMART_GW_POLICYROUTING_SCRIPT
225 %token TOK_SMART_GW_EGRESS_IFS
226 %token TOK_SMART_GW_EGRESS_FILE
227 %token TOK_SMART_GW_EGRESS_FILE_PERIOD
228 %token TOK_SMART_GW_STATUS_FILE
229 %token TOK_SMART_GW_OFFSET_TABLES
230 %token TOK_SMART_GW_OFFSET_RULES
231 %token TOK_SMART_GW_ALLOW_NAT
232 %token TOK_SMART_GW_PERIOD
233 %token TOK_SMART_GW_STABLECOUNT
234 %token TOK_SMART_GW_THRESH
235 %token TOK_SMART_GW_WEIGHT_EXITLINK_UP
236 %token TOK_SMART_GW_WEIGHT_EXITLINK_DOWN
237 %token TOK_SMART_GW_WEIGHT_ETX
238 %token TOK_SMART_GW_DIVIDER_ETX
239 %token TOK_SMART_GW_UPLINK
240 %token TOK_SMART_GW_UPLINK_NAT
241 %token TOK_SMART_GW_SPEED
242 %token TOK_SMART_GW_PREFIX
243 %token TOK_SRC_IP_ROUTES
244 %token TOK_MAIN_IP
245 %token TOK_SET_IPFORWARD
246
247 %token TOK_HOSTLABEL
248 %token TOK_NETLABEL
249 %token TOK_MAXIPC
250
251 %token TOK_IFMODE
252 %token TOK_IPV4MULTICAST
253 %token TOK_IP4BROADCAST
254 %token TOK_IPV4BROADCAST
255 %token TOK_IPV6MULTICAST
256 %token TOK_IPV4SRC
257 %token TOK_IPV6SRC
258 %token TOK_IFWEIGHT
259 %token TOK_HELLOINT
260 %token TOK_HELLOVAL
261 %token TOK_TCINT
262 %token TOK_TCVAL
263 %token TOK_MIDINT
264 %token TOK_MIDVAL
265 %token TOK_HNAINT
266 %token TOK_HNAVAL
267 %token TOK_AUTODETCHG
268
269 %token TOK_IPV4_ADDR
270 %token TOK_IPV6_ADDR
271 %token TOK_DEFAULT
272 %token TOK_AUTO
273 %token TOK_NONE
274
275 %token TOK_COMMENT
276
277 %%
278
279 conf:
280           | conf block
281           | conf stmt
282 ;
283
284 stmt:       idebug
285           | iipversion
286           | fibmetric
287           | afibmetricdefault
288           | bnoint
289           | atos
290           | aolsrport
291           | irtproto
292           | irttable
293           | irttable_default
294           | irttable_tunnel
295           | irttable_priority
296           | irttable_defaultolsr_priority
297           | irttable_tunnel_priority
298           | irttable_default_priority
299           | awillingness
300           | busehyst
301           | fhystscale
302           | fhystupper
303           | fhystlower
304           | fpollrate
305           | fnicchgspollrt
306           | atcredundancy
307           | amprcoverage
308           | alq_level
309           | alq_plugin
310           | alq_fish
311           | anat_thresh
312           | alq_aging
313           | bclear_screen
314           | vcomment
315           | amin_tc_vtime
316           | alock_file
317           | suse_niit
318           | bsmart_gw
319           | bsmart_gw_always_remove_server_tunnel
320           | ismart_gw_use_count
321           | ismart_gw_takedown_percentage
322           | ssmart_gw_policyrouting_script
323           | ssmart_gw_egress_file
324           | ismart_gw_egress_file_period
325           | ssmart_gw_status_file
326           | ismart_gw_offset_tables
327           | ismart_gw_offset_rules
328           | bsmart_gw_allow_nat
329           | ismart_gw_period
330           | asmart_gw_stablecount
331           | asmart_gw_thresh
332           | asmart_gw_weight_exitlink_up
333           | asmart_gw_weight_exitlink_down
334           | asmart_gw_weight_etx
335           | asmart_gw_divider_etx
336           | ssmart_gw_uplink
337           | bsmart_gw_uplink_nat
338           | ismart_gw_speed
339           | ismart_gw_prefix
340           | bsrc_ip_routes
341           | amain_ip
342           | bset_ipforward
343           | ssgw_egress_ifs
344 ;
345
346 block:      TOK_HNA4 hna4body
347           | TOK_HNA6 hna6body
348           | TOK_IPCCON ipcbody
349           | ifdblock ifdbody
350           | ifblock ifbody
351           | plblock plbody
352 ;
353
354 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
355 ;
356
357 hna4stmts: | hna4stmts hna4stmt
358 ;
359
360 hna4stmt:  vcomment
361          | ihna4entry
362 ;
363
364 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
365 ;
366
367 hna6stmts: | hna6stmts hna6stmt
368 ;
369
370 hna6stmt:  vcomment
371          | ihna6entry
372 ;
373
374 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
375 ;
376
377 ipcstmts: | ipcstmts ipcstmt
378 ;
379
380 ipcstmt:  vcomment
381           | imaxipc
382           | ipchost
383           | ipcnet
384 ;
385
386 ifblock:   ifstart ifnicks
387 ;
388
389 ifnicks:   | ifnicks ifnick
390 ;
391
392 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
393 ;
394
395 ifdbody:     TOK_OPEN ifstmts TOK_CLOSE
396 {
397   struct olsr_if *in = olsr_cnf->interfaces;
398   printf("\nInterface Defaults");
399   /*remove Interface Defaults from Interface list as they are no interface!*/
400   olsr_cnf->interfaces = in->next;
401   ifs_in_curr_cfg=0;
402   /*free interface but keep its config intact?*/
403   free(in->cnfi);
404   free(in);
405
406 }
407 ;
408
409 ifstmts:   | ifstmts ifstmt
410 ;
411
412 ifstmt:      vcomment
413              | iifweight
414              | isetifmode
415              | TOK_IP4BROADCAST isetipv4mc
416              | TOK_IPV4BROADCAST isetipv4mc
417              | TOK_IPV4MULTICAST isetipv4mc
418              | isetipv6mc
419              | isetipv4src
420              | isetipv6src
421              | isethelloint
422              | isethelloval
423              | isettcint
424              | isettcval
425              | isetmidint
426              | isetmidval
427              | isethnaint
428              | isethnaval
429              | isetautodetchg
430              | isetlqmult
431 ;
432
433 plbody:     TOK_OPEN plstmts TOK_CLOSE
434 ;
435
436 plstmts:   | plstmts plstmt
437 ;
438
439 plstmt:     plparam
440           | vcomment
441 ;
442
443 ifdblock: TOK_INTERFACE_DEFAULTS
444 {
445   struct olsr_if *in = malloc(sizeof(*in));
446
447   if (in == NULL) {
448     fprintf(stderr, "Out of memory(ADD IF)\n");
449     YYABORT;
450   }
451
452   in->cnf = get_default_if_config();
453   in->cnfi = get_default_if_config();
454
455   if (in->cnf == NULL || in->cnfi == NULL) {
456     fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
457     if (in->cnf) {
458       free(in->cnf);
459     }
460     if (in->cnfi) {
461       free(in->cnfi);
462     }
463     free(in);
464     YYABORT;
465   }
466
467   //should not need a name any more, as we free it on "}" again
468   //in->name = strdup(interface_defaults_name);
469
470   olsr_cnf->interface_defaults = in->cnf;
471
472   /* Queue */
473   in->next = olsr_cnf->interfaces;
474   olsr_cnf->interfaces = in;
475   ifs_in_curr_cfg=1;
476   
477   fflush(stdout);
478 }
479 ;
480
481 imaxipc: TOK_MAXIPC TOK_INTEGER
482 {
483   olsr_cnf->ipc_connections = $2->integer;
484   free($2);
485 }
486 ;
487
488 ipchost: TOK_HOSTLABEL TOK_IPV4_ADDR
489 {
490   union olsr_ip_addr ipaddr;
491   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
492   
493   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
494     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
495     YYABORT;
496   }
497
498   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
499
500   free($2->string);
501   free($2);
502 }
503 ;
504
505 ipcnet: TOK_NETLABEL TOK_IPV4_ADDR TOK_IPV4_ADDR
506 {
507   union olsr_ip_addr ipaddr, netmask;
508
509   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
510   
511   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
512     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
513     YYABORT;
514   }
515
516   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
517     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
518     YYABORT;
519   }
520
521   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
522
523   free($2->string);
524   free($2);
525   free($3->string);
526   free($3);
527 }
528         |       TOK_NETLABEL TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
529 {
530   union olsr_ip_addr ipaddr;
531
532   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
533   
534   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
535     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
536     YYABORT;
537   }
538
539   if ($4->integer > olsr_cnf->maxplen) {
540     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
541     YYABORT;
542   }
543
544   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
545
546   free($2->string);
547   free($2);
548   free($4);
549 }
550 ;
551
552 iifweight:       TOK_IFWEIGHT TOK_INTEGER
553 {
554   int ifcnt = ifs_in_curr_cfg;
555   struct olsr_if *ifs = olsr_cnf->interfaces;
556
557   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
558
559   while (ifcnt) {
560     ifs->cnf->weight.value = $2->integer;
561     ifs->cnf->weight.fixed = true;
562     ifs->cnfi->weight.value = $2->integer;
563     ifs->cnfi->weight.fixed = true;
564
565     ifs = ifs->next;
566     ifcnt--;
567   }
568
569   free($2);
570 }
571 ;
572
573 isetifmode: TOK_IFMODE TOK_STRING
574 {
575   int ifcnt = ifs_in_curr_cfg;
576   struct olsr_if *ifs = olsr_cnf->interfaces;
577         int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
578
579   PARSER_DEBUG_PRINTF("\tMode: %s\n", $2->string);
580
581         SET_IFS_CONF(ifs, ifcnt, mode, mode);
582         
583   free($2->string);
584   free($2);
585 }
586 ;
587
588 /* called if prepended with TOK_IPV4MULTICAST TOK_IP4BROADCAST TOK_IPV4BROADCAST */
589 isetipv4mc: TOK_IPV4_ADDR
590 {
591   struct in_addr in;
592   int ifcnt = ifs_in_curr_cfg;
593   struct olsr_if *ifs = olsr_cnf->interfaces;
594
595   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $1->string);
596
597   if (inet_pton(AF_INET, $1->string, &in) == 0) {
598     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $1->string);
599     YYABORT;
600   }
601
602         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
603
604   free($1->string);
605   free($1);
606 }
607 ;
608
609 isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
610 {
611   struct in6_addr in6;
612   int ifcnt = ifs_in_curr_cfg;
613   struct olsr_if *ifs = olsr_cnf->interfaces;
614
615   PARSER_DEBUG_PRINTF("\tIPv6 multicast: %s\n", $2->string);
616
617   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
618     fprintf(stderr, "isetipv6mc: Failed converting IP address %s\n", $2->string);
619     YYABORT;
620   }
621
622         SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
623
624   free($2->string);
625   free($2);
626 }
627 ;
628
629 isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
630 {
631   struct in_addr in;
632   int ifcnt = ifs_in_curr_cfg;
633   struct olsr_if *ifs = olsr_cnf->interfaces;
634
635   PARSER_DEBUG_PRINTF("\tIPv4 src: %s\n", $2->string);
636
637   if (inet_pton(AF_INET, $2->string, &in) == 0) {
638     fprintf(stderr, "isetipv4src: Failed converting IP address %s\n", $2->string);
639     YYABORT;
640   }
641
642         SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
643
644   free($2->string);
645   free($2);
646 }
647 ;
648
649 isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
650 {
651   struct olsr_ip_prefix pr6;
652   int ifcnt = ifs_in_curr_cfg;
653   struct olsr_if *ifs = olsr_cnf->interfaces;
654
655   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s/%d\n", $2->string, $4->integer);
656
657   if (inet_pton(AF_INET6, $2->string, &pr6.prefix.v6) <= 0) {
658     fprintf(stderr, "isetipv6src: Failed converting IP address %s\n", $2->string);
659     YYABORT;
660   }
661   if ($4->integer > 128) {
662     fprintf(stderr, "isetipv6src: Illegal Prefixlength %d\n", $4->integer);
663     YYABORT;
664   }
665   pr6.prefix_len = $4->integer;
666
667         SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
668
669   free($2->string);
670   free($2);
671 }
672         | TOK_IPV6SRC TOK_IPV6_ADDR
673 {
674   struct olsr_ip_prefix pr6;
675   int ifcnt = ifs_in_curr_cfg;
676   struct olsr_if *ifs = olsr_cnf->interfaces;
677
678   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s/%d\n", $2->string, 128);
679
680   if (inet_pton(AF_INET6, $2->string, &pr6.prefix.v6) <= 0) {
681     fprintf(stderr, "isetipv6src: Failed converting IP address %s\n", $2->string);
682     YYABORT;
683   }
684   pr6.prefix_len = 128;
685
686   SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
687
688   free($2->string);
689   free($2);
690 }
691 ;
692
693 isethelloint: TOK_HELLOINT TOK_FLOAT
694 {
695   int ifcnt = ifs_in_curr_cfg;
696   struct olsr_if *ifs = olsr_cnf->interfaces;
697
698   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", (double)$2->floating);
699
700         SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
701
702   free($2);
703 }
704 ;
705 isethelloval: TOK_HELLOVAL TOK_FLOAT
706 {
707   int ifcnt = ifs_in_curr_cfg;
708   struct olsr_if *ifs = olsr_cnf->interfaces;
709
710   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", (double)$2->floating);
711
712         SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
713
714   free($2);
715 }
716 ;
717 isettcint: TOK_TCINT TOK_FLOAT
718 {
719   int ifcnt = ifs_in_curr_cfg;
720   struct olsr_if *ifs = olsr_cnf->interfaces;
721
722   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", (double)$2->floating);
723
724         SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
725
726   free($2);
727 }
728 ;
729 isettcval: TOK_TCVAL TOK_FLOAT
730 {
731   int ifcnt = ifs_in_curr_cfg;
732   struct olsr_if *ifs = olsr_cnf->interfaces;
733   
734   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", (double)$2->floating);
735   
736  SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
737
738   free($2);
739 }
740 ;
741 isetmidint: TOK_MIDINT TOK_FLOAT
742 {
743   int ifcnt = ifs_in_curr_cfg;
744   struct olsr_if *ifs = olsr_cnf->interfaces;
745
746
747   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", (double)$2->floating);
748   
749   SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
750
751   free($2);
752 }
753 ;
754 isetmidval: TOK_MIDVAL TOK_FLOAT
755 {
756   int ifcnt = ifs_in_curr_cfg;
757   struct olsr_if *ifs = olsr_cnf->interfaces;
758
759   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", (double)$2->floating);
760   
761   SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
762
763   free($2);
764 }
765 ;
766 isethnaint: TOK_HNAINT TOK_FLOAT
767 {
768   int ifcnt = ifs_in_curr_cfg;
769   struct olsr_if *ifs = olsr_cnf->interfaces;
770   
771   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", (double)$2->floating);
772
773   SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
774
775   free($2);
776 }
777 ;
778 isethnaval: TOK_HNAVAL TOK_FLOAT
779 {
780   int ifcnt = ifs_in_curr_cfg;
781   struct olsr_if *ifs = olsr_cnf->interfaces;
782
783   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", (double)$2->floating);
784
785   SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
786
787   free($2);
788 }
789 ;
790 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
791 {
792   int ifcnt = ifs_in_curr_cfg;
793   struct olsr_if *ifs = olsr_cnf->interfaces;
794
795   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
796
797   SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
798
799   free($2);
800 }
801 ;
802
803 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
804 {
805   if (lq_mult_helper($2, $3) < 0) {
806     YYABORT;
807   }
808 }
809
810           | TOK_LQ_MULT TOK_IPV4_ADDR TOK_FLOAT
811 {
812   if (lq_mult_helper($2, $3) < 0) {
813     YYABORT;
814   }
815 }
816
817           | TOK_LQ_MULT TOK_IPV6_ADDR TOK_FLOAT
818 {
819   if (lq_mult_helper($2, $3) < 0) {
820     YYABORT;
821   }
822 }
823 ;
824
825 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
826 {
827   olsr_cnf->debug_level = $2->integer;
828   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
829   free($2);
830 }
831 ;
832
833
834 iipversion:    TOK_IPVERSION TOK_INTEGER
835 {
836   if ($2->integer == 4) {
837     olsr_cnf->ip_version = AF_INET;
838     olsr_cnf->ipsize = sizeof(struct in_addr);
839     olsr_cnf->maxplen = 32;
840   } else if ($2->integer == 6) {
841     olsr_cnf->ip_version = AF_INET6;
842     olsr_cnf->ipsize = sizeof(struct in6_addr);
843     olsr_cnf->maxplen = 128;
844   } else {
845     fprintf(stderr, "IPversion must be 4 or 6!\n");
846     YYABORT;
847   }
848
849   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
850   free($2);
851 }
852 ;
853
854 fibmetric:    TOK_FIBMETRIC TOK_STRING
855 {
856   int i;
857   PARSER_DEBUG_PRINTF("FIBMetric: %s\n", $2->string);
858   for (i=0; i<FIBM_CNT; i++) {
859     if (strcmp($2->string, FIB_METRIC_TXT[i]) == 0) {
860       olsr_cnf->fib_metric = i;
861       break;
862     }
863   }
864   if (i == FIBM_CNT) {
865     fprintf(stderr, "Bad FIBMetric value: %s\n", $2->string);
866     YYABORT;
867   }
868   free($1);
869   free($2->string);
870   free($2);
871 }
872 ;
873
874 afibmetricdefault: TOK_FIBMETRICDEFAULT TOK_INTEGER
875 {
876   PARSER_DEBUG_PRINTF("FIBMetricDefault: %d\n", $2->integer);
877   olsr_cnf->fib_metric_default = $2->integer;
878   free($2);
879 }
880 ;
881
882 ihna4entry:     TOK_IPV4_ADDR TOK_IPV4_ADDR
883 {
884   union olsr_ip_addr ipaddr, netmask;
885
886   if (olsr_cnf->ip_version == AF_INET6) {
887     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
888     olsr_startup_sleep(3);
889   }
890   else {
891     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
892
893     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
894       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
895       YYABORT;
896     }
897     if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
898       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
899       YYABORT;
900     }
901
902     /* check that the given IP address is actually a network address */
903     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
904       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
905       YYABORT;
906     }
907
908     /* Queue */
909     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
910   }
911   free($1->string);
912   free($1);
913   free($2->string);
914   free($2);
915 }
916         |       TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
917 {
918   union olsr_ip_addr ipaddr, netmask;
919
920   if (olsr_cnf->ip_version == AF_INET6) {
921     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
922     olsr_startup_sleep(3);
923   }
924   else {
925     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
926
927     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
928       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
929       YYABORT;
930     }
931     if ($3->integer > olsr_cnf->maxplen) {
932       fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
933       YYABORT;
934     }
935
936     /* check that the given IP address is actually a network address */
937     olsr_prefix_to_netmask(&netmask, $3->integer);
938     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
939       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
940       YYABORT;
941     }
942
943     /* Queue */
944     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
945   }
946   free($1->string);
947   free($1);
948   free($3);
949 }
950 ;
951
952 ihna6entry:     TOK_IPV6_ADDR TOK_INTEGER
953 {
954   if (add_ipv6_addr($1, $2)) {
955     YYABORT;
956   }
957 }
958         |       TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
959 {
960   if (add_ipv6_addr($1, $3)) {
961     YYABORT;
962   }
963 }
964 ;
965
966 ifstart: TOK_INTERFACE
967 {
968   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
969   ifs_in_curr_cfg = 0;
970 }
971 ;
972
973 ifnick: TOK_STRING
974 {
975   struct olsr_if *in, *last;
976   in = olsr_cnf->interfaces;
977   last = NULL;
978   while (in != NULL) {
979     if (strcmp(in->name, $1->string) == 0) {
980       free ($1->string);
981       break;
982     }
983     last = in;
984     in = in->next;
985   }
986
987   if (in != NULL) {
988     /* remove old interface from list to add it later at the beginning */
989     if (last) {
990       last->next = in->next;
991     }
992     else {
993       olsr_cnf->interfaces = in->next;
994     }
995   }
996   else {
997     in = malloc(sizeof(*in));
998     if (in == NULL) {
999       fprintf(stderr, "Out of memory(ADD IF)\n");
1000       YYABORT;
1001     }
1002     memset(in, 0, sizeof(*in));
1003
1004     in->cnf = malloc(sizeof(*in->cnf));
1005     if (in->cnf == NULL) {
1006       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
1007       free(in);
1008       YYABORT;
1009     }
1010     memset(in->cnf, 0x00, sizeof(*in->cnf));
1011
1012     in->cnfi = malloc(sizeof(*in->cnfi));
1013     if (in->cnfi == NULL) {
1014       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
1015       free (in->cnf);
1016       free(in);
1017       YYABORT;
1018     }
1019     memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
1020     in->cnfi->orig_lq_mult_cnt=0;
1021
1022     in->name = $1->string;
1023   }
1024   /* Queue */
1025   in->next = olsr_cnf->interfaces;
1026   olsr_cnf->interfaces = in;
1027   ifs_in_curr_cfg++;
1028   free($1);
1029 }
1030 ;
1031
1032 bnoint: TOK_NOINT TOK_BOOLEAN
1033 {
1034   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
1035   olsr_cnf->allow_no_interfaces = $2->boolean;
1036   free($2);
1037 }
1038 ;
1039
1040 atos: TOK_TOS TOK_INTEGER
1041 {
1042   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
1043   olsr_cnf->tos = $2->integer;
1044   free($2);
1045
1046 }
1047 ;
1048
1049 aolsrport: TOK_OLSRPORT TOK_INTEGER
1050 {
1051   PARSER_DEBUG_PRINTF("OlsrPort: %d\n", $2->integer);
1052   olsr_cnf->olsrport = $2->integer;
1053   free($2);
1054 }
1055 ;
1056
1057 irtproto: TOK_RTPROTO TOK_INTEGER
1058 {
1059   PARSER_DEBUG_PRINTF("RtProto: %d\n", $2->integer);
1060   olsr_cnf->rt_proto = $2->integer;
1061   free($2);
1062 }
1063 ;
1064
1065 irttable: TOK_RTTABLE TOK_INTEGER
1066 {
1067   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
1068   olsr_cnf->rt_table = $2->integer;
1069   free($2);
1070 }
1071        | TOK_RTTABLE TOK_AUTO
1072 {
1073   PARSER_DEBUG_PRINTF("RtTable: auto\n");
1074   olsr_cnf->rt_table = DEF_RT_AUTO;
1075   free($2);
1076 }
1077 ;
1078
1079 irttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
1080 {
1081   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
1082   olsr_cnf->rt_table_default = $2->integer;
1083   free($2);
1084 }
1085        | TOK_RTTABLE_DEFAULT TOK_AUTO
1086 {
1087   PARSER_DEBUG_PRINTF("RtTableDefault: auto\n");
1088   olsr_cnf->rt_table_default = DEF_RT_AUTO;
1089   free($2);
1090 }
1091 ;
1092
1093 irttable_tunnel: TOK_RTTABLE_TUNNEL TOK_INTEGER
1094 {
1095   PARSER_DEBUG_PRINTF("RtTableTunnel: %d\n", $2->integer);
1096   olsr_cnf->rt_table_tunnel = $2->integer;
1097   free($2);
1098 }
1099        | TOK_RTTABLE_TUNNEL TOK_AUTO
1100 {
1101   PARSER_DEBUG_PRINTF("RtTableTunnel: auto\n");
1102   olsr_cnf->rt_table_tunnel = DEF_RT_AUTO;
1103   free($2);
1104 }
1105 ;
1106
1107 irttable_priority: TOK_RTTABLE_PRIORITY TOK_INTEGER
1108 {
1109   PARSER_DEBUG_PRINTF("RtTablePriority: %d\n", $2->integer);
1110   olsr_cnf->rt_table_pri = $2->integer;
1111   free($2);
1112 }
1113         | TOK_RTTABLE_PRIORITY TOK_AUTO
1114 {
1115   PARSER_DEBUG_PRINTF("RtTablePriority: auto\n");
1116   olsr_cnf->rt_table_pri = DEF_RT_AUTO;
1117   free($2);
1118 }
1119         | TOK_RTTABLE_PRIORITY TOK_NONE
1120 {
1121   PARSER_DEBUG_PRINTF("RtTablePriority: none\n");
1122   olsr_cnf->rt_table_pri = DEF_RT_NONE;
1123   free($2);
1124 }
1125 ;
1126
1127 irttable_default_priority: TOK_RTTABLE_DEFAULT_PRIORITY TOK_INTEGER
1128 {
1129   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: %d\n", $2->integer);
1130   olsr_cnf->rt_table_default_pri = $2->integer;
1131   free($2);
1132 }
1133         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_AUTO
1134 {
1135   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: auto\n");
1136   olsr_cnf->rt_table_default_pri = DEF_RT_AUTO;
1137   free($2);
1138 }
1139         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_NONE
1140 {
1141   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: none\n");
1142   olsr_cnf->rt_table_default_pri = DEF_RT_NONE;
1143   free($2);
1144 }
1145 ;
1146
1147 irttable_tunnel_priority: TOK_RTTABLE_TUNNEL_PRIORITY TOK_INTEGER
1148 {
1149   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: %d\n", $2->integer);
1150   olsr_cnf->rt_table_tunnel_pri = $2->integer;
1151   free($2);
1152 }
1153         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_AUTO
1154 {
1155   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: auto\n");
1156   olsr_cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
1157   free($2);
1158 }
1159         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_NONE
1160 {
1161   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: none\n");
1162   olsr_cnf->rt_table_tunnel_pri = DEF_RT_NONE;
1163   free($2);
1164 }
1165 ;
1166
1167 irttable_defaultolsr_priority: TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_INTEGER
1168 {
1169   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: %d\n", $2->integer);
1170   olsr_cnf->rt_table_defaultolsr_pri = $2->integer;
1171   free($2);
1172 }
1173         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_AUTO
1174 {
1175   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: auto\n");
1176   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
1177   free($2);
1178 }
1179         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_NONE
1180 {
1181   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: none\n");
1182   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_NONE;
1183   free($2);
1184 }
1185 ;
1186
1187 awillingness: TOK_WILLINGNESS TOK_INTEGER
1188 {
1189   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
1190   olsr_cnf->willingness_auto = false;
1191   olsr_cnf->willingness = $2->integer;
1192   free($2);
1193 }
1194 ;
1195
1196 busehyst: TOK_USEHYST TOK_BOOLEAN
1197 {
1198   olsr_cnf->use_hysteresis = $2->boolean;
1199   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
1200   free($2);
1201 }
1202 ;
1203
1204 fhystscale: TOK_HYSTSCALE TOK_FLOAT
1205 {
1206   olsr_cnf->hysteresis_param.scaling = $2->floating;
1207   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", (double)$2->floating);
1208   free($2);
1209 }
1210 ;
1211
1212 fhystupper: TOK_HYSTUPPER TOK_FLOAT
1213 {
1214   olsr_cnf->hysteresis_param.thr_high = $2->floating;
1215   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", (double)$2->floating);
1216   free($2);
1217 }
1218 ;
1219
1220 fhystlower: TOK_HYSTLOWER TOK_FLOAT
1221 {
1222   olsr_cnf->hysteresis_param.thr_low = $2->floating;
1223   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", (double)$2->floating);
1224   free($2);
1225 }
1226 ;
1227
1228 fpollrate: TOK_POLLRATE TOK_FLOAT
1229 {
1230   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", (double)$2->floating);
1231   olsr_cnf->pollrate = $2->floating;
1232   free($2);
1233 }
1234 ;
1235
1236 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
1237 {
1238   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", (double)$2->floating);
1239   olsr_cnf->nic_chgs_pollrate = $2->floating;
1240   free($2);
1241 }
1242 ;
1243
1244 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
1245 {
1246   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
1247   olsr_cnf->tc_redundancy = $2->integer;
1248   free($2);
1249 }
1250 ;
1251
1252 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
1253 {
1254   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
1255   olsr_cnf->mpr_coverage = $2->integer;
1256   free($2);
1257 }
1258 ;
1259
1260 alq_level: TOK_LQ_LEVEL TOK_INTEGER
1261 {
1262   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
1263   olsr_cnf->lq_level = $2->integer;
1264   free($2);
1265 }
1266 ;
1267
1268 alq_fish: TOK_LQ_FISH TOK_INTEGER
1269 {
1270   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
1271   olsr_cnf->lq_fish = $2->integer;
1272   free($2);
1273 }
1274 ;
1275
1276 alq_aging: TOK_LQ_AGING TOK_FLOAT
1277 {
1278   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", (double)$2->floating);
1279   olsr_cnf->lq_aging = $2->floating;
1280   free($2);
1281 }
1282 ;
1283
1284 amin_tc_vtime: TOK_MIN_TC_VTIME TOK_FLOAT
1285 {
1286   PARSER_DEBUG_PRINTF("Minimum TC validity time %f\n", (double)$2->floating);
1287   olsr_cnf->min_tc_vtime = $2->floating;
1288   free($2);
1289 }
1290 ;
1291
1292 alock_file: TOK_LOCK_FILE TOK_STRING
1293 {
1294   PARSER_DEBUG_PRINTF("Lock file %s\n", $2->string);
1295   if (olsr_cnf->lock_file) free(olsr_cnf->lock_file);
1296   olsr_cnf->lock_file = $2->string;
1297   free($2);
1298 }
1299 ;
1300 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1301 {
1302   olsr_cnf->lq_algorithm = $2->string;
1303   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1304   free($2);
1305 }
1306 ;
1307
1308 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1309 {
1310   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", (double)$2->floating);
1311   olsr_cnf->lq_nat_thresh = $2->floating;
1312   free($2);
1313 }
1314 ;
1315
1316 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1317 {
1318   PARSER_DEBUG_PRINTF("Clear screen %s\n", $2->boolean ? "enabled" : "disabled");
1319   olsr_cnf->clear_screen = $2->boolean;
1320   free($2);
1321 }
1322 ;
1323
1324 suse_niit: TOK_USE_NIIT TOK_BOOLEAN
1325 {
1326   PARSER_DEBUG_PRINTF("Use NIIT ip translation: %s\n", $2->boolean ? "enabled" : "disabled");
1327   olsr_cnf->use_niit = $2->boolean;
1328   free($2);
1329 }
1330 ;
1331
1332 bsmart_gw: TOK_SMART_GW TOK_BOOLEAN
1333 {
1334         PARSER_DEBUG_PRINTF("Smart gateway system: %s\n", $2->boolean ? "enabled" : "disabled");
1335         olsr_cnf->smart_gw_active = $2->boolean;
1336         free($2);
1337 }
1338 ;
1339
1340 bsmart_gw_always_remove_server_tunnel: TOK_SMART_GW_ALWAYS_REMOVE_SERVER_TUNNEL TOK_BOOLEAN
1341 {
1342         PARSER_DEBUG_PRINTF("Smart gateway always remove server tunnel: %s\n", $2->boolean ? "enabled" : "disabled");
1343         olsr_cnf->smart_gw_always_remove_server_tunnel = $2->boolean;
1344         free($2);
1345 }
1346 ;
1347
1348 ismart_gw_use_count: TOK_SMART_GW_USE_COUNT TOK_INTEGER
1349 {
1350   PARSER_DEBUG_PRINTF("Smart gateway use count: %d\n", $2->integer);
1351   olsr_cnf->smart_gw_use_count = $2->integer;
1352   free($2);
1353 }
1354 ;
1355
1356 ismart_gw_takedown_percentage: TOK_SMART_GW_TAKEDOWN_PERCENTAGE TOK_INTEGER
1357 {
1358   PARSER_DEBUG_PRINTF("Smart gateway takedown percentage: %d\n", $2->integer);
1359   olsr_cnf->smart_gw_takedown_percentage = $2->integer;
1360   free($2);
1361 }
1362 ;
1363
1364 ssmart_gw_policyrouting_script: TOK_SMART_GW_POLICYROUTING_SCRIPT TOK_STRING
1365 {
1366   PARSER_DEBUG_PRINTF("Smart gateway policy routing script: %s\n", $2->string);
1367   olsr_cnf->smart_gw_policyrouting_script = $2->string;
1368   free($2);
1369 }
1370 ;
1371
1372 ssgw_egress_ifs:   TOK_SMART_GW_EGRESS_IFS sgw_egress_ifs
1373 ;
1374
1375 sgw_egress_ifs:   | sgw_egress_ifs sgw_egress_if
1376 ;
1377
1378 sgw_egress_if: TOK_STRING
1379 {
1380   struct sgw_egress_if *in, *previous, *last;
1381   char * str = $1->string;
1382   char *end;
1383
1384   /* Trim leading space */
1385   while(isspace(*str)) {
1386     str++;
1387   }
1388
1389   /* Trim trailing space */
1390   end = &str[strlen(str) - 1];
1391   while((end > str) && isspace(*end)) {
1392     end--;
1393   }
1394
1395   /* Write new null terminator */
1396   end[1] = '\0';
1397
1398   if(*str == '\0') {
1399     PARSER_DEBUG_PRINTF("Smart gateway egress interface: <empty> (skipped)\n");
1400   } else {
1401     PARSER_DEBUG_PRINTF("Smart gateway egress interface: %s\n", str);
1402
1403     in = olsr_cnf->smart_gw_egress_interfaces;
1404     previous = NULL;
1405     while (in != NULL) {
1406       if (strcmp(in->name, str) == 0) {
1407         free ($1->string);
1408         break;
1409       }
1410       previous = in;
1411       in = in->next;
1412     }
1413
1414     if (in != NULL) {
1415       /* remove old interface from list to add it later at the end */
1416       if (previous) {
1417         previous->next = in->next;
1418       }
1419       else {
1420         olsr_cnf->smart_gw_egress_interfaces = in->next;
1421       }
1422       in->next = NULL;
1423     }
1424     else {
1425       /* interface in not in the list: create a new entry to add it later at the end */
1426       in = malloc(sizeof(*in));
1427       if (in == NULL) {
1428         fprintf(stderr, "Out of memory(ADD IF)\n");
1429         YYABORT;
1430       }
1431       memset(in, 0, sizeof(*in));
1432
1433       in->name = str;
1434     }
1435
1436     last = olsr_cnf->smart_gw_egress_interfaces;
1437     while (last && last->next) {
1438       last = last->next;
1439     }
1440
1441     /* Add to the end of the list */
1442     if (!last) {
1443       olsr_cnf->smart_gw_egress_interfaces = in;
1444     } else {
1445       last->next = in;
1446     }
1447     free($1);
1448   }
1449 }
1450 ;
1451
1452 ssmart_gw_egress_file: TOK_SMART_GW_EGRESS_FILE TOK_STRING
1453 {
1454   PARSER_DEBUG_PRINTF("Smart gateway egress file: %s\n", $2->string);
1455   olsr_cnf->smart_gw_egress_file = $2->string;
1456   free($2);
1457 }
1458 ;
1459
1460 ismart_gw_egress_file_period: TOK_SMART_GW_EGRESS_FILE_PERIOD TOK_INTEGER
1461 {
1462   PARSER_DEBUG_PRINTF("Smart gateway egress file period: %d\n", $2->integer);
1463   olsr_cnf->smart_gw_egress_file_period = $2->integer;
1464   free($2);
1465 }
1466 ;
1467
1468 ssmart_gw_status_file: TOK_SMART_GW_STATUS_FILE TOK_STRING
1469 {
1470   PARSER_DEBUG_PRINTF("Smart gateway status file: %s\n", $2->string);
1471   olsr_cnf->smart_gw_status_file = $2->string;
1472   free($2);
1473 }
1474 ;
1475
1476 ismart_gw_offset_tables: TOK_SMART_GW_OFFSET_TABLES TOK_INTEGER
1477 {
1478   PARSER_DEBUG_PRINTF("Smart gateway tables offset: %d\n", $2->integer);
1479   olsr_cnf->smart_gw_offset_tables = $2->integer;
1480   free($2);
1481 }
1482 ;
1483
1484 ismart_gw_offset_rules: TOK_SMART_GW_OFFSET_RULES TOK_INTEGER
1485 {
1486   PARSER_DEBUG_PRINTF("Smart gateway rules offset: %d\n", $2->integer);
1487   olsr_cnf->smart_gw_offset_rules = $2->integer;
1488   free($2);
1489 }
1490 ;
1491
1492 bsmart_gw_allow_nat: TOK_SMART_GW_ALLOW_NAT TOK_BOOLEAN
1493 {
1494         PARSER_DEBUG_PRINTF("Smart gateway allow client nat: %s\n", $2->boolean ? "yes" : "no");
1495         olsr_cnf->smart_gw_allow_nat = $2->boolean;
1496         free($2);
1497 }
1498 ;
1499
1500 ismart_gw_period: TOK_SMART_GW_PERIOD TOK_INTEGER
1501 {
1502   PARSER_DEBUG_PRINTF("Smart gateway period: %d\n", $2->integer);
1503   olsr_cnf->smart_gw_period = $2->integer;
1504   free($2);
1505 }
1506 ;
1507
1508 asmart_gw_stablecount: TOK_SMART_GW_STABLECOUNT TOK_INTEGER
1509 {
1510   PARSER_DEBUG_PRINTF("Smart gateway stablecount: %d\n", $2->integer);
1511   olsr_cnf->smart_gw_stablecount = $2->integer;
1512   free($2);
1513 }
1514 ;
1515
1516 asmart_gw_thresh: TOK_SMART_GW_THRESH TOK_INTEGER
1517 {
1518   PARSER_DEBUG_PRINTF("Smart gateway threshold: %d\n", $2->integer);
1519   olsr_cnf->smart_gw_thresh = $2->integer;
1520   free($2);
1521 }
1522 ;
1523
1524 asmart_gw_weight_exitlink_up: TOK_SMART_GW_WEIGHT_EXITLINK_UP TOK_INTEGER
1525 {
1526   PARSER_DEBUG_PRINTF("Smart gateway exitlink uplink weight: %d\n", $2->integer);
1527   olsr_cnf->smart_gw_weight_exitlink_up = $2->integer;
1528   free($2);
1529 }
1530 ;
1531
1532 asmart_gw_weight_exitlink_down: TOK_SMART_GW_WEIGHT_EXITLINK_DOWN TOK_INTEGER
1533 {
1534   PARSER_DEBUG_PRINTF("Smart gateway exitlink downlink weight: %d\n", $2->integer);
1535   olsr_cnf->smart_gw_weight_exitlink_down = $2->integer;
1536   free($2);
1537 }
1538 ;
1539
1540 asmart_gw_weight_etx: TOK_SMART_GW_WEIGHT_ETX TOK_INTEGER
1541 {
1542   PARSER_DEBUG_PRINTF("Smart gateway ETX weight: %d\n", $2->integer);
1543   olsr_cnf->smart_gw_weight_etx = $2->integer;
1544   free($2);
1545 }
1546 ;
1547
1548 asmart_gw_divider_etx: TOK_SMART_GW_DIVIDER_ETX TOK_INTEGER
1549 {
1550   PARSER_DEBUG_PRINTF("Smart gateway ETX divider: %d\n", $2->integer);
1551   olsr_cnf->smart_gw_divider_etx = $2->integer;
1552   free($2);
1553 }
1554 ;
1555
1556 ssmart_gw_uplink: TOK_SMART_GW_UPLINK TOK_STRING
1557 {
1558         PARSER_DEBUG_PRINTF("Smart gateway uplink: %s\n", $2->string);
1559         if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_NONE]) == 0) {
1560                 olsr_cnf->smart_gw_type = GW_UPLINK_NONE;
1561         }
1562         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV4]) == 0) {
1563                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV4;
1564         }
1565         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV6]) == 0) {
1566                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV6;
1567         }
1568         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV46]) == 0) {
1569                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV46;
1570         }
1571         else {
1572                 fprintf(stderr, "Bad gateway uplink type: %s\n", $2->string);
1573                 YYABORT;
1574         }
1575         free($2);
1576 }
1577 ;
1578
1579 ismart_gw_speed: TOK_SMART_GW_SPEED TOK_INTEGER TOK_INTEGER
1580 {
1581         PARSER_DEBUG_PRINTF("Smart gateway speed: %u uplink/%u downlink kbit/s\n", $2->integer, $3->integer);
1582         olsr_cnf->smart_gw_uplink = $2->integer;
1583         olsr_cnf->smart_gw_downlink = $3->integer;
1584         free($2);
1585         free($3);
1586 }
1587 ;
1588
1589 bsmart_gw_uplink_nat: TOK_SMART_GW_UPLINK_NAT TOK_BOOLEAN
1590 {
1591         PARSER_DEBUG_PRINTF("Smart gateway uplink nat: %s\n", $2->boolean ? "yes" : "no");
1592         olsr_cnf->smart_gw_uplink_nat = $2->boolean;
1593         free($2);
1594 }
1595 ;
1596
1597 ismart_gw_prefix: TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_INTEGER
1598 {
1599   PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $3->integer);
1600         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1601           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1602     YYABORT;
1603   }
1604         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$3->integer;
1605         
1606         free($2);
1607         free($3);
1608 }
1609         |       TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
1610 {
1611         PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $4->integer);
1612         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1613           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1614     YYABORT;
1615   }
1616         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$4->integer;
1617         
1618         free($2);
1619         free($4);
1620 }
1621 ;
1622
1623 bsrc_ip_routes: TOK_SRC_IP_ROUTES TOK_BOOLEAN
1624 {
1625         PARSER_DEBUG_PRINTF("Use originator for routes src-ip: %s\n", $2->boolean ? "yes" : "no");
1626         if (olsr_cnf->ip_version != AF_INET) {
1627           fprintf(stderr, "Source ip routes not possible with IPV6\n");
1628           YYABORT;
1629         }
1630         else olsr_cnf->use_src_ip_routes = $2->boolean;
1631         free($2);
1632 }
1633 ;
1634
1635 amain_ip: TOK_MAIN_IP TOK_IPV4_ADDR
1636 {
1637   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1638   
1639   if (olsr_cnf->ip_version != AF_INET
1640       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1641     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1642     YYABORT;
1643   }
1644   else olsr_cnf->unicast_src_ip = olsr_cnf->main_addr;
1645   free($2);
1646 }
1647         |       TOK_MAIN_IP TOK_IPV6_ADDR
1648 {
1649   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1650   
1651   if (olsr_cnf->ip_version != AF_INET6
1652       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1653     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1654     YYABORT;
1655   }
1656   free($2);
1657 }
1658 ;
1659
1660 bset_ipforward: TOK_SET_IPFORWARD TOK_BOOLEAN
1661 {
1662   PARSER_DEBUG_PRINTF("Set IP-Forward procfile variable: %s\n", $2->boolean ? "yes" : "no");
1663   olsr_cnf->set_ip_forward = $2->boolean;
1664   free($2);
1665 }
1666 ;
1667
1668
1669 plblock: TOK_PLUGIN TOK_STRING
1670 {
1671   struct plugin_entry *pe, *last;
1672   
1673   pe = olsr_cnf->plugins;
1674   last = NULL;
1675   while (pe != NULL) {
1676     if (strcmp(pe->name, $2->string) == 0) {
1677       free ($2->string);
1678       break;
1679     }
1680     last = pe;
1681     pe = pe->next;
1682   }
1683
1684   if (pe != NULL) {
1685     /* remove old plugin from list to add it later at the beginning */
1686     if (last) {
1687       last->next = pe->next;
1688     }
1689     else {
1690       olsr_cnf->plugins = pe->next;
1691     }
1692   }
1693   else {
1694     pe = malloc(sizeof(*pe));
1695
1696     if (pe == NULL) {
1697       fprintf(stderr, "Out of memory(ADD PL)\n");
1698       YYABORT;
1699     }
1700
1701     pe->name = $2->string;
1702     pe->params = NULL;
1703
1704     PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1705   }
1706   
1707   /* Queue */
1708   pe->next = olsr_cnf->plugins;
1709   olsr_cnf->plugins = pe;
1710
1711   free($2);
1712 }
1713 ;
1714
1715 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1716 {
1717   struct plugin_param *pp = malloc(sizeof(*pp));
1718   
1719   if (pp == NULL) {
1720     fprintf(stderr, "Out of memory(ADD PP)\n");
1721     YYABORT;
1722   }
1723   
1724   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1725   
1726   pp->key = $2->string;
1727   pp->value = $3->string;
1728
1729   /* Queue */
1730   pp->next = olsr_cnf->plugins->params;
1731   olsr_cnf->plugins->params = pp;
1732
1733   free($2);
1734   free($3);
1735 }
1736 ;
1737
1738 vcomment:       TOK_COMMENT
1739 {
1740     //PARSER_DEBUG_PRINTF("Comment\n");
1741 }
1742 ;
1743
1744
1745
1746 %%
1747
1748 void yyerror (const char *string)
1749 {
1750   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1751 }