blob: fccaf06c72472c4883046199aa83fe868152e35d [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Sebastien Decugis <sdecugis@freediameter.net> *
4* *
5* Copyright (c) 2013, WIDE Project and NICT *
6* All rights reserved. *
7* *
8* Redistribution and use of this software in source and binary forms, with or without modification, are *
9* permitted provided that the following conditions are met: *
10* *
11* * Redistributions of source code must retain the above *
12* copyright notice, this list of conditions and the *
13* following disclaimer. *
14* *
15* * Redistributions in binary form must reproduce the above *
16* copyright notice, this list of conditions and the *
17* following disclaimer in the documentation and/or other *
18* materials provided with the distribution. *
19* *
20* * Neither the name of the WIDE Project or NICT nor the *
21* names of its contributors may be used to endorse or *
22* promote products derived from this software without *
23* specific prior written permission of WIDE Project and *
24* NICT. *
25* *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34*********************************************************************************************************/
35
36/* Yacc parser for echo/drop plugin.
37See doc/echodrop.rgwx.conf.sample for description of the parsed format. */
38
39
40/* For development only : */
41%debug
42%error-verbose
43
44/* The parser receives the configuration file filename and the conf structure as parameter */
45%parse-param {char * conffile}
46%parse-param {struct rgwp_config *cs}
47
48/* Keep track of location */
49%locations
50%pure-parser
51
52%{
53#include "rgwx_echodrop.h"
54#include "rgwx_echodrop.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
55
56
57/* Forward declaration */
58int yyparse(char * conffile, struct rgwp_config *cs);
59
60/* The Lex parser prototype */
61int rgwx_echodroplex(YYSTYPE *lvalp, YYLTYPE *llocp);
62
63
64/* Parse the configuration file */
65int ed_conffile_parse(char * conffile, struct rgwp_config *cs)
66{
67 extern FILE * rgwx_echodropin;
68 int ret;
69
70 rgwx_echodropin = fopen(conffile, "r");
71 if ((rgwx_echodropin == NULL) && (*conffile != '/')) { /* We received a relative path, try adding DEFAULT_CONF_PATH prefix */
72 char * fullpath;
73 CHECK_MALLOC( fullpath = malloc( strlen(conffile) + strlen(DEFAULT_CONF_PATH) + 2 ) );
74 sprintf( fullpath, DEFAULT_CONF_PATH "/%s", conffile );
75 rgwx_echodropin = fopen(fullpath, "r");
76 free(fullpath);
77 }
78 if (rgwx_echodropin == NULL) {
79 ret = errno;
80 fd_log_debug("[echodrop.rgwx] Unable to open plugin configuration file %s for reading: %s", conffile, strerror(ret));
81 return ret;
82 }
83
84 ret = rgwx_echodropparse(conffile, cs);
85
86 fclose(rgwx_echodropin);
87
88 if (ret != 0) {
89 return EINVAL;
90 }
91
92 return 0;
93}
94
95/* Function to report the errors */
96void yyerror (YYLTYPE *ploc, char * conffile, struct rgwp_config *cs, char const *s)
97{
98 if (ploc->first_line != ploc->last_line)
99 fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
100 else if (ploc->first_column != ploc->last_column)
101 fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
102 else
103 fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
104}
105
106static struct {
107 struct {
108 unsigned vendor :1;
109 unsigned tlv :1;
110 unsigned ext :1;
111 };
112 uint8_t type;
113 uint16_t extype;
114 uint32_t vendor_id;
115} attrinfo;
116
117
118%}
119
120/* Values returned by lex for tokens */
121%union {
122 unsigned integer; /* Value */
123}
124
125/* typed data */
126%token <integer> INTEGER
127%type <integer> action
128
129/* simple tokens */
130%token TOK_ECHO
131%token TOK_DROP
132%token TOK_CODE
133%token TOK_VENDOR
134%token TOK_TLV
135%token TOK_EXT
136
137/* In case of error in the lexical analysis */
138%token LEX_ERROR
139
140
141/* -------------------------------------- */
142%%
143
144 /* The grammar definition */
145conffile: /* empty grammar is OK */
146 | conffile attrdef
147 ;
148
149 /* An attribute line */
150attrdef: {
151 memset(&attrinfo, 0, sizeof(attrinfo));
152 }
153 action TOK_CODE INTEGER vendordef ';'
154 {
155 struct ed_conf_attribute * new;
156 struct fd_list * li;
157
158 if ($4 >= 256) {
159 yyerror (&yylloc, conffile, cs, "Too big value for attribute CODE");
160 YYERROR;
161 }
162
163 /* Create a new list item */
164 CHECK_MALLOC_DO( new = malloc(sizeof(struct ed_conf_attribute)),
165 {
166 yyerror (&yylloc, conffile, cs, "Memory allocation error");
167 YYERROR;
168 } );
169 memset(new, 0, sizeof(struct ed_conf_attribute));
170
171 fd_list_init(&new->chain, NULL);
172
173 new->action = $2;
174 new->vsa = attrinfo.vendor;
175 new->tlv = attrinfo.tlv;
176 new->ext = attrinfo.ext;
177
178 if (new->vsa)
179 new->vendor_id = attrinfo.vendor_id;
180 if (new->tlv)
181 new->type = attrinfo.type;
182 if (new->ext)
183 new->extype = attrinfo.extype;
184
185 new->code = $4;
186
187 /* Now place this attribute in the list */
188 for (li = cs->attributes.next; li != &cs->attributes; li = li->next) {
189 struct ed_conf_attribute *eca = (struct ed_conf_attribute *)li;
190 /* Order first by attribute code */
191 if (eca->code > new->code)
192 break;
193 if (eca->code < new->code)
194 continue;
195
196 /* Then by VSA flag */
197 if (! new->vsa)
198 break;
199 if (! eca->vsa)
200 continue;
201
202 /* Then by vendor value */
203 if (eca->vendor_id >= new->vendor_id)
204 break;
205 }
206
207 fd_list_insert_before(li, &new->chain);
208 }
209 ;
210
211 /* What to do with the specified attribute */
212action: TOK_ECHO
213 {
214 $$ = ACT_ECHO;
215 }
216 |
217 TOK_DROP
218 {
219 $$ = ACT_DROP;
220 }
221 ;
222
223 /* Vendor specifics, if any */
224vendordef: /* empty OK */
225 | TOK_VENDOR INTEGER specif
226 {
227 attrinfo.vendor_id = $2;
228 attrinfo.vendor = 1;
229 }
230 ;
231
232 /* Any additional specification ? */
233specif: /* empty OK */
234 | TOK_TLV INTEGER
235 {
236 if ($2 >= (1 << 8)) {
237 yyerror (&yylloc, conffile, cs, "Too big value for TLV type");
238 YYERROR;
239 }
240 attrinfo.type = $2;
241 attrinfo.tlv = 1;
242 }
243 | TOK_EXT INTEGER
244 {
245 if ($2 >= (1 << 16)) {
246 yyerror (&yylloc, conffile, cs, "Too big value for Ext-Type");
247 YYERROR;
248 }
249 attrinfo.extype = $2;
250 attrinfo.ext = 1;
251 yyerror (&yylloc, conffile, cs, "The EXT option is not supported in this version.");
252 YYERROR;
253 }
254 ;
255