25833af2faa10c37b1b63175961a86b9a8114587
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * The olsr.org Optimized Link-State Routing daemon(olsrd)
5  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions 
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright 
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in 
16  *   the documentation and/or other materials provided with the 
17  *   distribution.
18  * * Neither the name of olsr.org, olsrd nor the names of its 
19  *   contributors may be used to endorse or promote products derived 
20  *   from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Visit http://www.olsr.org for more information.
36  *
37  * If you find this software useful feel free to make a donation
38  * to the project. For more information see the website or contact
39  * the copyright holders.
40  *
41  */
42
43
44 #include "olsrd_conf.h"
45 #include "../defs.h"
46 #include "../ipcalc.h"
47 #include "../net_olsr.h"
48 #include "../link_set.h"
49 #include "../olsr.h"
50
51 #include <stddef.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <netinet/in.h>
57 #include <arpa/inet.h>
58 #include <string.h>
59
60 #define PARSER_DEBUG 1
61
62 #if PARSER_DEBUG
63 #define PARSER_DEBUG_PRINTF(x, args...)   printf(x, ##args)
64 #else
65 #define PARSER_DEBUG_PRINTF(x, args...)   do { } while (0)
66 #endif
67
68 #define SET_IFS_CONF(ifs, ifcnt, field, value) do { \
69         for (; ifcnt>0; ifs=ifs->next, ifcnt--) { \
70     ifs->cnfi->field = (value); \
71     ifs->cnf->field = (value); \
72         } \
73 } while (0)
74
75 #define YYSTYPE struct conf_token *
76
77 void yyerror(const char *);
78 int yylex(void);
79
80 static int ifs_in_curr_cfg = 0;
81
82 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
83
84 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
85 {
86   union olsr_ip_addr addr;
87   int i;
88   struct olsr_if *walker;
89
90 #if PARSER_DEBUG > 0
91   printf("\tLinkQualityMult %s %0.2f\n",
92          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
93          mult_arg->floating);
94 #endif
95
96   memset(&addr, 0, sizeof(addr));
97
98   if (ip_addr_arg != NULL &&
99      inet_pton(olsr_cnf->ip_version, ip_addr_arg->string, &addr) <= 0) {
100     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
101     return -1;
102   }
103
104   walker = olsr_cnf->interfaces;
105
106   for (i = 0; i < ifs_in_curr_cfg; i++) {
107     struct olsr_lq_mult *mult = malloc(sizeof(*mult));
108     if (mult == NULL) {
109       fprintf(stderr, "Out of memory (LQ multiplier).\n");
110       return -1;
111     }
112
113     mult->addr = addr;
114     mult->value = (uint32_t)(mult_arg->floating * LINK_LOSS_MULTIPLIER);
115
116     mult->next = walker->cnf->lq_mult;
117     walker->cnfi->lq_mult = walker->cnf->lq_mult = mult;
118     walker->cnf->orig_lq_mult_cnt++;
119     walker->cnfi->orig_lq_mult_cnt=walker->cnf->orig_lq_mult_cnt;
120
121     walker = walker->next;
122   }
123
124   if (ip_addr_arg != NULL) {
125     free(ip_addr_arg->string);
126     free(ip_addr_arg);
127   }
128
129   free(mult_arg);
130
131   return 0;
132 }
133
134 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
135 {
136   union olsr_ip_addr ipaddr;
137   PARSER_DEBUG_PRINTF("HNA IPv6 entry: %s/%d\n", ipaddr_arg->string, prefixlen_arg->integer);
138
139   if (olsr_cnf->ip_version != AF_INET6) {
140     fprintf(stderr, "IPv6 addresses can only be used if \"IpVersion\" == 6, skipping HNA6.\n");
141     olsr_startup_sleep(3);
142   }
143         else {
144           if(inet_pton(AF_INET6, ipaddr_arg->string, &ipaddr) <= 0) {
145       fprintf(stderr, "ihna6entry: Failed converting IP address %s\n", ipaddr_arg->string);
146       return 1;
147     }
148
149                 if (prefixlen_arg->integer > 128) {
150                         fprintf(stderr, "ihna6entry: Illegal IPv6 prefix length %d\n", prefixlen_arg->integer);
151                         return 1;
152                 }
153
154                 /* Queue */
155                 ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, prefixlen_arg->integer);
156         }
157   free(ipaddr_arg->string);
158   free(ipaddr_arg);
159   free(prefixlen_arg);
160
161   return 0;
162 }
163
164 %}
165
166 %token TOK_SLASH
167 %token TOK_OPEN
168 %token TOK_CLOSE
169
170 %token TOK_STRING
171 %token TOK_INTEGER
172 %token TOK_FLOAT
173 %token TOK_BOOLEAN
174
175 %token TOK_IPV6TYPE
176
177 %token TOK_DEBUGLEVEL
178 %token TOK_IPVERSION
179 %token TOK_HNA4
180 %token TOK_HNA6
181 %token TOK_PLUGIN
182 %token TOK_INTERFACE_DEFAULTS
183 %token TOK_INTERFACE
184 %token TOK_NOINT
185 %token TOK_TOS
186 %token TOK_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_UPLINK
220 %token TOK_SMART_GW_UPLINK_NAT
221 %token TOK_SMART_GW_SPEED
222 %token TOK_SMART_GW_PREFIX
223 %token TOK_SRC_IP_ROUTES
224 %token TOK_MAIN_IP
225
226 %token TOK_HOSTLABEL
227 %token TOK_NETLABEL
228 %token TOK_MAXIPC
229
230 %token TOK_IFMODE
231 %token TOK_IPV4MULTICAST
232 %token TOK_IP4BROADCAST
233 %token TOK_IPV4BROADCAST
234 %token TOK_IPV6MULTICAST
235 %token TOK_IPV4SRC
236 %token TOK_IPV6SRC
237 %token TOK_IFWEIGHT
238 %token TOK_HELLOINT
239 %token TOK_HELLOVAL
240 %token TOK_TCINT
241 %token TOK_TCVAL
242 %token TOK_MIDINT
243 %token TOK_MIDVAL
244 %token TOK_HNAINT
245 %token TOK_HNAVAL
246 %token TOK_AUTODETCHG
247
248 %token TOK_IPV4_ADDR
249 %token TOK_IPV6_ADDR
250 %token TOK_DEFAULT
251 %token TOK_AUTO
252 %token TOK_NONE
253
254 %token TOK_COMMENT
255
256 %%
257
258 conf:
259           | conf block
260           | conf stmt
261 ;
262
263 stmt:       idebug
264           | iipversion
265           | fibmetric
266           | bnoint
267           | atos
268           | aolsrport
269           | irtproto
270           | irttable
271           | irttable_default
272           | irttable_tunnel
273           | irttable_priority
274           | irttable_defaultolsr_priority
275           | irttable_tunnel_priority
276           | irttable_default_priority
277           | awillingness
278           | busehyst
279           | fhystscale
280           | fhystupper
281           | fhystlower
282           | fpollrate
283           | fnicchgspollrt
284           | atcredundancy
285           | amprcoverage
286           | alq_level
287           | alq_plugin
288           | alq_fish
289           | anat_thresh
290           | alq_aging
291           | bclear_screen
292           | vcomment
293           | amin_tc_vtime
294           | alock_file
295           | suse_niit
296           | bsmart_gw
297           | bsmart_gw_allow_nat
298           | ssmart_gw_uplink
299           | bsmart_gw_uplink_nat
300           | ismart_gw_speed
301           | ismart_gw_prefix
302           | bsrc_ip_routes
303           | amain_ip
304 ;
305
306 block:      TOK_HNA4 hna4body
307           | TOK_HNA6 hna6body
308           | TOK_IPCCON ipcbody
309           | ifdblock ifdbody
310           | ifblock ifbody
311           | plblock plbody
312 ;
313
314 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
315 ;
316
317 hna4stmts: | hna4stmts hna4stmt
318 ;
319
320 hna4stmt:  vcomment
321          | ihna4entry
322 ;
323
324 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
325 ;
326
327 hna6stmts: | hna6stmts hna6stmt
328 ;
329
330 hna6stmt:  vcomment
331          | ihna6entry
332 ;
333
334 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
335 ;
336
337 ipcstmts: | ipcstmts ipcstmt
338 ;
339
340 ipcstmt:  vcomment
341           | imaxipc
342           | ipchost
343           | ipcnet
344 ;
345
346 ifblock:   ifstart ifnicks
347 ;
348
349 ifnicks:   | ifnicks ifnick
350 ;
351
352 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
353 ;
354
355 ifdbody:     TOK_OPEN ifstmts TOK_CLOSE
356 {
357   struct olsr_if *in = olsr_cnf->interfaces;
358   printf("\nInterface Defaults");
359   /*remove Interface Defaults from Interface list as they are no interface!*/
360   olsr_cnf->interfaces = in->next;
361   ifs_in_curr_cfg=0;
362   /*free interface but keep its config intact?*/
363   free(in->cnfi);
364   free(in);
365
366 }
367 ;
368
369 ifstmts:   | ifstmts ifstmt
370 ;
371
372 ifstmt:      vcomment
373              | iifweight
374              | isetifmode
375              | TOK_IP4BROADCAST isetipv4mc
376              | TOK_IPV4BROADCAST isetipv4mc
377              | TOK_IPV4MULTICAST isetipv4mc
378              | isetipv6mc
379              | isetipv4src
380              | isetipv6src
381              | isethelloint
382              | isethelloval
383              | isettcint
384              | isettcval
385              | isetmidint
386              | isetmidval
387              | isethnaint
388              | isethnaval
389              | isetautodetchg
390              | isetlqmult
391 ;
392
393 plbody:     TOK_OPEN plstmts TOK_CLOSE
394 ;
395
396 plstmts:   | plstmts plstmt
397 ;
398
399 plstmt:     plparam
400           | vcomment
401 ;
402
403 ifdblock: TOK_INTERFACE_DEFAULTS
404 {
405   struct olsr_if *in = malloc(sizeof(*in));
406
407   if (in == NULL) {
408     fprintf(stderr, "Out of memory(ADD IF)\n");
409     YYABORT;
410   }
411
412   in->cnf = get_default_if_config();
413   in->cnfi = get_default_if_config();
414
415   if (in->cnf == NULL || in->cnfi == NULL) {
416     fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
417     YYABORT;
418   }
419
420   //should not need a name any more, as we free it on "}" again
421   //in->name = strdup(interface_defaults_name);
422
423   olsr_cnf->interface_defaults = in->cnf;
424
425   /* Queue */
426   in->next = olsr_cnf->interfaces;
427   olsr_cnf->interfaces = in;
428   ifs_in_curr_cfg=1;
429   
430   fflush(stdout);
431 }
432 ;
433
434 imaxipc: TOK_MAXIPC TOK_INTEGER
435 {
436   olsr_cnf->ipc_connections = $2->integer;
437   free($2);
438 }
439 ;
440
441 ipchost: TOK_HOSTLABEL TOK_IPV4_ADDR
442 {
443   union olsr_ip_addr ipaddr;
444   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
445   
446   if (inet_aton($2->string, &ipaddr.v4) == 0) {
447     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
448     YYABORT;
449   }
450
451   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
452
453   free($2->string);
454   free($2);
455 }
456 ;
457
458 ipcnet: TOK_NETLABEL TOK_IPV4_ADDR TOK_IPV4_ADDR
459 {
460   union olsr_ip_addr ipaddr, netmask;
461
462   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
463   
464   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
465     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
466     YYABORT;
467   }
468
469   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
470     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
471     YYABORT;
472   }
473
474   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
475
476   free($2->string);
477   free($2);
478   free($3->string);
479   free($3);
480 }
481         |       TOK_NETLABEL TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
482 {
483   union olsr_ip_addr ipaddr;
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 ($4->integer > olsr_cnf->maxplen) {
493     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
494     YYABORT;
495   }
496
497   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
498
499   free($2->string);
500   free($2);
501   free($4);
502 }
503 ;
504
505 iifweight:       TOK_IFWEIGHT TOK_INTEGER
506 {
507   int ifcnt = ifs_in_curr_cfg;
508   struct olsr_if *ifs = olsr_cnf->interfaces;
509
510   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
511
512   while (ifcnt) {
513     ifs->cnf->weight.value = $2->integer;
514     ifs->cnf->weight.fixed = true;
515     ifs->cnfi->weight.value = $2->integer;
516     ifs->cnfi->weight.fixed = true;
517
518     ifs = ifs->next;
519     ifcnt--;
520   }
521
522   free($2);
523 }
524 ;
525
526 isetifmode: TOK_IFMODE TOK_STRING
527 {
528   int ifcnt = ifs_in_curr_cfg;
529   struct olsr_if *ifs = olsr_cnf->interfaces;
530         int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
531
532   PARSER_DEBUG_PRINTF("\tMode: %s\n", $2->string);
533
534         SET_IFS_CONF(ifs, ifcnt, mode, mode);
535         
536   free($2->string);
537   free($2);
538 }
539 ;
540
541 /* called if prepended with TOK_IPV4MULTICAST TOK_IP4BROADCAST TOK_IPV4BROADCAST */
542 isetipv4mc: TOK_IPV4_ADDR
543 {
544   struct in_addr in;
545   int ifcnt = ifs_in_curr_cfg;
546   struct olsr_if *ifs = olsr_cnf->interfaces;
547
548   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $1->string);
549
550   if (inet_aton($1->string, &in) == 0) {
551     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $1->string);
552     YYABORT;
553   }
554
555         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
556
557   free($1->string);
558   free($1);
559 }
560 ;
561
562 isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
563 {
564   struct in6_addr in6;
565   int ifcnt = ifs_in_curr_cfg;
566   struct olsr_if *ifs = olsr_cnf->interfaces;
567
568   PARSER_DEBUG_PRINTF("\tIPv6 multicast: %s\n", $2->string);
569
570   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
571     fprintf(stderr, "isetipv6mc: Failed converting IP address %s\n", $2->string);
572     YYABORT;
573   }
574
575         SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
576
577   free($2->string);
578   free($2);
579 }
580 ;
581
582 isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
583 {
584   struct in_addr in;
585   int ifcnt = ifs_in_curr_cfg;
586   struct olsr_if *ifs = olsr_cnf->interfaces;
587
588   PARSER_DEBUG_PRINTF("\tIPv4 src: %s\n", $2->string);
589
590   if (inet_aton($2->string, &in) == 0) {
591     fprintf(stderr, "isetipv4src: Failed converting IP address %s\n", $2->string);
592     YYABORT;
593   }
594
595         SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
596
597   free($2->string);
598   free($2);
599 }
600 ;
601
602 isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR
603 {
604   struct olsr_ip_prefix pr6;
605   int ifcnt = ifs_in_curr_cfg;
606   struct olsr_if *ifs = olsr_cnf->interfaces;
607
608   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s\n", $2->string);
609
610   if (olsr_string_to_prefix(AF_INET6, &pr6, $2->string)) {
611     fprintf(stderr, "isetipv6src: Failed converting IP prefix %s\n", $2->string);
612     YYABORT;
613   }
614
615         SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
616
617   free($2->string);
618   free($2);
619 }
620 ;
621
622 isethelloint: TOK_HELLOINT TOK_FLOAT
623 {
624   int ifcnt = ifs_in_curr_cfg;
625   struct olsr_if *ifs = olsr_cnf->interfaces;
626
627   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", $2->floating);
628
629         SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
630
631   free($2);
632 }
633 ;
634 isethelloval: TOK_HELLOVAL TOK_FLOAT
635 {
636   int ifcnt = ifs_in_curr_cfg;
637   struct olsr_if *ifs = olsr_cnf->interfaces;
638
639   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", $2->floating);
640
641         SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
642
643   free($2);
644 }
645 ;
646 isettcint: TOK_TCINT TOK_FLOAT
647 {
648   int ifcnt = ifs_in_curr_cfg;
649   struct olsr_if *ifs = olsr_cnf->interfaces;
650
651   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", $2->floating);
652
653         SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
654
655   free($2);
656 }
657 ;
658 isettcval: TOK_TCVAL TOK_FLOAT
659 {
660   int ifcnt = ifs_in_curr_cfg;
661   struct olsr_if *ifs = olsr_cnf->interfaces;
662   
663   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", $2->floating);
664   
665  SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
666
667   free($2);
668 }
669 ;
670 isetmidint: TOK_MIDINT TOK_FLOAT
671 {
672   int ifcnt = ifs_in_curr_cfg;
673   struct olsr_if *ifs = olsr_cnf->interfaces;
674
675
676   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", $2->floating);
677   
678   SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
679
680   free($2);
681 }
682 ;
683 isetmidval: TOK_MIDVAL TOK_FLOAT
684 {
685   int ifcnt = ifs_in_curr_cfg;
686   struct olsr_if *ifs = olsr_cnf->interfaces;
687
688   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", $2->floating);
689   
690   SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
691
692   free($2);
693 }
694 ;
695 isethnaint: TOK_HNAINT TOK_FLOAT
696 {
697   int ifcnt = ifs_in_curr_cfg;
698   struct olsr_if *ifs = olsr_cnf->interfaces;
699   
700   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", $2->floating);
701
702   SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
703
704   free($2);
705 }
706 ;
707 isethnaval: TOK_HNAVAL TOK_FLOAT
708 {
709   int ifcnt = ifs_in_curr_cfg;
710   struct olsr_if *ifs = olsr_cnf->interfaces;
711
712   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", $2->floating);
713
714   SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
715
716   free($2);
717 }
718 ;
719 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
720 {
721   int ifcnt = ifs_in_curr_cfg;
722   struct olsr_if *ifs = olsr_cnf->interfaces;
723
724   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
725
726   SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
727
728   free($2);
729 }
730 ;
731
732 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
733 {
734   if (lq_mult_helper($2, $3) < 0) {
735     YYABORT;
736   }
737 }
738
739           | TOK_LQ_MULT TOK_IPV4_ADDR TOK_FLOAT
740 {
741   if (lq_mult_helper($2, $3) < 0) {
742     YYABORT;
743   }
744 }
745
746           | TOK_LQ_MULT TOK_IPV6_ADDR TOK_FLOAT
747 {
748   if (lq_mult_helper($2, $3) < 0) {
749     YYABORT;
750   }
751 }
752 ;
753
754 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
755 {
756   olsr_cnf->debug_level = $2->integer;
757   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
758   free($2);
759 }
760 ;
761
762
763 iipversion:    TOK_IPVERSION TOK_INTEGER
764 {
765   if ($2->integer == 4) {
766     olsr_cnf->ip_version = AF_INET;
767     olsr_cnf->ipsize = sizeof(struct in_addr);
768     olsr_cnf->maxplen = 32;
769   } else if ($2->integer == 6) {
770     olsr_cnf->ip_version = AF_INET6;
771     olsr_cnf->ipsize = sizeof(struct in6_addr);
772     olsr_cnf->maxplen = 128;
773   } else {
774     fprintf(stderr, "IPversion must be 4 or 6!\n");
775     YYABORT;
776   }
777
778   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
779   free($2);
780 }
781 ;
782
783 fibmetric:    TOK_FIBMETRIC TOK_STRING
784 {
785   int i;
786   PARSER_DEBUG_PRINTF("FIBMetric: %s\n", $2->string);
787   for (i=0; i<FIBM_CNT; i++) {
788     if (strcmp($2->string, FIB_METRIC_TXT[i]) == 0) {
789       olsr_cnf->fib_metric = i;
790       break;
791     }
792   }
793   if (i == FIBM_CNT) {
794     fprintf(stderr, "Bad FIBMetric value: %s\n", $2->string);
795     YYABORT;
796   }
797   free($1);
798   free($2->string);
799   free($2);
800 }
801 ;
802
803 ihna4entry:     TOK_IPV4_ADDR TOK_IPV4_ADDR
804 {
805   union olsr_ip_addr ipaddr, netmask;
806
807   if (olsr_cnf->ip_version == AF_INET6) {
808     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
809     olsr_startup_sleep(3);
810   }
811   else {
812     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
813
814     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
815       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
816       YYABORT;
817     }
818     if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
819       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
820       YYABORT;
821     }
822
823     /* check that the given IP address is actually a network address */
824     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
825       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
826       YYABORT;
827     }
828
829     /* Queue */
830     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
831   }
832   free($1->string);
833   free($1);
834   free($2->string);
835   free($2);
836 }
837         |       TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
838 {
839   union olsr_ip_addr ipaddr, netmask;
840
841   if (olsr_cnf->ip_version == AF_INET6) {
842     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
843     olsr_startup_sleep(3);
844   }
845   else {
846     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
847
848     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
849       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
850       YYABORT;
851     }
852     if ($3->integer > olsr_cnf->maxplen) {
853       fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
854       YYABORT;
855     }
856
857     /* check that the given IP address is actually a network address */
858     olsr_prefix_to_netmask(&netmask, $3->integer);
859     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
860       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
861       YYABORT;
862     }
863
864     /* Queue */
865     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
866   }
867   free($1->string);
868   free($1);
869   free($3);
870 }
871 ;
872
873 ihna6entry:     TOK_IPV6_ADDR TOK_INTEGER
874 {
875   if (add_ipv6_addr($1, $2)) {
876     YYABORT;
877   }
878 }
879         |       TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
880 {
881   if (add_ipv6_addr($1, $3)) {
882     YYABORT;
883   }
884 }
885 ;
886
887 ifstart: TOK_INTERFACE
888 {
889   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
890   ifs_in_curr_cfg = 0;
891 }
892 ;
893
894 ifnick: TOK_STRING
895 {
896   struct olsr_if *in, *last;
897   in = olsr_cnf->interfaces;
898   last = NULL;
899   while (in != NULL) {
900     if (strcmp(in->name, $1->string) == 0) {
901       free ($1->string);
902       break;
903     }
904     last = in;
905     in = in->next;
906   }
907
908   if (in != NULL) {
909     /* remove old interface from list to add it later at the beginning */
910     if (last) {
911       last->next = in->next;
912     }
913     else {
914       olsr_cnf->interfaces = in->next;
915     }
916   }
917   else {
918     in = malloc(sizeof(*in));
919     if (in == NULL) {
920       fprintf(stderr, "Out of memory(ADD IF)\n");
921       YYABORT;
922     }
923     memset(in, 0, sizeof(*in));
924
925     in->cnf = malloc(sizeof(*in->cnf));
926     if (in->cnf == NULL) {
927       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
928       YYABORT;
929     }
930     memset(in->cnf, 0x00, sizeof(*in->cnf));
931
932     in->cnfi = malloc(sizeof(*in->cnfi));
933     if (in->cnf == NULL) {
934       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
935       YYABORT;
936     }
937     memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
938     in->cnfi->orig_lq_mult_cnt=0;
939
940     in->name = $1->string;
941   }
942   /* Queue */
943   in->next = olsr_cnf->interfaces;
944   olsr_cnf->interfaces = in;
945   ifs_in_curr_cfg++;
946   free($1);
947 }
948 ;
949
950 bnoint: TOK_NOINT TOK_BOOLEAN
951 {
952   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
953   olsr_cnf->allow_no_interfaces = $2->boolean;
954   free($2);
955 }
956 ;
957
958 atos: TOK_TOS TOK_INTEGER
959 {
960   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
961   olsr_cnf->tos = $2->integer;
962   free($2);
963
964 }
965 ;
966
967 aolsrport: TOK_OLSRPORT TOK_INTEGER
968 {
969   PARSER_DEBUG_PRINTF("OlsrPort: %d\n", $2->integer);
970   olsr_cnf->olsrport = $2->integer;
971   free($2);
972 }
973 ;
974
975 irtproto: TOK_RTPROTO TOK_INTEGER
976 {
977   PARSER_DEBUG_PRINTF("RtProto: %d\n", $2->integer);
978   olsr_cnf->rt_proto = $2->integer;
979   free($2);
980 }
981 ;
982
983 irttable: TOK_RTTABLE TOK_INTEGER
984 {
985   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
986   olsr_cnf->rt_table = $2->integer;
987   free($2);
988 }
989        | TOK_RTTABLE TOK_AUTO
990 {
991   PARSER_DEBUG_PRINTF("RtTable: auto\n");
992   olsr_cnf->rt_table = DEF_RT_AUTO;
993   free($2);
994 }
995 ;
996
997 irttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
998 {
999   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
1000   olsr_cnf->rt_table_default = $2->integer;
1001   free($2);
1002 }
1003        | TOK_RTTABLE_DEFAULT TOK_AUTO
1004 {
1005   PARSER_DEBUG_PRINTF("RtTableDefault: auto\n");
1006   olsr_cnf->rt_table_default = DEF_RT_AUTO;
1007   free($2);
1008 }
1009 ;
1010
1011 irttable_tunnel: TOK_RTTABLE_TUNNEL TOK_INTEGER
1012 {
1013   PARSER_DEBUG_PRINTF("RtTableTunnel: %d\n", $2->integer);
1014   olsr_cnf->rt_table_tunnel = $2->integer;
1015   free($2);
1016 }
1017        | TOK_RTTABLE_TUNNEL TOK_AUTO
1018 {
1019   PARSER_DEBUG_PRINTF("RtTableTunnel: auto\n");
1020   olsr_cnf->rt_table_tunnel = DEF_RT_AUTO;
1021   free($2);
1022 }
1023 ;
1024
1025 irttable_priority: TOK_RTTABLE_PRIORITY TOK_INTEGER
1026 {
1027   PARSER_DEBUG_PRINTF("RtTablePriority: %d\n", $2->integer);
1028   olsr_cnf->rt_table_pri = $2->integer;
1029   free($2);
1030 }
1031         | TOK_RTTABLE_PRIORITY TOK_AUTO
1032 {
1033   PARSER_DEBUG_PRINTF("RtTablePriority: auto\n");
1034   olsr_cnf->rt_table_pri = DEF_RT_AUTO;
1035   free($2);
1036 }
1037         | TOK_RTTABLE_PRIORITY TOK_NONE
1038 {
1039   PARSER_DEBUG_PRINTF("RtTablePriority: none\n");
1040   olsr_cnf->rt_table_pri = DEF_RT_NONE;
1041   free($2);
1042 }
1043 ;
1044
1045 irttable_default_priority: TOK_RTTABLE_DEFAULT_PRIORITY TOK_INTEGER
1046 {
1047   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: %d\n", $2->integer);
1048   olsr_cnf->rt_table_default_pri = $2->integer;
1049   free($2);
1050 }
1051         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_AUTO
1052 {
1053   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: auto\n");
1054   olsr_cnf->rt_table_default_pri = DEF_RT_AUTO;
1055   free($2);
1056 }
1057         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_NONE
1058 {
1059   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: none\n");
1060   olsr_cnf->rt_table_default_pri = DEF_RT_NONE;
1061   free($2);
1062 }
1063 ;
1064
1065 irttable_tunnel_priority: TOK_RTTABLE_TUNNEL_PRIORITY TOK_INTEGER
1066 {
1067   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: %d\n", $2->integer);
1068   olsr_cnf->rt_table_tunnel_pri = $2->integer;
1069   free($2);
1070 }
1071         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_AUTO
1072 {
1073   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: auto\n");
1074   olsr_cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
1075   free($2);
1076 }
1077         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_NONE
1078 {
1079   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: none\n");
1080   olsr_cnf->rt_table_tunnel_pri = DEF_RT_NONE;
1081   free($2);
1082 }
1083 ;
1084
1085 irttable_defaultolsr_priority: TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_INTEGER
1086 {
1087   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: %d\n", $2->integer);
1088   olsr_cnf->rt_table_defaultolsr_pri = $2->integer;
1089   free($2);
1090 }
1091         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_AUTO
1092 {
1093   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: auto\n");
1094   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
1095   free($2);
1096 }
1097         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_NONE
1098 {
1099   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: none\n");
1100   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_NONE;
1101   free($2);
1102 }
1103 ;
1104
1105 awillingness: TOK_WILLINGNESS TOK_INTEGER
1106 {
1107   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
1108   olsr_cnf->willingness_auto = false;
1109   olsr_cnf->willingness = $2->integer;
1110   free($2);
1111 }
1112 ;
1113
1114 busehyst: TOK_USEHYST TOK_BOOLEAN
1115 {
1116   olsr_cnf->use_hysteresis = $2->boolean;
1117   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
1118   free($2);
1119 }
1120 ;
1121
1122 fhystscale: TOK_HYSTSCALE TOK_FLOAT
1123 {
1124   olsr_cnf->hysteresis_param.scaling = $2->floating;
1125   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", $2->floating);
1126   free($2);
1127 }
1128 ;
1129
1130 fhystupper: TOK_HYSTUPPER TOK_FLOAT
1131 {
1132   olsr_cnf->hysteresis_param.thr_high = $2->floating;
1133   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", $2->floating);
1134   free($2);
1135 }
1136 ;
1137
1138 fhystlower: TOK_HYSTLOWER TOK_FLOAT
1139 {
1140   olsr_cnf->hysteresis_param.thr_low = $2->floating;
1141   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", $2->floating);
1142   free($2);
1143 }
1144 ;
1145
1146 fpollrate: TOK_POLLRATE TOK_FLOAT
1147 {
1148   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", $2->floating);
1149   olsr_cnf->pollrate = $2->floating;
1150   free($2);
1151 }
1152 ;
1153
1154 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
1155 {
1156   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", $2->floating);
1157   olsr_cnf->nic_chgs_pollrate = $2->floating;
1158   free($2);
1159 }
1160 ;
1161
1162 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
1163 {
1164   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
1165   olsr_cnf->tc_redundancy = $2->integer;
1166   free($2);
1167 }
1168 ;
1169
1170 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
1171 {
1172   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
1173   olsr_cnf->mpr_coverage = $2->integer;
1174   free($2);
1175 }
1176 ;
1177
1178 alq_level: TOK_LQ_LEVEL TOK_INTEGER
1179 {
1180   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
1181   olsr_cnf->lq_level = $2->integer;
1182   free($2);
1183 }
1184 ;
1185
1186 alq_fish: TOK_LQ_FISH TOK_INTEGER
1187 {
1188   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
1189   olsr_cnf->lq_fish = $2->integer;
1190   free($2);
1191 }
1192 ;
1193
1194 alq_aging: TOK_LQ_AGING TOK_FLOAT
1195 {
1196   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", $2->floating);
1197   olsr_cnf->lq_aging = $2->floating;
1198   free($2);
1199 }
1200 ;
1201
1202 amin_tc_vtime: TOK_MIN_TC_VTIME TOK_FLOAT
1203 {
1204   PARSER_DEBUG_PRINTF("Minimum TC validity time %f\n", $2->floating);
1205   olsr_cnf->min_tc_vtime = $2->floating;
1206   free($2);
1207 }
1208 ;
1209
1210 alock_file: TOK_LOCK_FILE TOK_STRING
1211 {
1212   PARSER_DEBUG_PRINTF("Lock file %s\n", $2->string);
1213   olsr_cnf->lock_file = $2->string;
1214   free($2);
1215 }
1216 ;
1217 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1218 {
1219   olsr_cnf->lq_algorithm = $2->string;
1220   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1221   free($2);
1222 }
1223 ;
1224
1225 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1226 {
1227   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
1228   olsr_cnf->lq_nat_thresh = $2->floating;
1229   free($2);
1230 }
1231 ;
1232
1233 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1234 {
1235   PARSER_DEBUG_PRINTF("Clear screen %s\n", $2->boolean ? "enabled" : "disabled");
1236   olsr_cnf->clear_screen = $2->boolean;
1237   free($2);
1238 }
1239 ;
1240
1241 suse_niit: TOK_USE_NIIT TOK_BOOLEAN
1242 {
1243   PARSER_DEBUG_PRINTF("Use NIIT ip translation: %s\n", $2->boolean ? "enabled" : "disabled");
1244   olsr_cnf->use_niit = $2->boolean;
1245   free($2);
1246 }
1247 ;
1248
1249 bsmart_gw: TOK_SMART_GW TOK_BOOLEAN
1250 {
1251         PARSER_DEBUG_PRINTF("Smart gateway system: %s\n", $2->boolean ? "enabled" : "disabled");
1252         olsr_cnf->smart_gw_active = $2->boolean;
1253         free($2);
1254 }
1255 ;
1256
1257 bsmart_gw_allow_nat: TOK_SMART_GW_ALLOW_NAT TOK_BOOLEAN
1258 {
1259         PARSER_DEBUG_PRINTF("Smart gateway allow client nat: %s\n", $2->boolean ? "yes" : "no");
1260         olsr_cnf->smart_gw_allow_nat = $2->boolean;
1261         free($2);
1262 }
1263 ;
1264
1265 ssmart_gw_uplink: TOK_SMART_GW_UPLINK TOK_STRING
1266 {
1267         PARSER_DEBUG_PRINTF("Smart gateway uplink: %s\n", $2->string);
1268         if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_NONE]) == 0) {
1269                 olsr_cnf->smart_gw_type = GW_UPLINK_NONE;
1270         }
1271         if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV4]) == 0) {
1272                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV4;
1273         }
1274         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV6]) == 0) {
1275                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV6;
1276         }
1277         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV46]) == 0) {
1278                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV46;
1279         }
1280         else {
1281                 fprintf(stderr, "Bad gateway uplink type: %s\n", $2->string);
1282                 YYABORT;
1283         }
1284         free($2);
1285 }
1286 ;
1287
1288 ismart_gw_speed: TOK_SMART_GW_SPEED TOK_INTEGER TOK_INTEGER
1289 {
1290         PARSER_DEBUG_PRINTF("Smart gateway speed: %u uplink/%u downlink kbit/s\n", $2->integer, $3->integer);
1291         olsr_cnf->smart_gw_uplink = $2->integer;
1292         olsr_cnf->smart_gw_downlink = $3->integer;
1293         free($2);
1294         free($3);
1295 }
1296 ;
1297
1298 bsmart_gw_uplink_nat: TOK_SMART_GW_UPLINK_NAT TOK_BOOLEAN
1299 {
1300         PARSER_DEBUG_PRINTF("Smart gateway uplink nat: %s\n", $2->boolean ? "yes" : "no");
1301         olsr_cnf->smart_gw_uplink_nat = $2->boolean;
1302         free($2);
1303 }
1304 ;
1305
1306 ismart_gw_prefix: TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_INTEGER
1307 {
1308   PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $3->integer);
1309         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1310           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1311     YYABORT;
1312   }
1313         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$3->integer;
1314         
1315         free($2);
1316         free($3);
1317 }
1318         |       TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
1319 {
1320         PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $4->integer);
1321         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1322           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1323     YYABORT;
1324   }
1325         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$4->integer;
1326         
1327         free($2);
1328         free($4);
1329 }
1330 ;
1331
1332 bsrc_ip_routes: TOK_SRC_IP_ROUTES TOK_BOOLEAN
1333 {
1334         PARSER_DEBUG_PRINTF("Use originator for routes src-ip: %s\n", $2->boolean ? "yes" : "no");
1335         if (olsr_cnf->ip_version != AF_INET) {
1336           fprintf(stderr, "Source ip routes not possible with IPV6\n");
1337           YYABORT;
1338         }
1339         else olsr_cnf->use_src_ip_routes = $2->boolean;
1340         free($2);
1341 }
1342 ;
1343
1344 amain_ip: TOK_MAIN_IP TOK_IPV4_ADDR
1345 {
1346   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1347   
1348   if (olsr_cnf->ip_version != AF_INET
1349       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1350     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1351     YYABORT;
1352   }
1353   else olsr_cnf->unicast_src_ip = olsr_cnf->main_addr;
1354   free($2);
1355 }
1356         |       TOK_MAIN_IP TOK_IPV6_ADDR
1357 {
1358   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1359   
1360   if (olsr_cnf->ip_version != AF_INET6
1361       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1362     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1363     YYABORT;
1364   }
1365   free($2);
1366 }
1367
1368 plblock: TOK_PLUGIN TOK_STRING
1369 {
1370   struct plugin_entry *pe, *last;
1371   
1372   pe = olsr_cnf->plugins;
1373   last = NULL;
1374   while (pe != NULL) {
1375     if (strcmp(pe->name, $2->string) == 0) {
1376       free ($2->string);
1377       break;
1378     }
1379     last = pe;
1380     pe = pe->next;
1381   }
1382
1383   if (pe != NULL) {
1384     /* remove old plugin from list to add it later at the beginning */
1385     if (last) {
1386       last->next = pe->next;
1387     }
1388     else {
1389       olsr_cnf->plugins = pe->next;
1390     }
1391   }
1392   else {
1393     pe = malloc(sizeof(*pe));
1394
1395     if (pe == NULL) {
1396       fprintf(stderr, "Out of memory(ADD PL)\n");
1397       YYABORT;
1398     }
1399
1400     pe->name = $2->string;
1401     pe->params = NULL;
1402
1403     PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1404   }
1405   
1406   /* Queue */
1407   pe->next = olsr_cnf->plugins;
1408   olsr_cnf->plugins = pe;
1409
1410   free($2);
1411 }
1412 ;
1413
1414 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1415 {
1416   struct plugin_param *pp = malloc(sizeof(*pp));
1417   
1418   if (pp == NULL) {
1419     fprintf(stderr, "Out of memory(ADD PP)\n");
1420     YYABORT;
1421   }
1422   
1423   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1424   
1425   pp->key = $2->string;
1426   pp->value = $3->string;
1427
1428   /* Queue */
1429   pp->next = olsr_cnf->plugins->params;
1430   olsr_cnf->plugins->params = pp;
1431
1432   free($2);
1433   free($3);
1434 }
1435 ;
1436
1437 vcomment:       TOK_COMMENT
1438 {
1439     //PARSER_DEBUG_PRINTF("Comment\n");
1440 }
1441 ;
1442
1443
1444
1445 %%
1446
1447 void yyerror (const char *string)
1448 {
1449   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1450 }