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