Added sanity check function in config parser
[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.18 2004/11/20 21:42:35 kattemat Exp $
25  *
26  */
27
28
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <string.h>
37
38 #include "olsrd_conf.h"
39
40 #define PARSER_DEBUG 0
41
42 #define YYSTYPE struct conf_token *
43
44 void yyerror(char *);
45 int yylex(void);
46
47
48
49
50
51 %}
52
53 %token TOK_OPEN
54 %token TOK_CLOSE
55 %token TOK_SEMI
56
57 %token TOK_STRING
58 %token TOK_INTEGER
59 %token TOK_FLOAT
60 %token TOK_BOOLEAN
61
62 %token TOK_IP6TYPE
63
64 %token TOK_DEBUGLEVEL
65 %token TOK_IPVERSION
66 %token TOK_HNA4
67 %token TOK_HNA6
68 %token TOK_PLUGIN
69 %token TOK_INTERFACE
70 %token TOK_NOINT
71 %token TOK_TOS
72 %token TOK_WILLINGNESS
73 %token TOK_IPCCON
74 %token TOK_USEHYST
75 %token TOK_HYSTSCALE
76 %token TOK_HYSTUPPER
77 %token TOK_HYSTLOWER
78 %token TOK_POLLRATE
79 %token TOK_TCREDUNDANCY
80 %token TOK_MPRCOVERAGE
81 %token TOK_LQ_LEVEL
82 %token TOK_LQ_WSIZE
83 %token TOK_CLEAR_SCREEN
84 %token TOK_PLNAME
85 %token TOK_PLPARAM
86
87 %token TOK_HOSTLABEL
88 %token TOK_NETLABEL
89 %token TOK_MAXIPC
90
91 %token TOK_IP4BROADCAST
92 %token TOK_IP6ADDRTYPE
93 %token TOK_IP6MULTISITE
94 %token TOK_IP6MULTIGLOBAL
95 %token TOK_HELLOINT
96 %token TOK_HELLOVAL
97 %token TOK_TCINT
98 %token TOK_TCVAL
99 %token TOK_MIDINT
100 %token TOK_MIDVAL
101 %token TOK_HNAINT
102 %token TOK_HNAVAL
103
104 %token TOK_IP4_ADDR
105 %token TOK_IP6_ADDR
106
107 %token TOK_COMMENT
108
109 %%
110
111 conf:
112           | conf block
113           | conf stmt
114 ;
115
116 stmt:       idebug
117           | iipversion
118           | bnoint
119           | atos
120           | awillingness
121           | busehyst
122           | fhystscale
123           | fhystupper
124           | fhystlower
125           | fpollrate
126           | atcredundancy
127           | amprcoverage
128           | alq_level
129           | alq_wsize
130           | bclear_screen
131           | vcomment
132 ;
133
134 block:      TOK_HNA4 hna4body
135           | TOK_HNA6 hna6body
136           | TOK_IPCCON ipcbody
137           | ifblock ifbody
138           | plblock plbody
139 ;
140
141 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
142 ;
143
144 hna4stmts: | hna4stmts hna4stmt
145 ;
146
147 hna4stmt:  vcomment
148          | ihna4entry
149 ;
150
151 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
152 ;
153
154 hna6stmts: | hna6stmts hna6stmt
155 ;
156
157 hna6stmt:  vcomment
158          | ihna6entry
159 ;
160
161 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
162 ;
163
164 ipcstmts: | ipcstmts ipcstmt
165 ;
166
167 ipcstmt:  vcomment
168           | imaxipc
169           | ipchost
170           | ipcnet
171 ;
172
173 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
174 ;
175
176 ifstmts:   | ifstmts ifstmt
177 ;
178
179 ifstmt:      vcomment
180              | isetip4br
181              | isetip6addrt
182              | isetip6mults
183              | isetip6multg
184              | isethelloint
185              | isethelloval
186              | isettcint
187              | isettcval
188              | isetmidint
189              | isetmidval
190              | isethnaint
191              | isethnaval
192 ;
193
194 plbody:     TOK_OPEN plstmts TOK_CLOSE
195 ;
196
197 plstmts:   | plstmts plstmt
198 ;
199
200 plstmt:     plparam
201           | vcomment
202 ;
203
204
205 imaxipc: TOK_MAXIPC TOK_INTEGER
206 {
207   cnf->ipc_connections = $2->integer;
208
209   cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
210
211   free($2);
212 }
213 ;
214
215
216 ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
217 {
218   struct in_addr in;
219   struct ipc_host *ipch;
220
221   if(PARSER_DEBUG) printf("\tIPC host: %s\n", $2->string);
222   
223   if(inet_aton($2->string, &in) == 0)
224     {
225       fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
226       exit(EXIT_FAILURE);
227     }
228
229   ipch = malloc(sizeof(struct ipc_host));
230   ipch->host.v4 = in.s_addr;
231
232   ipch->next = cnf->ipc_hosts;
233   cnf->ipc_hosts = ipch;
234
235   free($2->string);
236   free($2);
237
238 }
239 ;
240
241 ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
242 {
243   struct in_addr in1, in2;
244   struct ipc_net *ipcn;
245
246   if(PARSER_DEBUG) printf("\tIPC net: %s/%s\n", $2->string, $3->string);
247   
248   if(inet_aton($2->string, &in1) == 0)
249     {
250       fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
251       exit(EXIT_FAILURE);
252     }
253
254   if(inet_aton($3->string, &in2) == 0)
255     {
256       fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
257       exit(EXIT_FAILURE);
258     }
259
260   ipcn = malloc(sizeof(struct ipc_net));
261   ipcn->net.v4 = in1.s_addr;
262   ipcn->mask.v4 = in2.s_addr;
263
264   ipcn->next = cnf->ipc_nets;
265   cnf->ipc_nets = ipcn;
266
267   free($2->string);
268   free($2);
269   free($3->string);
270   free($3);
271
272 }
273 ;
274
275 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
276 {
277   struct in_addr in;
278
279   if(PARSER_DEBUG) printf("\tIPv4 broadcast: %s\n", $2->string);
280
281   if(inet_aton($2->string, &in) == 0)
282     {
283       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
284       exit(EXIT_FAILURE);
285     }
286
287   cnf->interfaces->cnf->ipv4_broadcast.v4 = in.s_addr;
288
289   free($2->string);
290   free($2);
291 }
292 ;
293
294 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
295 {
296   if($2->boolean)
297     cnf->interfaces->cnf->ipv6_addrtype = IPV6_ADDR_SITELOCAL;
298   else
299     cnf->interfaces->cnf->ipv6_addrtype = 0;
300
301   free($2);
302 }
303 ;
304
305 isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
306 {
307   struct in6_addr in6;
308
309   if(PARSER_DEBUG) printf("\tIPv6 site-local multicast: %s\n", $2->string);
310
311   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
312     {
313       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
314       exit(EXIT_FAILURE);
315     }
316   memcpy(&cnf->interfaces->cnf->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
317
318
319   free($2->string);
320   free($2);
321 }
322 ;
323
324
325 isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
326 {
327   struct in6_addr in6;
328
329   if(PARSER_DEBUG) printf("\tIPv6 global multicast: %s\n", $2->string);
330
331   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
332     {
333       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
334       exit(EXIT_FAILURE);
335     }
336   memcpy(&cnf->interfaces->cnf->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
337
338
339   free($2->string);
340   free($2);
341 }
342 ;
343 isethelloint: TOK_HELLOINT TOK_FLOAT
344 {
345     if(PARSER_DEBUG) printf("\tHELLO interval: %0.2f\n", $2->floating);
346     cnf->interfaces->cnf->hello_params.emission_interval = $2->floating;
347     free($2);
348 }
349 ;
350 isethelloval: TOK_HELLOVAL TOK_FLOAT
351 {
352     if(PARSER_DEBUG) printf("\tHELLO validity: %0.2f\n", $2->floating);
353     cnf->interfaces->cnf->hello_params.validity_time = $2->floating;
354     free($2);
355 }
356 ;
357 isettcint: TOK_TCINT TOK_FLOAT
358 {
359     if(PARSER_DEBUG) printf("\tTC interval: %0.2f\n", $2->floating);
360     cnf->interfaces->cnf->tc_params.emission_interval = $2->floating;
361     free($2);
362 }
363 ;
364 isettcval: TOK_TCVAL TOK_FLOAT
365 {
366     if(PARSER_DEBUG) printf("\tTC validity: %0.2f\n", $2->floating);
367     cnf->interfaces->cnf->tc_params.validity_time = $2->floating;
368     free($2);
369 }
370 ;
371 isetmidint: TOK_MIDINT TOK_FLOAT
372 {
373     if(PARSER_DEBUG) printf("\tMID interval: %0.2f\n", $2->floating);
374     cnf->interfaces->cnf->mid_params.emission_interval = $2->floating;
375     free($2);
376 }
377 ;
378 isetmidval: TOK_MIDVAL TOK_FLOAT
379 {
380     if(PARSER_DEBUG) printf("\tMID validity: %0.2f\n", $2->floating);
381     cnf->interfaces->cnf->mid_params.validity_time = $2->floating;
382     free($2);
383 }
384 ;
385 isethnaint: TOK_HNAINT TOK_FLOAT
386 {
387     if(PARSER_DEBUG) printf("\tHNA interval: %0.2f\n", $2->floating);
388     cnf->interfaces->cnf->hna_params.emission_interval = $2->floating;
389     free($2);
390 }
391 ;
392 isethnaval: TOK_HNAVAL TOK_FLOAT
393 {
394     if(PARSER_DEBUG) printf("\tHNA validity: %0.2f\n", $2->floating);
395     cnf->interfaces->cnf->hna_params.validity_time = $2->floating;
396     free($2);
397 }
398 ;
399
400
401 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
402 {
403
404   cnf->debug_level = $2->integer;
405   if(PARSER_DEBUG) printf("Debug level: %d\n", cnf->debug_level);
406   free($2);
407 }
408 ;
409
410
411 iipversion:    TOK_IPVERSION TOK_INTEGER
412 {
413   if($2->integer == 4)
414     cnf->ip_version = AF_INET;
415   else if($2->integer == 6)
416     cnf->ip_version = AF_INET6;
417   else
418     {
419       fprintf(stderr, "IPversion must be 4 or 6!\n");
420       YYABORT;
421     }
422
423   if(PARSER_DEBUG) printf("IpVersion: %d\n", $2->integer);
424   free($2);
425 }
426 ;
427
428
429 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
430 {
431   struct hna4_entry *h = malloc(sizeof(struct hna4_entry));
432   struct in_addr in;
433
434   if(PARSER_DEBUG) printf("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
435
436   if(h == NULL)
437     {
438       fprintf(stderr, "Out of memory(HNA4)\n");
439       YYABORT;
440     }
441
442   if(inet_aton($1->string, &in) == 0)
443     {
444       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
445       exit(EXIT_FAILURE);
446     }
447   h->net.v4 = in.s_addr;
448   if(inet_aton($2->string, &in) == 0)
449     {
450       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
451       exit(EXIT_FAILURE);
452     }
453   h->netmask.v4 = in.s_addr;
454   /* Queue */
455   h->next = cnf->hna4_entries;
456   cnf->hna4_entries = h;
457
458   free($1->string);
459   free($1);
460   free($2->string);
461   free($2);
462
463 }
464
465 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
466 {
467   struct hna6_entry *h = malloc(sizeof(struct hna6_entry));
468   struct in6_addr in6;
469
470   if(PARSER_DEBUG) printf("HNA IPv6 entry: %s/%d\n", $1->string, $2->integer);
471
472   if(h == NULL)
473     {
474       fprintf(stderr, "Out of memory(HNA6)\n");
475       YYABORT;
476     }
477
478   if(inet_pton(AF_INET6, $1->string, &in6) < 0)
479     {
480       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
481       exit(EXIT_FAILURE);
482     }
483   memcpy(&h->net, &in6, sizeof(struct in6_addr));
484
485   if(($2->integer < 0) || ($2->integer > 128))
486     {
487       fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
488       exit(EXIT_FAILURE);
489     }
490
491   h->prefix_len = $2->integer;
492   /* Queue */
493   h->next = cnf->hna6_entries;
494   cnf->hna6_entries = h;
495
496   free($1->string);
497   free($1);
498   free($2);
499
500 }
501
502 ifblock: TOK_INTERFACE TOK_STRING
503 {
504   struct olsr_if *in = malloc(sizeof(struct olsr_if));
505   
506   if(in == NULL)
507     {
508       fprintf(stderr, "Out of memory(ADD IF)\n");
509       YYABORT;
510     }
511
512   in->cnf = get_default_if_config();
513
514   if(in->cnf == NULL)
515     {
516       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
517       YYABORT;
518     }
519
520   in->name = $2->string;
521
522   /* Queue */
523   in->next = cnf->interfaces;
524   cnf->interfaces = in;
525
526   free($2);
527 }
528
529 bnoint: TOK_NOINT TOK_BOOLEAN
530 {
531   if(PARSER_DEBUG) printf("Noint set to %d\n", $2->boolean);
532
533   cnf->allow_no_interfaces = $2->boolean;
534
535   free($2);
536 }
537 ;
538
539 atos: TOK_TOS TOK_INTEGER
540 {
541   if(PARSER_DEBUG) printf("TOS: %d\n", $2->integer);
542   cnf->tos = $2->integer;
543
544   free($2);
545
546 }
547 ;
548
549 awillingness: TOK_WILLINGNESS TOK_INTEGER
550 {
551   cnf->willingness_auto = OLSR_FALSE;
552
553   if(PARSER_DEBUG) printf("Willingness: %d\n", $2->integer);
554   cnf->willingness = $2->integer;
555
556   free($2);
557
558 }
559 ;
560
561
562
563 busehyst: TOK_USEHYST TOK_BOOLEAN
564 {
565   cnf->use_hysteresis = $2->boolean;
566   if(cnf->use_hysteresis)
567     {
568       if(PARSER_DEBUG) printf("Hysteresis enabled\n");
569     }
570   else
571     {
572       if(PARSER_DEBUG) printf("Hysteresis disabled\n");
573     }
574   free($2);
575
576 }
577 ;
578
579
580 fhystscale: TOK_HYSTSCALE TOK_FLOAT
581 {
582   cnf->hysteresis_param.scaling = $2->floating;
583   if(PARSER_DEBUG) printf("Hysteresis Scaling: %0.2f\n", $2->floating);
584   free($2);
585 }
586 ;
587
588
589 fhystupper: TOK_HYSTUPPER TOK_FLOAT
590 {
591   cnf->hysteresis_param.thr_high = $2->floating;
592   if(PARSER_DEBUG) printf("Hysteresis UpperThr: %0.2f\n", $2->floating);
593   free($2);
594 }
595 ;
596
597
598 fhystlower: TOK_HYSTLOWER TOK_FLOAT
599 {
600   cnf->hysteresis_param.thr_low = $2->floating;
601   if(PARSER_DEBUG) printf("Hysteresis LowerThr: %0.2f\n", $2->floating);
602   free($2);
603 }
604 ;
605
606 fpollrate: TOK_POLLRATE TOK_FLOAT
607 {
608   if(PARSER_DEBUG) printf("Pollrate %0.2f\n", $2->floating);
609   cnf->pollrate = $2->floating;
610
611   free($2);
612 }
613 ;
614
615
616 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
617 {
618   if(PARSER_DEBUG) printf("TC redundancy %d\n", $2->integer);
619   cnf->tc_redundancy = $2->integer;
620   free($2);
621 }
622 ;
623
624 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
625 {
626   if(PARSER_DEBUG) printf("MPR coverage %d\n", $2->integer);
627   cnf->mpr_coverage = $2->integer;
628   free($2);
629 }
630 ;
631
632 alq_level: TOK_LQ_LEVEL TOK_INTEGER
633 {
634   if(PARSER_DEBUG) printf("Link quality level %d\n", $2->integer);
635   cnf->lq_level = $2->integer;
636   free($2);
637 }
638 ;
639
640 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
641 {
642   if(PARSER_DEBUG) printf("Link quality window size %d\n", $2->integer);
643   cnf->lq_wsize = $2->integer;
644   free($2);
645 }
646 ;
647
648 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
649 {
650   cnf->clear_screen = $2->boolean;
651
652   if (PARSER_DEBUG)
653     printf("Clear screen %s\n", cnf->clear_screen ? "enabled" : "disabled");
654
655   free($2);
656 }
657 ;
658
659 plblock: TOK_PLUGIN TOK_STRING
660 {
661   struct plugin_entry *pe = malloc(sizeof(struct plugin_entry));
662   
663   if(pe == NULL)
664     {
665       fprintf(stderr, "Out of memory(ADD PL)\n");
666       YYABORT;
667     }
668
669   pe->name = $2->string;
670
671   pe->params = NULL;
672   
673   if(PARSER_DEBUG) printf("Plugin: %s\n", $2->string);
674
675   /* Queue */
676   pe->next = cnf->plugins;
677   cnf->plugins = pe;
678
679   free($2);
680 }
681 ;
682
683 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
684 {
685   struct plugin_param *pp = malloc(sizeof(struct plugin_param));
686   
687   if(pp == NULL)
688     {
689       fprintf(stderr, "Out of memory(ADD PP)\n");
690       YYABORT;
691     }
692   
693   if(PARSER_DEBUG) printf("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
694   
695   pp->key = $2->string;
696   pp->value = $3->string;
697
698   /* Queue */
699   pp->next = cnf->plugins->params;
700   cnf->plugins->params = pp;
701
702   free($2);
703   free($3);
704 }
705 ;
706
707 vcomment:       TOK_COMMENT
708 {
709     //if(PARSER_DEBUG) printf("Comment\n");
710 }
711 ;
712
713
714
715 %%
716
717 void yyerror (char *string)
718 {
719   fprintf(stderr, "Config line %d: %s\n", current_line, string);
720 }