- still to do action,c
[sip-router] / cfg.y
1 /*
2  * $Id$
3  *
4  *  cfg grammar
5  */
6
7 %{
8
9 #include "route_struct.h"
10
11 %}
12
13 %union {
14         int intval;
15         unsigned uval;
16         char* strval;
17         struct expr* expr;
18         struct action* action;
19         struct net* net;
20 }
21
22 /* terminals */
23
24
25 /* keywors */
26 %token FORWARD
27 %token SEND
28 %token DROP
29 %token LOG
30 %token ERROR
31 %token ROUTE
32 %token EXEC
33
34 %token METHOD
35 %token URI
36 %token SRCIP
37 %token DSTIP
38
39 /* config vars. */
40 %token DEBUG
41 %token FORK
42 %token LOGSTDERROR
43 %token LISTEN
44 %token DNS
45 %token REV_DNS
46
47
48 /* operators */
49 %nonassoc EQUAL
50 %nonassoc EQUAL_T
51 %nonassoc MATCH
52 %left OR
53 %left AND
54 %left NOT
55
56 /* values */
57 %token <intval> NUMBER
58 %token <strval> ID
59 %token <strval> STRING
60
61 /* other */
62 %token COMMA
63 %token SEMICOLON
64 %token RPAREN
65 %token LPAREN
66 %token LBRACE
67 %token RBRACE
68 %token LBRACK
69 %token RBRACK
70 %token SLASH
71 %token DOT
72 %token CR
73
74
75 /*non-terminals */
76 %type <expr> exp, condition,  exp_elem
77 %type <action> action, actions, cmd
78 %type <uval> ipv4
79 %type <net> net4
80 %type <strval> host
81
82
83
84 %%
85
86
87 cfg:    statements
88         ;
89
90 statements:     statements statement {printf("got <> <>\n");}
91                 | statement {printf("got a statement<>\n"); }
92                 | statements error { yyerror(""); }
93         ;
94
95 statement:      assign_stm CR
96                 | route_stm CR
97                 | CR    /* null statement*/
98         ;
99
100 assign_stm:     DEBUG EQUAL NUMBER 
101                 | DEBUG EQUAL error  { yyerror("number  expected"); }
102                 | FORK  EQUAL NUMBER
103                 | FORK  EQUAL error  { yyerror("boolean value expected"); }
104                 | LOGSTDERROR EQUAL NUMBER 
105                 | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
106                 | DNS EQUAL NUMBER
107                 | DNS EQUAL error { yyerror("boolean value expected"); }
108                 | REV_DNS EQUAL NUMBER 
109                 | REV_DNS EQUAL error { yyerror("boolean value expected"); }
110                 | LISTEN EQUAL ipv4 
111                 | LISTEN EQUAL ID 
112                 | LISTEN EQUAL STRING
113                 | LISTEN EQUAL  error { yyerror("ip address or hostname"
114                                                 "expected"); }
115                 | error EQUAL { yyerror("unknown config variable"); }
116         ;
117
118
119 ipv4:   NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { 
120                                                                                         if (($1>255) || ($1<0) ||
121                                                                                                 ($3>255) || ($3<0) ||
122                                                                                                 ($5>255) || ($5<0) ||
123                                                                                                 ($7>255) || ($7<0)){
124                                                                                                 yyerror("invalid ipv4"
125                                                                                                                 "address");
126                                                                                                 $$=0;
127                                                                                         }else{
128                                                                                                 $$=($1<<24)|($3<<16)|
129                                                                                                         ($5<<8)|$7;
130                                                                                         }
131                                                                                                 }
132         ;
133
134 route_stm:      ROUTE LBRACE rules RBRACE 
135                 | ROUTE LBRACK NUMBER RBRACK LBRACE rules RBRACE
136                 | ROUTE error { yyerror("invalid  route  statement"); }
137         ;
138
139 rules:  rules rule
140         | rule
141         | rules error { yyerror("invalid rule"); }
142          ;
143
144 rule:   condition       actions CR {
145                                                                 printf("Got a new rule!\n");
146                                                                 printf("expr: "); print_expr($1);
147                                                                 printf("\n  -> actions: ");
148                                                                 print_action($2); printf("\n");
149                                                            }
150         | CR  /* null rule */
151         | condition error { yyerror("bad actions in rule"); }
152         ;
153
154 condition:      exp {$$=$1;}
155         ;
156
157 exp:    exp AND exp     { $$=mk_exp(AND_OP, $1, $3); }
158         | exp OR  exp           { $$=mk_exp(OR_OP, $1, $3);  }
159         | NOT exp                       { $$=mk_exp(NOT_OP, $2, 0);  }
160         | LPAREN exp RPAREN     { $$=$2; }
161         | exp_elem                      { $$=$1; }
162         ;
163
164 exp_elem:       METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST, 
165                                                                                                         METHOD_O, $3);
166                                                                         }
167                 | METHOD EQUAL_T ID     {$$ = mk_elem(  EQUAL_OP, STRING_ST,
168                                                                                         METHOD_O, $3); 
169                                                         }
170                 | METHOD EQUAL_T error { $$=0; yyerror("string expected"); }
171                 | METHOD MATCH STRING   {$$ = mk_elem(  MATCH_OP, STRING_ST,
172                                                                                                 METHOD_O, $3); 
173                                                                 }
174                 | METHOD MATCH ID       {$$ = mk_elem(  MATCH_OP, STRING_ST,
175                                                                                         METHOD_O, $3); 
176                                                         }
177                 | METHOD MATCH error { $$=0; yyerror("string expected"); }
178                 | METHOD error  { $$=0; yyerror("invalid operator,"
179                                                                                 "== or ~= expected");
180                                                 }
181                 | URI EQUAL_T STRING    {$$ = mk_elem(  EQUAL_OP, STRING_ST,
182                                                                                                 URI_O, $3); 
183                                                                 }
184                 | URI EQUAL_T ID        {$$ = mk_elem(  EQUAL_OP, STRING_ST,
185                                                                                         URI_O, $3); 
186                                                         }
187                 | URI EQUAL_T error { $$=0; yyerror("string expected"); }
188                 | URI MATCH STRING      { $$=mk_elem(   MATCH_OP, STRING_ST,
189                                                                                         URI_O, $3);
190                                                         }
191                 | URI MATCH ID          { $$=mk_elem(   MATCH_OP, STRING_ST,
192                                                                                         URI_O, $3);
193                                                         }
194                 | URI MATCH error {  $$=0; yyerror("string expected"); }
195                 | URI error     { $$=0; yyerror("invalid operator,"
196                                                                         " == or ~= expected");
197                                         }
198                 | SRCIP EQUAL_T net4    { $$=mk_elem(   EQUAL_OP, NET_ST,
199                                                                                                 SRCIP_O, $3);
200                                                                 }
201                 | SRCIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
202                                                                                                 SRCIP_O, $3);
203                                                                 }
204                 | SRCIP EQUAL_T host    { $$=mk_elem(   EQUAL_OP, STRING_ST,
205                                                                                                 SRCIP_O, $3);
206                                                                 }
207                 | SRCIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
208                                                  "expected" ); }
209                 | SRCIP MATCH STRING    { $$=mk_elem(   MATCH_OP, STRING_ST,
210                                                                                                 SRCIP_O, $3);
211                                                                 }
212                 | SRCIP MATCH ID                { $$=mk_elem(   MATCH_OP, STRING_ST,
213                                                                                                 SRCIP_O, $3);
214                                                                 }
215                 | SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
216                 | SRCIP error  { $$=0; 
217                                                  yyerror("invalid operator, == or ~= expected");}
218                 | DSTIP EQUAL_T net4    { $$=mk_elem(   EQUAL_OP, NET_ST,
219                                                                                                 DSTIP_O, $3);
220                                                                 }
221                 | DSTIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
222                                                                                                 DSTIP_O, $3);
223                                                                 }
224                 | DSTIP EQUAL_T host    { $$=mk_elem(   EQUAL_OP, STRING_ST,
225                                                                                                 DSTIP_O, $3);
226                                                                 }
227                 | DSTIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
228                                                                         "expected" ); }
229                 | DSTIP MATCH STRING    { $$=mk_elem(   MATCH_OP, STRING_ST,
230                                                                                                 DSTIP_O, $3);
231                                                                 }
232                 | DSTIP MATCH ID        { $$=mk_elem(   MATCH_OP, STRING_ST,
233                                                                                         DSTIP_O, $3);
234                                                         }
235                 | DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
236                 | DSTIP error { $$=0; 
237                                                 yyerror("invalid operator, == or ~= expected");}
238         ;
239
240 net4:   ipv4 SLASH ipv4 { $$=mk_net($1, $3); } 
241         | ipv4 SLASH NUMBER {   if (($3>32)|($3<0)){
242                                                                 yyerror("invalid bit number in netmask");
243                                                                 $$=0;
244                                                         }else{
245                                                                 $$=mk_net($1, (1<<$3)-1);
246                                                         }
247                                                 }
248         | ipv4                          { $$=mk_net($1, 0xffffffff); }
249         | ipv4 SLASH error { $$=0;
250                                                  yyerror("netmask (eg:255.0.0.0 or 8) expected");}
251         ;
252
253 host:   ID                              { $$=$1; }
254         | host DOT ID           { $$=(char*)malloc(strlen($1)+1+strlen($3)+1);
255                                                   if ($$==0){
256                                                         fprintf(stderr, "memory allocation failure"
257                                                                                 " while parsing host\n");
258                                                   }else{
259                                                         memcpy($$, $1, strlen($1));
260                                                         $$[strlen($1)]='.';
261                                                         memcpy($$+strlen($1)+1, $3, strlen($3));
262                                                         $$[strlen($1)+1+strlen($3)]=0;
263                                                   }
264                                                   free($1); free($3);
265                                                 };
266         | host DOT error { $$=0; free($1); yyerror("invalid hostname"); }
267         ;
268
269
270 actions:        actions action  {$$=append_action($1, $2); }
271                 | action                        {$$=$1;}
272                 | actions error { $$=0; yyerror("bad command"); }
273         ;
274
275 action:         cmd SEMICOLON {$$=$1;}
276                 | SEMICOLON /* null action */ {$$=0;}
277                 | cmd error { $$=0; yyerror("bad command: missing ';'?"); }
278         ;
279
280 cmd:            FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
281                                                                                                                 STRING_ST,
282                                                                                                                 NUMBER_ST,
283                                                                                                                 $3,
284                                                                                                                 0);
285                                                                                 }
286                 | FORWARD LPAREN STRING RPAREN  { $$=mk_action( FORWARD_T,
287                                                                                                                 STRING_ST,
288                                                                                                                 NUMBER_ST,
289                                                                                                                 $3,
290                                                                                                                 0);
291                                                                                 }
292                 | FORWARD LPAREN ipv4 RPAREN    { $$=mk_action( FORWARD_T,
293                                                                                                                 IP_ST,
294                                                                                                                 NUMBER_ST,
295                                                                                                                 (void*)$3,
296                                                                                                                 0);
297                                                                                 }
298                 | FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
299                                                                                                                                  STRING_ST,
300                                                                                                                                  NUMBER_ST,
301                                                                                                                                 $3,
302                                                                                                                                 (void*)$5);
303                                                                                                  }
304                 | FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T,
305                                                                                                                                  STRING_ST,
306                                                                                                                                  NUMBER_ST,
307                                                                                                                                 $3,
308                                                                                                                                 (void*)$5);
309                                                                                                         }
310                 | FORWARD LPAREN ipv4 COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
311                                                                                                                                  IP_ST,
312                                                                                                                                  NUMBER_ST,
313                                                                                                                                  (void*)$3,
314                                                                                                                                 (void*)$5);
315                                                                                                   }
316                 | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
317                 | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward"
318                                                                                 "argument"); }
319                 | SEND LPAREN host RPAREN       { $$=mk_action( SEND_T,
320                                                                                                         STRING_ST,
321                                                                                                         NUMBER_ST,
322                                                                                                         $3,
323                                                                                                         0);
324                                                                         }
325                 | SEND LPAREN STRING RPAREN { $$=mk_action(     SEND_T,
326                                                                                                         STRING_ST,
327                                                                                                         NUMBER_ST,
328                                                                                                         $3,
329                                                                                                         0);
330                                                                         }
331                 | SEND LPAREN ipv4 RPAREN       { $$=mk_action( SEND_T,
332                                                                                                         IP_ST,
333                                                                                                         NUMBER_ST,
334                                                                                                         (void*)$3,
335                                                                                                         0);
336                                                                         }
337                 | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action( SEND_T,
338                                                                                                                                 STRING_ST,
339                                                                                                                                 NUMBER_ST,
340                                                                                                                                 $3,
341                                                                                                                                 (void*)$5);
342                                                                                                 }
343                 | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action( SEND_T,
344                                                                                                                                 STRING_ST,
345                                                                                                                                 NUMBER_ST,
346                                                                                                                                 $3,
347                                                                                                                                 (void*)$5);
348                                                                                                 }
349                 | SEND LPAREN ipv4 COMMA NUMBER RPAREN { $$=mk_action(  SEND_T,
350                                                                                                                                 IP_ST,
351                                                                                                                                 NUMBER_ST,
352                                                                                                                                 (void*)$3,
353                                                                                                                                 (void*)$5);
354                                                                                            }
355                 | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
356                 | SEND LPAREN error RPAREN { $$=0; yyerror("bad send"
357                                                                                                         "argument"); }
358                 | DROP LPAREN RPAREN    {$$=mk_action(DROP_T,0, 0, 0, 0); }
359                 | DROP                                  {$$=mk_action(DROP_T,0, 0, 0, 0); }
360                 | LOG LPAREN STRING RPAREN      {$$=mk_action(  LOG_T, NUMBER_ST, 
361                                                                                                         STRING_ST,(void*)4,$3);
362                                                                         }
363                 | LOG LPAREN NUMBER COMMA STRING RPAREN {$$=mk_action(  LOG_T,
364                                                                                                                                 NUMBER_ST, 
365                                                                                                                                 STRING_ST,
366                                                                                                                                 (void*)$3,
367                                                                                                                                 $5);
368                                                                                                 }
369                 | LOG error { $$=0; yyerror("missing '(' or ')' ?"); }
370                 | LOG LPAREN error RPAREN { $$=0; yyerror("bad log"
371                                                                         "argument"); }
372                 | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
373                                                                                                                                 STRING_ST, 
374                                                                                                                                 STRING_ST,
375                                                                                                                                 $3,
376                                                                                                                                 $5);
377                                                                                                   }
378                                                                                                 
379                 | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
380                 | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
381                                                                                                                 "argument"); }
382                 | ROUTE LPAREN NUMBER RPAREN    { $$=mk_action(ROUTE_T, NUMBER_ST,
383                                                                                                                 0, (void*)$3, 0);
384                                                                                 }
385                 | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
386                 | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route"
387                                                 "argument"); }
388                 | EXEC LPAREN STRING RPAREN     { $$=mk_action( EXEC_T, STRING_ST, 0,
389                                                                                                         $3, 0);
390                                                                         }
391         ;
392
393
394 %%
395
396 extern int line;
397 extern int column;
398 extern int startcolumn;
399 yyerror(char* s)
400 {
401         fprintf(stderr, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
402                         column, s);
403 }
404
405 /*
406 int main(int argc, char ** argv)
407 {
408         if (yyparse()!=0)
409                 fprintf(stderr, "parsing error\n");
410 }
411 */