98bb393d8aa9468273a93ab42f9abe1f4bd475c9
[sip-router] / cfg.y
1 /*
2  * $Id$
3  *
4  *  cfg grammar
5  *
6  * Copyright (C) 2001-2003 Fhg Fokus
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License 
26  * along with this program; if not, write to the Free Software 
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29  /*
30  * History:
31  * ---------
32  * 2003-01-29  src_port added (jiri)
33  * 2003-01-23  mhomed added (jiri)
34  * 2003-03-19  replaced all mallocs/frees with pkg_malloc/pkg_free (andrei)
35  * 2003-03-19  Added support for route type in find_export (janakj)
36  * 2003-03-20  Regex support in modparam (janakj)
37  * 2003-04-01  added dst_port, proto , af (andrei)
38  * 2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
39  * 2003-04-12  added force_rport, chroot and wdir (andrei)
40  */
41
42
43 %{
44
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
51 #include <string.h>
52 #include <errno.h>
53 #include "route_struct.h"
54 #include "globals.h"
55 #include "route.h"
56 #include "dprint.h"
57 #include "sr_module.h"
58 #include "modparam.h"
59 #include "ip_addr.h"
60 #include "name_alias.h"
61
62 #include "config.h"
63
64 #ifdef DEBUG_DMALLOC
65 #include <dmalloc.h>
66 #endif
67
68 /* hack to avoid alloca usage in the generated C file (needed for compiler
69  with no built in alloca, like icc*/
70 #undef _ALLOCA_H
71
72 struct id_list{
73         char* s;
74         struct id_list* next;
75 };
76
77 extern int yylex();
78 void yyerror(char* s);
79 char* tmp;
80 void* f_tmp;
81 struct id_list* lst_tmp;
82 int rt;  /* Type of route block for find_export */
83  
84
85 %}
86
87 %union {
88         long intval;
89         unsigned long uval;
90         char* strval;
91         struct expr* expr;
92         struct action* action;
93         struct net* ipnet;
94         struct ip_addr* ipaddr;
95         struct id_list* idlst;
96 }
97
98 /* terminals */
99
100
101 /* keywords */
102 %token FORWARD
103 %token FORWARD_TCP
104 %token FORWARD_UDP
105 %token SEND
106 %token SEND_TCP
107 %token DROP
108 %token LOG_TOK
109 %token ERROR
110 %token ROUTE
111 %token ROUTE_FAILURE
112 %token ROUTE_ONREPLY
113 %token EXEC
114 %token SET_HOST
115 %token SET_HOSTPORT
116 %token PREFIX
117 %token STRIP
118 %token APPEND_BRANCH
119 %token SET_USER
120 %token SET_USERPASS
121 %token SET_PORT
122 %token SET_URI
123 %token REVERT_URI
124 %token FORCE_RPORT
125 %token IF
126 %token ELSE
127 %token URIHOST
128 %token URIPORT
129 %token MAX_LEN
130 %token SETFLAG
131 %token RESETFLAG
132 %token ISFLAGSET
133 %token LEN_GT
134 %token METHOD
135 %token URI
136 %token SRCIP
137 %token SRCPORT
138 %token DSTIP
139 %token DSTPORT
140 %token PROTO
141 %token AF
142 %token MYSELF
143
144 /* config vars. */
145 %token DEBUG
146 %token FORK
147 %token LOGSTDERROR
148 %token LISTEN
149 %token ALIAS
150 %token DNS
151 %token REV_DNS
152 %token PORT
153 %token STAT
154 %token CHILDREN
155 %token CHECK_VIA
156 %token SYN_BRANCH
157 %token MEMLOG
158 %token SIP_WARNING
159 %token FIFO
160 %token FIFO_MODE
161 %token SERVER_SIGNATURE
162 %token REPLY_TO_VIA
163 %token LOADMODULE
164 %token MODPARAM
165 %token MAXBUFFER
166 %token USER
167 %token GROUP
168 %token CHROOT
169 %token WDIR
170 %token MHOMED
171
172
173
174 /* operators */
175 %nonassoc EQUAL
176 %nonassoc EQUAL_T
177 %nonassoc MATCH
178 %left OR
179 %left AND
180 %left NOT
181
182 /* values */
183 %token <intval> NUMBER
184 %token <strval> ID
185 %token <strval> STRING
186 %token <strval> IPV6ADDR
187
188 /* other */
189 %token COMMA
190 %token SEMICOLON
191 %token RPAREN
192 %token LPAREN
193 %token LBRACE
194 %token RBRACE
195 %token LBRACK
196 %token RBRACK
197 %token SLASH
198 %token DOT
199 %token CR
200
201
202 /*non-terminals */
203 %type <expr> exp exp_elem /*, condition*/
204 %type <action> action actions cmd if_cmd stm
205 %type <ipaddr> ipv4 ipv6 ip
206 %type <ipnet> ipnet
207 %type <strval> host
208 %type <strval> listen_id
209 %type <idlst>  id_lst
210 /*%type <route_el> rules;
211   %type <route_el> rule;
212 */
213
214
215
216 %%
217
218
219 cfg:    statements
220         ;
221
222 statements:     statements statement {}
223                 | statement {}
224                 | statements error { yyerror(""); YYABORT;}
225         ;
226
227 statement:      assign_stm 
228                 | module_stm
229                 | {rt=REQUEST_ROUTE;} route_stm 
230                 | {rt=FAILURE_ROUTE;} failure_route_stm
231                 | {rt=ONREPLY_ROUTE;} onreply_route_stm
232
233                 | CR    /* null statement*/
234         ;
235
236 listen_id:      ip                      {       tmp=ip_addr2a($1);
237                                                         if(tmp==0){
238                                                                 LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
239                                                                                 "addresss.\n");
240                                                                 $$=0;
241                                                         }else{
242                                                                 $$=pkg_malloc(strlen(tmp)+1);
243                                                                 if ($$==0){
244                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
245                                                                                         "memory.\n");
246                                                                 }else{
247                                                                         strncpy($$, tmp, strlen(tmp)+1);
248                                                                 }
249                                                         }
250                                                 }
251                  |      ID                      {       $$=pkg_malloc(strlen($1)+1);
252                                                         if ($$==0){
253                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
254                                                                                         "memory.\n");
255                                                         }else{
256                                                                         strncpy($$, $1, strlen($1)+1);
257                                                         }
258                                                 }
259                  |      STRING                  {       $$=pkg_malloc(strlen($1)+1);
260                                                         if ($$==0){
261                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
262                                                                                         "memory.\n");
263                                                         }else{
264                                                                         strncpy($$, $1, strlen($1)+1);
265                                                         }
266                                                 }
267                  |      host            {       $$=pkg_malloc(strlen($1)+1);
268                                                         if ($$==0){
269                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
270                                                                                         "memory.\n");
271                                                         }else{
272                                                                         strncpy($$, $1, strlen($1)+1);
273                                                         }
274                                                 }
275         ;
276
277 id_lst:   listen_id     {       $$=pkg_malloc(sizeof(struct id_list));
278                                                 if ($$==0){
279                                                         LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
280                                                 }else{
281                                                         $$->s=$1;
282                                                         $$->next=0;
283                                                 }
284                                         }
285                 | listen_id id_lst      {
286                                                 $$=pkg_malloc(sizeof(struct id_list));
287                                                 if ($$==0){
288                                                         LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
289                                                 }else{
290                                                         $$->s=$1;
291                                                         $$->next=$2;
292                                                 }
293                                                         }
294                 ;
295
296
297 assign_stm:     DEBUG EQUAL NUMBER { debug=$3; }
298                 | DEBUG EQUAL error  { yyerror("number  expected"); }
299                 | FORK  EQUAL NUMBER { dont_fork= ! $3; }
300                 | FORK  EQUAL error  { yyerror("boolean value expected"); }
301                 | LOGSTDERROR EQUAL NUMBER { log_stderr=$3; }
302                 | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
303                 | DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
304                 | DNS EQUAL error { yyerror("boolean value expected"); }
305                 | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
306                 | REV_DNS EQUAL error { yyerror("boolean value expected"); }
307                 | PORT EQUAL NUMBER   { port_no=$3; 
308                                                                 if (sock_no>0) 
309                                                                         sock_info[sock_no-1].port_no=port_no;
310                                                           }
311                 | STAT EQUAL STRING {
312                                         #ifdef STATS
313                                                         stat_file=$3;
314                                         #endif
315                                                         }
316                 | MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
317                 | MAXBUFFER EQUAL error { yyerror("number expected"); }
318                 | PORT EQUAL error    { yyerror("number expected"); } 
319                 | CHILDREN EQUAL NUMBER { children_no=$3; }
320                 | CHILDREN EQUAL error { yyerror("number expected"); } 
321                 | CHECK_VIA EQUAL NUMBER { check_via=$3; }
322                 | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
323                 | SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
324                 | SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
325                 | MEMLOG EQUAL NUMBER { memlog=$3; }
326                 | MEMLOG EQUAL error { yyerror("int value expected"); }
327                 | SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
328                 | SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
329                 | FIFO EQUAL STRING { fifo=$3; }
330                 | FIFO EQUAL error { yyerror("string value expected"); }
331                 | FIFO_MODE EQUAL NUMBER { fifo_mode=$3; }
332                 | FIFO_MODE EQUAL error { yyerror("int value expected"); }
333                 | USER EQUAL STRING     { user=$3; }
334                 | USER EQUAL ID         { user=$3; }
335                 | USER EQUAL error      { yyerror("string value expected"); }
336                 | GROUP EQUAL STRING     { group=$3; }
337                 | GROUP EQUAL ID         { group=$3; }
338                 | GROUP EQUAL error      { yyerror("string value expected"); }
339                 | CHROOT EQUAL STRING     { chroot_dir=$3; }
340                 | CHROOT EQUAL ID         { chroot_dir=$3; }
341                 | CHROOT EQUAL error      { yyerror("string value expected"); }
342                 | WDIR EQUAL STRING     { working_dir=$3; }
343                 | WDIR EQUAL ID         { working_dir=$3; }
344                 | WDIR EQUAL error      { yyerror("string value expected"); }
345                 | MHOMED EQUAL NUMBER { mhomed=$3; }
346                 | MHOMED EQUAL error { yyerror("boolean value expected"); }
347                 | SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
348                 | SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
349                 | REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
350                 | REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
351                 | LISTEN EQUAL id_lst {
352                                                         for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
353                                                                 if (sock_no < MAX_LISTEN){
354                                                                         sock_info[sock_no].name.s=(char*)
355                                                                                         pkg_malloc(strlen(lst_tmp->s)+1);
356                                                                         if (sock_info[sock_no].name.s==0){
357                                                                                 LOG(L_CRIT, "ERROR: cfg. parser:"
358                                                                                                         " out of memory.\n");
359                                                                                 break;
360                                                                         }else{
361                                                                                 strncpy(sock_info[sock_no].name.s,
362                                                                                                 lst_tmp->s,
363                                                                                                 strlen(lst_tmp->s)+1);
364                                                                                 sock_info[sock_no].name.len=
365                                                                                                         strlen(lst_tmp->s);
366                                                                                 sock_info[sock_no].port_no=port_no;
367                                                                                 sock_no++;
368                                                                         }
369                                                                 }else{
370                                                                         LOG(L_CRIT, "ERROR: cfg. parser: "
371                                                                                                 "too many listen addresses"
372                                                                                                 "(max. %d).\n", MAX_LISTEN);
373                                                                         break;
374                                                                 }
375                                                         }
376                                                          }
377                 | LISTEN EQUAL  error { yyerror("ip address or hostname"
378                                                 "expected"); }
379                 | ALIAS EQUAL  id_lst { 
380                                                         for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
381                                                                 add_alias(lst_tmp->s, strlen(lst_tmp->s), 0);
382                                                           }
383                 | ALIAS  EQUAL error  { yyerror(" hostname expected"); }
384                 | error EQUAL { yyerror("unknown config variable"); }
385         ;
386
387 module_stm:     LOADMODULE STRING       { DBG("loading module %s\n", $2);
388                                                                   if (load_module($2)!=0){
389                                                                                 yyerror("failed to load module");
390                                                                   }
391                                                                 }
392                  | LOADMODULE error     { yyerror("string expected");  }
393                  | MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
394                          if (set_mod_param_regex($3, $5, STR_PARAM, $7) != 0) {
395                                  yyerror("Can't set module parameter");
396                          }
397                    }
398                  | MODPARAM LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
399                          if (set_mod_param_regex($3, $5, INT_PARAM, (void*)$7) != 0) {
400                                  yyerror("Can't set module parameter");
401                          }
402                    }
403                  | MODPARAM error { yyerror("Invalid arguments"); }
404                  ;
405
406
407 ip:              ipv4  { $$=$1; }
408                 |ipv6  { $$=$1; }
409                 ;
410
411 ipv4:   NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { 
412                                                                                         $$=pkg_malloc(
413                                                                                                         sizeof(struct ip_addr));
414                                                                                         if ($$==0){
415                                                                                                 LOG(L_CRIT, "ERROR: cfg. "
416                                                                                                         "parser: out of memory.\n"
417                                                                                                         );
418                                                                                         }else{
419                                                                                                 memset($$, 0, 
420                                                                                                         sizeof(struct ip_addr));
421                                                                                                 $$->af=AF_INET;
422                                                                                                 $$->len=4;
423                                                                                                 if (($1>255) || ($1<0) ||
424                                                                                                         ($3>255) || ($3<0) ||
425                                                                                                         ($5>255) || ($5<0) ||
426                                                                                                         ($7>255) || ($7<0)){
427                                                                                                         yyerror("invalid ipv4"
428                                                                                                                         "address");
429                                                                                                         $$->u.addr32[0]=0;
430                                                                                                         /* $$=0; */
431                                                                                                 }else{
432                                                                                                         $$->u.addr[0]=$1;
433                                                                                                         $$->u.addr[1]=$3;
434                                                                                                         $$->u.addr[2]=$5;
435                                                                                                         $$->u.addr[3]=$7;
436                                                                                                         /*
437                                                                                                         $$=htonl( ($1<<24)|
438                                                                                                         ($3<<16)| ($5<<8)|$7 );
439                                                                                                         */
440                                                                                                 }
441                                                                                         }
442                                                                                                 }
443         ;
444
445 ipv6:   IPV6ADDR {
446                                         $$=pkg_malloc(sizeof(struct ip_addr));
447                                         if ($$==0){
448                                                 LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
449                                         }else{
450                                                 memset($$, 0, sizeof(struct ip_addr));
451                                                 $$->af=AF_INET6;
452                                                 $$->len=16;
453                                         #ifdef USE_IPV6
454                                                 if (inet_pton(AF_INET6, $1, $$->u.addr)<=0){
455                                                         yyerror("bad ipv6 address");
456                                                 }
457                                         #else
458                                                 yyerror("ipv6 address & no ipv6 support compiled in");
459                                                 YYABORT;
460                                         #endif
461                                         }
462                                 }
463         ;
464
465
466 route_stm:  ROUTE LBRACE actions RBRACE { push($3, &rlist[DEFAULT_RT]); }
467
468             | ROUTE LBRACK NUMBER RBRACK LBRACE actions RBRACE { 
469                                                                                 if (($3<RT_NO) && ($3>=0)){
470                                                                                         push($6, &rlist[$3]);
471                                                                                 }else{
472                                                                                         yyerror("invalid routing"
473                                                                                                         "table number");
474                                                                                         YYABORT; }
475                                                                                 }
476                 | ROUTE error { yyerror("invalid  route  statement"); }
477         ;
478
479 failure_route_stm: ROUTE_FAILURE LBRACK NUMBER RBRACK LBRACE actions RBRACE {
480                                                                                 if (($3<FAILURE_RT_NO)&&($3>=1)){
481                                                                                         push($6, &failure_rlist[$3]);
482                                                                                 } else {
483                                                                                         yyerror("invalid reply routing"
484                                                                                                 "table number");
485                                                                                         YYABORT; }
486                                                                                 }
487                 | ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
488         ;
489
490 onreply_route_stm: ROUTE_ONREPLY LBRACK NUMBER RBRACK LBRACE actions RBRACE {
491                                                                                 if (($3<ONREPLY_RT_NO)&&($3>=1)){
492                                                                                         push($6, &onreply_rlist[$3]);
493                                                                                 } else {
494                                                                                         yyerror("invalid reply routing"
495                                                                                                 "table number");
496                                                                                         YYABORT; }
497                                                                                 }
498                 | ROUTE_ONREPLY error { yyerror("invalid failure_route statement"); }
499         ;
500 /*
501 rules:  rules rule { push($2, &$1); $$=$1; }
502         | rule {$$=$1; }
503         | rules error { $$=0; yyerror("invalid rule"); }
504          ;
505
506 rule:   condition       actions CR {
507                                                                 $$=0;
508                                                                 if (add_rule($1, $2, &$$)<0) {
509                                                                         yyerror("error calling add_rule");
510                                                                         YYABORT;
511                                                                 }
512                                                           }
513         | CR            { $$=0;}
514         | condition error { $$=0; yyerror("bad actions in rule"); }
515         ;
516
517 condition:      exp {$$=$1;}
518 */
519
520 exp:    exp AND exp     { $$=mk_exp(AND_OP, $1, $3); }
521         | exp OR  exp           { $$=mk_exp(OR_OP, $1, $3);  }
522         | NOT exp                       { $$=mk_exp(NOT_OP, $2, 0);  }
523         | LPAREN exp RPAREN     { $$=$2; }
524         | exp_elem                      { $$=$1; }
525         ;
526
527 exp_elem:       METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST, 
528                                                                                                         METHOD_O, $3);
529                                                                         }
530                 | METHOD EQUAL_T ID     {$$ = mk_elem(  EQUAL_OP, STRING_ST,
531                                                                                         METHOD_O, $3); 
532                                                         }
533                 | METHOD EQUAL_T error { $$=0; yyerror("string expected"); }
534                 | METHOD MATCH STRING   {$$ = mk_elem(  MATCH_OP, STRING_ST,
535                                                                                                 METHOD_O, $3); 
536                                                                 }
537                 | METHOD MATCH ID       {$$ = mk_elem(  MATCH_OP, STRING_ST,
538                                                                                         METHOD_O, $3); 
539                                                         }
540                 | METHOD MATCH error { $$=0; yyerror("string expected"); }
541                 | METHOD error  { $$=0; yyerror("invalid operator,"
542                                                                                 "== or =~ expected");
543                                                 }
544                 | URI EQUAL_T STRING    {$$ = mk_elem(  EQUAL_OP, STRING_ST,
545                                                                                                 URI_O, $3); 
546                                                                 }
547                 | URI EQUAL_T ID        {$$ = mk_elem(  EQUAL_OP, STRING_ST,
548                                                                                         URI_O, $3); 
549                                                         }
550                 | URI EQUAL_T MYSELF    { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
551                                                                                                 URI_O, 0);
552                                                                 }
553                 | URI EQUAL_T error { $$=0; yyerror("string expected"); }
554                 | URI MATCH STRING      { $$=mk_elem(   MATCH_OP, STRING_ST,
555                                                                                         URI_O, $3);
556                                                         }
557                 | URI MATCH ID          { $$=mk_elem(   MATCH_OP, STRING_ST,
558                                                                                         URI_O, $3);
559                                                         }
560                 | URI MATCH error {  $$=0; yyerror("string expected"); }
561                 | URI error     { $$=0; yyerror("invalid operator,"
562                                                                         " == or =~ expected");
563                                         }
564                 | SRCPORT EQUAL_T NUMBER        { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
565                                                                                                 SRCPORT_O, (void *) $3 ); }
566                 | SRCPORT EQUAL_T error { $$=0; yyerror("number expected"); }
567                 | SRCPORT error { $$=0; yyerror("equal operator expected"); }
568                 | DSTPORT EQUAL_T NUMBER        { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
569                                                                                                 DSTPORT_O, (void *) $3 ); }
570                 | DSTPORT EQUAL_T error { $$=0; yyerror("number expected"); }
571                 | DSTPORT error { $$=0; yyerror("equal operator expected"); }
572                 | PROTO EQUAL_T NUMBER  { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
573                                                                                                 PROTO_O, (void *) $3 ); }
574                 | PROTO EQUAL_T error { $$=0; yyerror("number expected"); }
575                 | PROTO error { $$=0; yyerror("equal operator expected"); }
576                 | AF EQUAL_T NUMBER     { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
577                                                                                                 AF_O, (void *) $3 ); }
578                 | AF EQUAL_T error { $$=0; yyerror("number expected"); }
579                 | AF error { $$=0; yyerror("equal operator expected"); }
580                 | SRCIP EQUAL_T ipnet   { $$=mk_elem(   EQUAL_OP, NET_ST,
581                                                                                                 SRCIP_O, $3);
582                                                                 }
583                 | SRCIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
584                                                                                                 SRCIP_O, $3);
585                                                                 }
586                 | SRCIP EQUAL_T host    { $$=mk_elem(   EQUAL_OP, STRING_ST,
587                                                                                                 SRCIP_O, $3);
588                                                                 }
589                 | SRCIP EQUAL_T MYSELF  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
590                                                                                                 SRCIP_O, 0);
591                                                                 }
592                 | SRCIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
593                                                  "expected" ); }
594                 | SRCIP MATCH STRING    { $$=mk_elem(   MATCH_OP, STRING_ST,
595                                                                                                 SRCIP_O, $3);
596                                                                 }
597                 | SRCIP MATCH ID                { $$=mk_elem(   MATCH_OP, STRING_ST,
598                                                                                                 SRCIP_O, $3);
599                                                                 }
600                 | SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
601                 | SRCIP error  { $$=0; 
602                                                  yyerror("invalid operator, == or =~ expected");}
603                 | DSTIP EQUAL_T ipnet   { $$=mk_elem(   EQUAL_OP, NET_ST,
604                                                                                                 DSTIP_O, $3);
605                                                                 }
606                 | DSTIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
607                                                                                                 DSTIP_O, $3);
608                                                                 }
609                 | DSTIP EQUAL_T host    { $$=mk_elem(   EQUAL_OP, STRING_ST,
610                                                                                                 DSTIP_O, $3);
611                                                                 }
612                 | DSTIP EQUAL_T MYSELF  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
613                                                                                                 DSTIP_O, 0);
614                                                                 }
615                 | DSTIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
616                                                                         "expected" ); }
617                 | DSTIP MATCH STRING    { $$=mk_elem(   MATCH_OP, STRING_ST,
618                                                                                                 DSTIP_O, $3);
619                                                                 }
620                 | DSTIP MATCH ID        { $$=mk_elem(   MATCH_OP, STRING_ST,
621                                                                                         DSTIP_O, $3);
622                                                         }
623                 | DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
624                 | DSTIP error { $$=0; 
625                                                 yyerror("invalid operator, == or =~ expected");}
626                 | MYSELF EQUAL_T URI    { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
627                                                                                                 URI_O, 0);
628                                                                 }
629                 | MYSELF EQUAL_T SRCIP  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
630                                                                                                 SRCIP_O, 0);
631                                                                 }
632                 | MYSELF EQUAL_T DSTIP  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
633                                                                                                 DSTIP_O, 0);
634                                                                 }
635                 | MYSELF EQUAL_T error {        $$=0; 
636                                                                         yyerror(" URI, SRCIP or DSTIP expected"); }
637                 | MYSELF error  { $$=0; yyerror ("invalid operator, == expected"); }
638                 | stm                           { $$=mk_elem( NO_OP, ACTIONS_ST, ACTION_O, $1 ); }
639                 | NUMBER                {$$=mk_elem( NO_OP, NUMBER_ST, NUMBER_O, (void*)$1 ); }
640         ;
641
642 ipnet:  ip SLASH ip     { $$=mk_net($1, $3); } 
643         | ip SLASH NUMBER       {       if (($3<0) || ($3>$1->len*8)){
644                                                                 yyerror("invalid bit number in netmask");
645                                                                 $$=0;
646                                                         }else{
647                                                                 $$=mk_net_bitlen($1, $3);
648                                                         /*
649                                                                 $$=mk_net($1, 
650                                                                                 htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
651                                                         */
652                                                         }
653                                                 }
654         | ip                            { $$=mk_net_bitlen($1, $1->len*8); }
655         | ip SLASH error        { $$=0;
656                                                  yyerror("netmask (eg:255.0.0.0 or 8) expected");
657                                                 }
658         ;
659
660 host:   ID                              { $$=$1; }
661         | host DOT ID           { $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
662                                                   if ($$==0){
663                                                         LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
664                                                                                 " failure while parsing host\n");
665                                                   }else{
666                                                         memcpy($$, $1, strlen($1));
667                                                         $$[strlen($1)]='.';
668                                                         memcpy($$+strlen($1)+1, $3, strlen($3));
669                                                         $$[strlen($1)+1+strlen($3)]=0;
670                                                   }
671                                                   pkg_free($1); pkg_free($3);
672                                                 }
673         | host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
674         ;
675
676
677 stm:            cmd                                             { $$=$1; }
678                 |       LBRACE actions RBRACE   { $$=$2; }
679         ;
680
681 actions:        actions action  {$$=append_action($1, $2); }
682                 | action                        {$$=$1;}
683                 | actions error { $$=0; yyerror("bad command"); }
684         ;
685
686 action:         cmd SEMICOLON {$$=$1;}
687                 | SEMICOLON /* null action */ {$$=0;}
688                 | cmd error { $$=0; yyerror("bad command: missing ';'?"); }
689         ;
690
691 if_cmd:         IF exp stm                              { $$=mk_action3( IF_T,
692                                                                                                          EXPR_ST,
693                                                                                                          ACTIONS_ST,
694                                                                                                          NOSUBTYPE,
695                                                                                                          $2,
696                                                                                                          $3,
697                                                                                                          0);
698                                                                         }
699                 |       IF exp stm ELSE stm             { $$=mk_action3( IF_T,
700                                                                                                          EXPR_ST,
701                                                                                                          ACTIONS_ST,
702                                                                                                          ACTIONS_ST,
703                                                                                                          $2,
704                                                                                                          $3,
705                                                                                                          $5);
706                                                                         }
707         ;
708
709 cmd:            FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
710                                                                                                                 STRING_ST,
711                                                                                                                 NUMBER_ST,
712                                                                                                                 $3,
713                                                                                                                 0);
714                                                                                 }
715                 | FORWARD LPAREN STRING RPAREN  { $$=mk_action( FORWARD_T,
716                                                                                                                 STRING_ST,
717                                                                                                                 NUMBER_ST,
718                                                                                                                 $3,
719                                                                                                                 0);
720                                                                                 }
721                 | FORWARD LPAREN ip RPAREN      { $$=mk_action( FORWARD_T,
722                                                                                                                 IP_ST,
723                                                                                                                 NUMBER_ST,
724                                                                                                                 (void*)$3,
725                                                                                                                 0);
726                                                                                 }
727                 | FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
728                                                                                                                                  STRING_ST,
729                                                                                                                                  NUMBER_ST,
730                                                                                                                                 $3,
731                                                                                                                                 (void*)$5);
732                                                                                                  }
733                 | FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T,
734                                                                                                                                  STRING_ST,
735                                                                                                                                  NUMBER_ST,
736                                                                                                                                 $3,
737                                                                                                                                 (void*)$5);
738                                                                                                         }
739                 | FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
740                                                                                                                                  IP_ST,
741                                                                                                                                  NUMBER_ST,
742                                                                                                                                  (void*)$3,
743                                                                                                                                 (void*)$5);
744                                                                                                   }
745                 | FORWARD LPAREN URIHOST COMMA URIPORT RPAREN {
746                                                                                                         $$=mk_action(FORWARD_T,
747                                                                                                                                  URIHOST_ST,
748                                                                                                                                  URIPORT_ST,
749                                                                                                                                 0,
750                                                                                                                                 0);
751                                                                                                         }
752                                                                                                         
753                                                                         
754                 | FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {
755                                                                                                         $$=mk_action(FORWARD_T,
756                                                                                                                                  URIHOST_ST,
757                                                                                                                                  NUMBER_ST,
758                                                                                                                                 0,
759                                                                                                                                 (void*)$5);
760                                                                                                         }
761                 | FORWARD LPAREN URIHOST RPAREN {
762                                                                                                         $$=mk_action(FORWARD_T,
763                                                                                                                                  URIHOST_ST,
764                                                                                                                                  NUMBER_ST,
765                                                                                                                                 0,
766                                                                                                                                 0);
767                                                                                 }
768                 | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
769                 | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward"
770                                                                                 "argument"); }
771                 | FORWARD_UDP LPAREN host RPAREN        { $$=mk_action( FORWARD_UDP_T,
772                                                                                                                 STRING_ST,
773                                                                                                                 NUMBER_ST,
774                                                                                                                 $3,
775                                                                                                                 0);
776                                                                                 }
777                 | FORWARD_UDP LPAREN STRING RPAREN      { $$=mk_action( FORWARD_UDP_T,
778                                                                                                                 STRING_ST,
779                                                                                                                 NUMBER_ST,
780                                                                                                                 $3,
781                                                                                                                 0);
782                                                                                 }
783                 | FORWARD_UDP LPAREN ip RPAREN  { $$=mk_action( FORWARD_UDP_T,
784                                                                                                                 IP_ST,
785                                                                                                                 NUMBER_ST,
786                                                                                                                 (void*)$3,
787                                                                                                                 0);
788                                                                                 }
789                 | FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
790                                                                                                                                 FORWARD_UDP_T,
791                                                                                                                                  STRING_ST,
792                                                                                                                                  NUMBER_ST,
793                                                                                                                                 $3,
794                                                                                                                                 (void*)$5);
795                                                                                                  }
796                 | FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
797                                                                                                                                 FORWARD_UDP_T,
798                                                                                                                                  STRING_ST,
799                                                                                                                                  NUMBER_ST,
800                                                                                                                                 $3,
801                                                                                                                                 (void*)$5);
802                                                                                                         }
803                 | FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(
804                                                                                                                                 FORWARD_UDP_T,
805                                                                                                                                  IP_ST,
806                                                                                                                                  NUMBER_ST,
807                                                                                                                                  (void*)$3,
808                                                                                                                                 (void*)$5);
809                                                                                                   }
810                 | FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {
811                                                                                                         $$=mk_action(FORWARD_UDP_T,
812                                                                                                                                  URIHOST_ST,
813                                                                                                                                  URIPORT_ST,
814                                                                                                                                 0,
815                                                                                                                                 0);
816                                                                                                         }
817                                                                                                         
818                                                                         
819                 | FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN {
820                                                                                                         $$=mk_action(FORWARD_UDP_T,
821                                                                                                                                  URIHOST_ST,
822                                                                                                                                  NUMBER_ST,
823                                                                                                                                 0,
824                                                                                                                                 (void*)$5);
825                                                                                                         }
826                 | FORWARD_UDP LPAREN URIHOST RPAREN {
827                                                                                                         $$=mk_action(FORWARD_UDP_T,
828                                                                                                                                  URIHOST_ST,
829                                                                                                                                  NUMBER_ST,
830                                                                                                                                 0,
831                                                                                                                                 0);
832                                                                                 }
833                 | FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
834                 | FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp"
835                                                                                 "argument"); }
836                 | FORWARD_TCP LPAREN host RPAREN        { $$=mk_action( FORWARD_TCP_T,
837                                                                                                                 STRING_ST,
838                                                                                                                 NUMBER_ST,
839                                                                                                                 $3,
840                                                                                                                 0);
841                                                                                 }
842                 | FORWARD_TCP LPAREN STRING RPAREN      { $$=mk_action( FORWARD_TCP_T,
843                                                                                                                 STRING_ST,
844                                                                                                                 NUMBER_ST,
845                                                                                                                 $3,
846                                                                                                                 0);
847                                                                                 }
848                 | FORWARD_TCP LPAREN ip RPAREN  { $$=mk_action( FORWARD_TCP_T,
849                                                                                                                 IP_ST,
850                                                                                                                 NUMBER_ST,
851                                                                                                                 (void*)$3,
852                                                                                                                 0);
853                                                                                 }
854                 | FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
855                                                                                                                                 FORWARD_TCP_T,
856                                                                                                                                  STRING_ST,
857                                                                                                                                  NUMBER_ST,
858                                                                                                                                 $3,
859                                                                                                                                 (void*)$5);
860                                                                                                  }
861                 | FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
862                                                                                                                                 FORWARD_TCP_T,
863                                                                                                                                  STRING_ST,
864                                                                                                                                  NUMBER_ST,
865                                                                                                                                 $3,
866                                                                                                                                 (void*)$5);
867                                                                                                         }
868                 | FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T,
869                                                                                                                                  IP_ST,
870                                                                                                                                  NUMBER_ST,
871                                                                                                                                  (void*)$3,
872                                                                                                                                 (void*)$5);
873                                                                                                   }
874                 | FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {
875                                                                                                         $$=mk_action(FORWARD_TCP_T,
876                                                                                                                                  URIHOST_ST,
877                                                                                                                                  URIPORT_ST,
878                                                                                                                                 0,
879                                                                                                                                 0);
880                                                                                                         }
881                                                                                                         
882                                                                         
883                 | FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN {
884                                                                                                         $$=mk_action(FORWARD_TCP_T,
885                                                                                                                                  URIHOST_ST,
886                                                                                                                                  NUMBER_ST,
887                                                                                                                                 0,
888                                                                                                                                 (void*)$5);
889                                                                                                         }
890                 | FORWARD_TCP LPAREN URIHOST RPAREN {
891                                                                                                         $$=mk_action(FORWARD_TCP_T,
892                                                                                                                                  URIHOST_ST,
893                                                                                                                                  NUMBER_ST,
894                                                                                                                                 0,
895                                                                                                                                 0);
896                                                                                 }
897                 | FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
898                 | FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp"
899                                                                                 "argument"); }
900                 | SEND LPAREN host RPAREN       { $$=mk_action( SEND_T,
901                                                                                                         STRING_ST,
902                                                                                                         NUMBER_ST,
903                                                                                                         $3,
904                                                                                                         0);
905                                                                         }
906                 | SEND LPAREN STRING RPAREN { $$=mk_action(     SEND_T,
907                                                                                                         STRING_ST,
908                                                                                                         NUMBER_ST,
909                                                                                                         $3,
910                                                                                                         0);
911                                                                         }
912                 | SEND LPAREN ip RPAREN         { $$=mk_action( SEND_T,
913                                                                                                         IP_ST,
914                                                                                                         NUMBER_ST,
915                                                                                                         (void*)$3,
916                                                                                                         0);
917                                                                         }
918                 | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action( SEND_T,
919                                                                                                                                 STRING_ST,
920                                                                                                                                 NUMBER_ST,
921                                                                                                                                 $3,
922                                                                                                                                 (void*)$5);
923                                                                                                 }
924                 | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action( SEND_T,
925                                                                                                                                 STRING_ST,
926                                                                                                                                 NUMBER_ST,
927                                                                                                                                 $3,
928                                                                                                                                 (void*)$5);
929                                                                                                 }
930                 | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(    SEND_T,
931                                                                                                                                 IP_ST,
932                                                                                                                                 NUMBER_ST,
933                                                                                                                                 (void*)$3,
934                                                                                                                                 (void*)$5);
935                                                                                            }
936                 | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
937                 | SEND LPAREN error RPAREN { $$=0; yyerror("bad send"
938                                                                                                         "argument"); }
939                 | SEND_TCP LPAREN host RPAREN   { $$=mk_action( SEND_TCP_T,
940                                                                                                         STRING_ST,
941                                                                                                         NUMBER_ST,
942                                                                                                         $3,
943                                                                                                         0);
944                                                                         }
945                 | SEND_TCP LPAREN STRING RPAREN { $$=mk_action( SEND_TCP_T,
946                                                                                                         STRING_ST,
947                                                                                                         NUMBER_ST,
948                                                                                                         $3,
949                                                                                                         0);
950                                                                         }
951                 | SEND_TCP LPAREN ip RPAREN             { $$=mk_action( SEND_TCP_T,
952                                                                                                         IP_ST,
953                                                                                                         NUMBER_ST,
954                                                                                                         (void*)$3,
955                                                                                                         0);
956                                                                         }
957                 | SEND_TCP LPAREN host COMMA NUMBER RPAREN      { $$=mk_action( SEND_TCP_T,
958                                                                                                                                 STRING_ST,
959                                                                                                                                 NUMBER_ST,
960                                                                                                                                 $3,
961                                                                                                                                 (void*)$5);
962                                                                                                 }
963                 | SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(     SEND_TCP_T,
964                                                                                                                                 STRING_ST,
965                                                                                                                                 NUMBER_ST,
966                                                                                                                                 $3,
967                                                                                                                                 (void*)$5);
968                                                                                                 }
969                 | SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(        SEND_TCP_T,
970                                                                                                                                 IP_ST,
971                                                                                                                                 NUMBER_ST,
972                                                                                                                                 (void*)$3,
973                                                                                                                                 (void*)$5);
974                                                                                            }
975                 | SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
976                 | SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp"
977                                                                                                         "argument"); }
978                 | DROP LPAREN RPAREN    {$$=mk_action(DROP_T,0, 0, 0, 0); }
979                 | DROP                                  {$$=mk_action(DROP_T,0, 0, 0, 0); }
980                 | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(  LOG_T, NUMBER_ST, 
981                                                                                                         STRING_ST,(void*)4,$3);
982                                                                         }
983                 | LOG_TOK LPAREN NUMBER COMMA STRING RPAREN     {$$=mk_action(  LOG_T,
984                                                                                                                                 NUMBER_ST, 
985                                                                                                                                 STRING_ST,
986                                                                                                                                 (void*)$3,
987                                                                                                                                 $5);
988                                                                                                 }
989                 | LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
990                 | LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
991                                                                         "argument"); }
992                 | SETFLAG LPAREN NUMBER RPAREN {$$=mk_action( SETFLAG_T, NUMBER_ST, 0,
993                                                                                                         (void *)$3, 0 ); }
994                 | SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
995
996                 | LEN_GT LPAREN NUMBER RPAREN {$$=mk_action( LEN_GT_T, NUMBER_ST, 0,
997                                                                                                         (void *)$3, 0 ); }
998                 | LEN_GT LPAREN MAX_LEN RPAREN {$$=mk_action( LEN_GT_T, NUMBER_ST, 0,
999                                                                                                         (void *) BUF_SIZE, 0 ); }
1000                 | LEN_GT error { $$=0; yyerror("missing '(' or ')'?"); }
1001
1002                 | RESETFLAG LPAREN NUMBER RPAREN {$$=mk_action( RESETFLAG_T, NUMBER_ST, 0,
1003                                                                                                         (void *)$3, 0 ); }
1004                 | RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
1005                 | ISFLAGSET LPAREN NUMBER RPAREN {$$=mk_action( ISFLAGSET_T, NUMBER_ST, 0,
1006                                                                                                         (void *)$3, 0 ); }
1007                 | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
1008                 | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
1009                                                                                                                                 STRING_ST, 
1010                                                                                                                                 STRING_ST,
1011                                                                                                                                 $3,
1012                                                                                                                                 $5);
1013                                                                                                   }
1014                 | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
1015                 | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
1016                                                                                                                 "argument"); }
1017                 | ROUTE LPAREN NUMBER RPAREN    { $$=mk_action(ROUTE_T, NUMBER_ST,
1018                                                                                                                 0, (void*)$3, 0);
1019                                                                                 }
1020                 | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
1021                 | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route"
1022                                                 "argument"); }
1023                 | EXEC LPAREN STRING RPAREN     { $$=mk_action( EXEC_T, STRING_ST, 0,
1024                                                                                                         $3, 0);
1025                                                                         }
1026                 | SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, STRING_ST,
1027                                                                                                                 0, $3, 0); }
1028                 | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
1029                 | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1030                                                                                                                 "string expected"); }
1031
1032                 | PREFIX LPAREN STRING RPAREN { $$=mk_action(PREFIX_T, STRING_ST,
1033                                                                                                                 0, $3, 0); }
1034                 | PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); }
1035                 | PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1036                                                                                                                 "string expected"); }
1037                 | STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, NUMBER_ST,
1038                                                                                                                 0, (void *) $3, 0); }
1039                 | STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
1040                 | STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1041                                                                                                                 "number expected"); }
1042
1043                 | APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T,
1044                                                                                                         STRING_ST, 0, $3, 0) ; }
1045                 | APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T,
1046                                                                                                         STRING_ST, 0, 0, 0 ) ; }
1047                 | APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; }
1048
1049                 | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, 
1050                                                                                                                 STRING_ST, 0, $3, 0); }
1051                 | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
1052                 | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument,"
1053                                                                                                 " string expected"); }
1054                 | SET_PORT LPAREN STRING RPAREN { $$=mk_action( SET_PORT_T, STRING_ST,
1055                                                                                                                 0, $3, 0); }
1056                 | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
1057                 | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1058                                                                                                                 "string expected"); }
1059                 | SET_USER LPAREN STRING RPAREN { $$=mk_action( SET_USER_T, STRING_ST,
1060                                                                                                                 0, $3, 0); }
1061                 | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
1062                 | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1063                                                                                                                 "string expected"); }
1064                 | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action( SET_USERPASS_T, 
1065                                                                                                                 STRING_ST, 0, $3, 0); }
1066                 | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
1067                 | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1068                                                                                                                 "string expected"); }
1069                 | SET_URI LPAREN STRING RPAREN { $$=mk_action( SET_URI_T, STRING_ST, 
1070                                                                                                                 0, $3, 0); }
1071                 | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
1072                 | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1073                                                                                 "string expected"); }
1074                 | REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1075                 | REVERT_URI { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1076                 | FORCE_RPORT LPAREN RPAREN     {$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1077                 | FORCE_RPORT                           {$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1078                 | ID LPAREN RPAREN                      { f_tmp=(void*)find_export($1, 0, rt);
1079                                                                            if (f_tmp==0){
1080                                                                                    if (find_export($1, 0, 0)) {
1081                                                                                            yyerror("Command cannot be used in the block\n");
1082                                                                                    } else {
1083                                                                                            yyerror("unknown command, missing"
1084                                                                                                    " loadmodule?\n");
1085                                                                                    }
1086                                                                                 $$=0;
1087                                                                            }else{
1088                                                                                 $$=mk_action(   MODULE_T,
1089                                                                                                                 CMDF_ST,
1090                                                                                                                 0,
1091                                                                                                                 f_tmp,
1092                                                                                                                 0
1093                                                                                                         );
1094                                                                            }
1095                                                                         }
1096                 | ID LPAREN STRING RPAREN { f_tmp=(void*)find_export($1, 1, rt);
1097                                                                         if (f_tmp==0){
1098                                                                                 if (find_export($1, 1, 0)) {
1099                                                                                         yyerror("Command cannot be used in the block\n");
1100                                                                                 } else {
1101                                                                                         yyerror("unknown command, missing"
1102                                                                                                 " loadmodule?\n");
1103                                                                                 }
1104                                                                                 $$=0;
1105                                                                         }else{
1106                                                                                 $$=mk_action(   MODULE_T,
1107                                                                                                                 CMDF_ST,
1108                                                                                                                 STRING_ST,
1109                                                                                                                 f_tmp,
1110                                                                                                                 $3
1111                                                                                                         );
1112                                                                         }
1113                                                                   }
1114                 | ID LPAREN STRING  COMMA STRING RPAREN 
1115                                                                   { f_tmp=(void*)find_export($1, 2, rt);
1116                                                                         if (f_tmp==0){
1117                                                                                 if (find_export($1, 2, 0)) {
1118                                                                                         yyerror("Command cannot be used in the block\n");
1119                                                                                 } else {
1120                                                                                         yyerror("unknown command, missing"
1121                                                                                                 " loadmodule?\n");
1122                                                                                 }
1123                                                                                 $$=0;
1124                                                                         }else{
1125                                                                                 $$=mk_action3(  MODULE_T,
1126                                                                                                                 CMDF_ST,
1127                                                                                                                 STRING_ST,
1128                                                                                                                 STRING_ST,
1129                                                                                                                 f_tmp,
1130                                                                                                                 $3,
1131                                                                                                                 $5
1132                                                                                                         );
1133                                                                         }
1134                                                                   }
1135                 | ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
1136                 | if_cmd                { $$=$1; }
1137         ;
1138
1139
1140 %%
1141
1142 extern int line;
1143 extern int column;
1144 extern int startcolumn;
1145 void yyerror(char* s)
1146 {
1147         LOG(L_CRIT, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
1148                         column, s);
1149         cfg_errors++;
1150 }
1151
1152 /*
1153 int main(int argc, char ** argv)
1154 {
1155         if (yyparse()!=0)
1156                 fprintf(stderr, "parsing error\n");
1157 }
1158 */