6ef6aaf8221ecf40d750b17e9568cfad95ffb5d1
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * OLSR ad-hoc routing table management protocol config parser
5  * Copyright (C) 2004 Andreas T√łnnesen (andreto@olsr.org)
6  *
7  * This file is part of the olsr.org OLSR daemon.
8  *
9  * olsr.org is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * olsr.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with olsr.org; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  * 
23  * 
24  * $Id: oparse.y,v 1.3 2004/10/17 11:52:41 kattemat Exp $
25  *
26  */
27
28
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <string.h>
36
37 #include "olsrd_conf.h"
38
39 #define PARSER_DEBUG 0
40
41 #define YYSTYPE struct conf_token *
42
43 void yyerror(char *);
44 int yylex(void);
45
46 struct if_config_options *
47 get_default_if_config(void);
48
49
50 struct if_config_options *
51 get_default_if_config()
52 {
53   struct if_config_options *io = malloc(sizeof(struct if_config_options));
54   struct in6_addr in6;
55  
56   memset(io, 0, sizeof(struct if_config_options));
57
58   io->ipv6_addrtype = 1;
59
60   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6) < 0)
61     {
62       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_SITE_LOCAL);
63       exit(EXIT_FAILURE);
64     }
65   memcpy(&io->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
66
67   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6) < 0)
68     {
69       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_GLOBAL);
70       exit(EXIT_FAILURE);
71     }
72   memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
73
74
75   io->hello_params.emission_interval = HELLO_INTERVAL;
76   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
77   io->tc_params.emission_interval = TC_INTERVAL;
78   io->tc_params.validity_time = TOP_HOLD_TIME;
79   io->mid_params.emission_interval = MID_INTERVAL;
80   io->mid_params.validity_time = MID_HOLD_TIME;
81   io->hna_params.emission_interval = HNA_INTERVAL;
82   io->hna_params.validity_time = HNA_HOLD_TIME;
83
84   return io;
85
86 }
87
88
89
90
91 %}
92
93 %token TOK_OPEN
94 %token TOK_CLOSE
95 %token TOK_SEMI
96
97 %token TOK_STRING
98 %token TOK_INTEGER
99 %token TOK_FLOAT
100 %token TOK_BOOLEAN
101
102 %token TOK_IP6TYPE
103
104 %token TOK_DEBUGLEVEL
105 %token TOK_IPVERSION
106 %token TOK_HNA4
107 %token TOK_HNA6
108 %token TOK_PLUGIN
109 %token TOK_INTERFACES
110 %token TOK_IFSETUP
111 %token TOK_NOINT
112 %token TOK_TOS
113 %token TOK_WILLINGNESS
114 %token TOK_IPCCON
115 %token TOK_USEHYST
116 %token TOK_HYSTSCALE
117 %token TOK_HYSTUPPER
118 %token TOK_HYSTLOWER
119 %token TOK_POLLRATE
120 %token TOK_TCREDUNDANCY
121 %token TOK_MPRCOVERAGE
122 %token TOK_PLNAME
123 %token TOK_PLPARAM
124
125 %token TOK_IP4BROADCAST
126 %token TOK_IP6ADDRTYPE
127 %token TOK_IP6MULTISITE
128 %token TOK_IP6MULTIGLOBAL
129 %token TOK_HELLOINT
130 %token TOK_HELLOVAL
131 %token TOK_TCINT
132 %token TOK_TCVAL
133 %token TOK_MIDINT
134 %token TOK_MIDVAL
135 %token TOK_HNAINT
136 %token TOK_HNAVAL
137
138 %token TOK_IP4_ADDR
139 %token TOK_IP6_ADDR
140
141 %token TOK_COMMENT
142
143 %%
144
145 conf:
146           | conf block
147           | conf stmt
148 ;
149
150 stmt:       idebug
151           | iipversion
152           | bnoint
153           | atos
154           | awillingness
155           | bipccon
156           | busehyst
157           | fhystscale
158           | fhystupper
159           | fhystlower
160           | fpollrate
161           | atcredundancy
162           | amprcoverage
163           | vcomment
164 ;
165
166 block:      TOK_HNA4 hna4body
167           | TOK_HNA6 hna6body
168           | TOK_INTERFACES ifbody
169           | TOK_PLUGIN plbody
170           | isetblock isetbody
171 ;
172
173 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
174 ;
175
176 hna4stmts: | hna4stmts ihna4entry
177 ;
178
179 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
180 ;
181
182 hna6stmts: | hna6stmts ihna6entry
183 ;
184
185 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
186 ;
187
188 ifstmts:   | ifstmts ifstmt
189 ;
190
191 ifstmt:     ifentry
192           | vcomment
193 ;
194
195 isetbody:   TOK_OPEN isetstmts TOK_CLOSE
196 ;
197
198 isetstmts:   | isetstmts isetstmt
199 ;
200
201 isetstmt:      vcomment
202              | isetip4br
203              | isetip6addrt
204              | isetip6mults
205              | isetip6multg
206              | isethelloint
207              | isethelloval
208              | isettcint
209              | isettcval
210              | isetmidint
211              | isetmidval
212              | isethnaint
213              | isethnaval
214 ;
215
216 plbody:     TOK_OPEN plstmts TOK_CLOSE
217 ;
218
219 plstmts:   | plstmts plstmt
220 ;
221
222 plstmt:     plname
223           | plparam
224           | vcomment
225 ;
226
227
228
229
230 isetblock:    TOK_IFSETUP TOK_STRING
231 {
232   struct if_config_options *io = get_default_if_config();
233   if(io == NULL)
234     {
235       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
236       YYABORT;
237     }
238
239   if(PARSER_DEBUG) printf("Interface setup: \"%s\"\n", $2->string);
240   
241   io->name = $2->string;
242   
243   
244   /* Queue */
245   io->next = cnf->if_options;
246   cnf->if_options = io;
247
248   free($2);
249 }
250 ;
251
252
253 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
254 {
255   struct in_addr in;
256
257   if(PARSER_DEBUG) printf("\tIPv4 broadcast: %s\n", $2->string);
258
259   if(inet_aton($2->string, &in) == 0)
260     {
261       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
262       exit(EXIT_FAILURE);
263     }
264
265   cnf->if_options->ipv4_broadcast.v4 = in.s_addr;
266
267   free($2->string);
268   free($2);
269 }
270 ;
271
272 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
273 {
274   cnf->if_options->ipv6_addrtype = $2->boolean;
275   
276   free($2);
277 }
278 ;
279
280 isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
281 {
282   struct in6_addr in6;
283
284   if(PARSER_DEBUG) printf("\tIPv6 site-local multicast: %s\n", $2->string);
285
286   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
287     {
288       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
289       exit(EXIT_FAILURE);
290     }
291   memcpy(&cnf->if_options->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
292
293
294   free($2->string);
295   free($2);
296 }
297 ;
298
299
300 isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
301 {
302   struct in6_addr in6;
303
304   if(PARSER_DEBUG) printf("\tIPv6 global multicast: %s\n", $2->string);
305
306   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
307     {
308       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
309       exit(EXIT_FAILURE);
310     }
311   memcpy(&cnf->if_options->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
312
313
314   free($2->string);
315   free($2);
316 }
317 ;
318 isethelloint: TOK_HELLOINT TOK_FLOAT
319 {
320     if(PARSER_DEBUG) printf("\tHELLO interval: %0.2f\n", $2->floating);
321     cnf->if_options->hello_params.emission_interval = $2->floating;
322     free($2);
323 }
324 ;
325 isethelloval: TOK_HELLOVAL TOK_FLOAT
326 {
327     if(PARSER_DEBUG) printf("\tHELLO validity: %0.2f\n", $2->floating);
328     cnf->if_options->hello_params.validity_time = $2->floating;
329     free($2);
330 }
331 ;
332 isettcint: TOK_TCINT TOK_FLOAT
333 {
334     if(PARSER_DEBUG) printf("\tTC interval: %0.2f\n", $2->floating);
335     cnf->if_options->tc_params.emission_interval = $2->floating;
336     free($2);
337 }
338 ;
339 isettcval: TOK_TCVAL TOK_FLOAT
340 {
341     if(PARSER_DEBUG) printf("\tTC validity: %0.2f\n", $2->floating);
342     cnf->if_options->tc_params.validity_time = $2->floating;
343     free($2);
344 }
345 ;
346 isetmidint: TOK_MIDINT TOK_FLOAT
347 {
348     if(PARSER_DEBUG) printf("\tMID interval: %0.2f\n", $2->floating);
349     cnf->if_options->mid_params.emission_interval = $2->floating;
350     free($2);
351 }
352 ;
353 isetmidval: TOK_MIDVAL TOK_FLOAT
354 {
355     if(PARSER_DEBUG) printf("\tMID validity: %0.2f\n", $2->floating);
356     cnf->if_options->mid_params.validity_time = $2->floating;
357     free($2);
358 }
359 ;
360 isethnaint: TOK_HNAINT TOK_FLOAT
361 {
362     if(PARSER_DEBUG) printf("\tHNA interval: %0.2f\n", $2->floating);
363     cnf->if_options->hna_params.emission_interval = $2->floating;
364     free($2);
365 }
366 ;
367 isethnaval: TOK_HNAVAL TOK_FLOAT
368 {
369     if(PARSER_DEBUG) printf("\tHNA validity: %0.2f\n", $2->floating);
370     cnf->if_options->hna_params.validity_time = $2->floating;
371     free($2);
372 }
373 ;
374
375
376 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
377 {
378
379   if($2->boolean == 1)
380     {
381       if(PARSER_DEBUG) printf("Debug levl AUTO\n");
382     }
383   else
384     {
385       cnf->debug_level = $2->integer;
386       if(PARSER_DEBUG) printf("Debug level: %d\n", cnf->debug_level);
387     }
388
389   free($2);
390 }
391 ;
392
393
394 iipversion:    TOK_IPVERSION TOK_INTEGER
395 {
396   if(($2->integer != 4) && ($2->integer != 6))
397     {
398       fprintf(stderr, "IPversion must be 4 or 6!\n");
399       YYABORT;
400     }
401   cnf->ip_version = $2->integer;
402   if(PARSER_DEBUG) printf("IpVersion: %d\n", cnf->ip_version);
403   free($2);
404 }
405 ;
406
407
408 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
409 {
410   struct hna4_entry *h = malloc(sizeof(struct hna4_entry));
411   struct in_addr in;
412
413   if(PARSER_DEBUG) printf("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
414
415   if(h == NULL)
416     {
417       fprintf(stderr, "Out of memory(HNA4)\n");
418       YYABORT;
419     }
420
421   if(inet_aton($1->string, &in) == 0)
422     {
423       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
424       exit(EXIT_FAILURE);
425     }
426   h->net = in.s_addr;
427   if(inet_aton($2->string, &in) == 0)
428     {
429       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
430       exit(EXIT_FAILURE);
431     }
432   h->netmask = in.s_addr;
433   /* Queue */
434   h->next = cnf->hna4_entries;
435   cnf->hna4_entries = h;
436
437   free($1->string);
438   free($1);
439   free($2->string);
440   free($2);
441
442 }
443
444 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
445 {
446   struct hna6_entry *h = malloc(sizeof(struct hna6_entry));
447   struct in6_addr in6;
448
449   if(PARSER_DEBUG) printf("HNA IPv6 entry: %s/%d\n", $1->string, $2->integer);
450
451   if(h == NULL)
452     {
453       fprintf(stderr, "Out of memory(HNA6)\n");
454       YYABORT;
455     }
456
457   if(inet_pton(AF_INET6, $1->string, &in6) < 0)
458     {
459       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
460       exit(EXIT_FAILURE);
461     }
462   memcpy(&h->net, &in6, sizeof(struct in6_addr));
463
464   if(($2->integer < 0) || ($2->integer > 128))
465     {
466       fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
467       exit(EXIT_FAILURE);
468     }
469
470   h->prefix_len = $2->integer;
471   /* Queue */
472   h->next = cnf->hna6_entries;
473   cnf->hna6_entries = h;
474
475   free($1->string);
476   free($1);
477   free($2);
478
479 }
480
481 ifentry: TOK_STRING TOK_STRING
482 {
483   struct olsr_if *in = malloc(sizeof(struct olsr_if));
484   
485   if(in == NULL)
486     {
487       fprintf(stderr, "Out of memory(ADD IF)\n");
488       YYABORT;
489     }
490
491   in->name = $1->string;
492   in->config = $2->string;
493
494   if(PARSER_DEBUG) printf("Interface: %s Ruleset: %s\n", $1->string, $2->string);
495
496   /* Queue */
497   in->next = cnf->interfaces;
498   cnf->interfaces = in;
499
500   free($1);
501   free($2);
502 }
503 ;
504
505 bnoint: TOK_NOINT TOK_BOOLEAN
506 {
507   if(PARSER_DEBUG) printf("Noint set to %d\n", $2->boolean);
508   free($2);
509 }
510 ;
511
512 atos: TOK_TOS TOK_INTEGER
513 {
514   if($2->boolean == 1)
515     {
516       if(PARSER_DEBUG) printf("Tos AUTO\n");
517     }
518   else
519     {
520       if(PARSER_DEBUG) printf("TOS: %d\n", $2->integer);
521     }
522   free($2);
523
524 }
525 ;
526
527 awillingness: TOK_WILLINGNESS TOK_INTEGER
528 {
529   if($2->boolean == 1)
530     {
531       if(PARSER_DEBUG) printf("Willingness AUTO\n");
532     }
533   else
534     {
535       if(PARSER_DEBUG) printf("Willingness: %d\n", $2->integer);
536     }
537   free($2);
538
539 }
540 ;
541
542 bipccon: TOK_IPCCON TOK_BOOLEAN
543 {
544   if($2->boolean == 1)
545     {
546       if(PARSER_DEBUG) printf("IPC allowed\n");
547     }
548   else
549     {
550       if(PARSER_DEBUG) printf("IPC blocked\n");
551     }
552   free($2);
553
554 }
555 ;
556
557
558 busehyst: TOK_USEHYST TOK_BOOLEAN
559 {
560   if($2->boolean == 1)
561     {
562       if(PARSER_DEBUG) printf("Hysteresis enabled\n");
563     }
564   else
565     {
566       if(PARSER_DEBUG) printf("Hysteresis disabled\n");
567     }
568   free($2);
569
570 }
571 ;
572
573
574 fhystscale: TOK_HYSTSCALE TOK_FLOAT
575 {
576   cnf->hysteresis_param.scaling = $2->floating;
577   if(PARSER_DEBUG) printf("Hysteresis Scaling: %0.2f\n", $2->floating);
578   free($2);
579 }
580 ;
581
582
583 fhystupper: TOK_HYSTUPPER TOK_FLOAT
584 {
585   cnf->hysteresis_param.thr_high = $2->floating;
586   if(PARSER_DEBUG) printf("Hysteresis UpperThr: %0.2f\n", $2->floating);
587   free($2);
588 }
589 ;
590
591
592 fhystlower: TOK_HYSTLOWER TOK_FLOAT
593 {
594   cnf->hysteresis_param.thr_low = $2->floating;
595   if(PARSER_DEBUG) printf("Hysteresis LowerThr: %0.2f\n", $2->floating);
596   free($2);
597 }
598 ;
599
600 fpollrate: TOK_POLLRATE TOK_FLOAT
601 {
602   if(PARSER_DEBUG) printf("Pollrate %0.2f\n", $2->floating);
603   cnf->pollrate = $2->floating;
604
605   free($2);
606 }
607 ;
608
609
610 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
611 {
612   if($2->boolean == 1)
613     {
614       if(PARSER_DEBUG) printf("TC redundancy AUTO\n");
615     }
616   else
617     {
618       if(PARSER_DEBUG) printf("TC redundancy %d\n", $2->integer);
619       cnf->tc_redundancy = $2->integer;
620     }
621   free($2);
622
623 }
624 ;
625
626 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
627 {
628   if($2->boolean == 1)
629     {
630       if(PARSER_DEBUG) printf("MPR coverage AUTO\n");
631     }
632   else
633     {
634       if(PARSER_DEBUG) printf("MPR coverage %d\n", $2->integer);
635       cnf->mpr_coverage = $2->integer;
636     }
637   free($2);
638 }
639 ;
640
641
642 plname: TOK_PLNAME TOK_STRING
643 {
644   struct plugin_entry *pe = malloc(sizeof(struct plugin_entry));
645   
646   if(pe == NULL)
647     {
648       fprintf(stderr, "Out of memory(ADD PL)\n");
649       YYABORT;
650     }
651
652   pe->name = $2->string;
653   
654   if(PARSER_DEBUG) printf("Plugin: %s\n", $2->string);
655
656   /* Queue */
657   pe->next = cnf->plugins;
658   cnf->plugins = pe;
659
660   free($2);
661 }
662 ;
663
664 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
665 {
666
667     if(PARSER_DEBUG) printf("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
668
669     free($2->string);
670     free($2);
671     free($3->string);
672     free($3);
673 }
674 ;
675
676 vcomment:       TOK_COMMENT
677 {
678     //if(PARSER_DEBUG) printf("Comment\n");
679 }
680 ;
681
682
683
684 %%
685
686 void yyerror (char *string)
687 {
688   fprintf(stderr, "Config line %d: %s\n", current_line, string);
689 }