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