57bfb14a3590072864ccbcb73d0561774820a8ed
[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  * 2003-04-15  added tcp_children, disable_tcp (andrei)
41  * 2003-04-22  strip_tail added (jiri)
42  * 2003-07-03  tls* (disable, certificate, private_key, ca_list, verify,
43  *              require_certificate added (andrei)
44  * 2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
45  * 2003-10-02  added {,set_}advertised_{address,port} (andrei)
46  * 2003-10-10  added <,>,<=,>=, != operators support
47  *             added msg:len (andrei)
48  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
49  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
50  * 2003-10-24  converted to the new socket_info lists (andrei)
51  * 2003-10-28  added tcp_accept_aliases (andrei)
52  * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
53  * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
54  * 2004-04-29  added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
55  * 2004-05-03  applied multicast support patch (MCAST_LOOPBACK) from janakj
56  *             added MCAST_TTL (andrei)
57  * 2004-07-05  src_ip & dst_ip will detect ip addresses between quotes
58  *              (andrei)
59  * 2004-10-19  added FROM_URI, TO_URI (andrei)
60  * 2004-11-30  added force_send_socket (andrei)
61  * 2005-07-08  added TCP_CON_LIFETIME, TCP_POLL_METHOD, TCP_MAX_CONNECTIONS
62  *              (andrei)
63  * 2005-07-11 added DNS_RETR_TIME, DNS_RETR_NO, DNS_SERVERS_NO, DNS_USE_SEARCH,
64  *             DNS_TRY_IPV6 (andrei)
65  * 2005-07-12  default onreply route added (andrei)
66  * 2005-11-16  fixed if (cond) cmd; (andrei)
67  * 2005-12-11  added onsend_route support, fcmd (filtered cmd),
68  *             snd_{ip,port,proto,af}, to_{ip,proto} (andrei)
69  * 2005-12-19  select framework (mma)
70  * 2006-01-06  AVP index support (mma)
71  * 2005-01-07  optional semicolon in statement, PARAM_STR&PARAM_STRING
72  * 2006-02-02  named flags support (andrei)
73  * 2006-02-06  named routes support (andrei)
74  * 2006-05-30  avp flags (tma)
75  * 2006-09-11  added dns cache (use, flags, ttls, mem ,gc) & dst blacklist
76  *              options (andrei)
77  * 2006-10-13  added STUN_ALLOW_STUN, STUN_ALLOW_FP, STUN_REFRESH_INTERVAL
78  *              (vlada)
79  * 2007-02-09  separated command needed for tls-in-core and for tls in general
80  *              (andrei)
81  * 2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
82  *              RT_POLICY, RT_TIMER1_PRIO, RT_TIMER1_POLICY, RT_TIMER2_PRIO,
83  *              RT_TIMER2_POLICY (andrei)
84  * 2007-06-16  added DDNS_SRV_LB, DNS_TRY_NAPTR (andrei)
85  * 2007-09-10  introduced phone2tel option which allows NOT to consider
86  *             user=phone URIs as TEL URIs (jiri)
87  * 2007-10-10  added DNS_SEARCH_FMATCH (mma)
88  * 2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
89  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
90 */
91
92 %{
93
94 #include <stdlib.h>
95 #include <stdio.h>
96 #include <sys/types.h>
97 #include <sys/socket.h>
98 #include <netinet/in.h>
99 #include <arpa/inet.h>
100 #include <string.h>
101 #include <errno.h>
102 #include "route_struct.h"
103 #include "globals.h"
104 #include "route.h"
105 #include "dprint.h"
106 #include "sr_module.h"
107 #include "modparam.h"
108 #include "ip_addr.h"
109 #include "resolve.h"
110 #include "socket_info.h"
111 #include "name_alias.h"
112 #include "ut.h"
113 #include "dset.h"
114 #include "select.h"
115 #include "flags.h"
116 #include "tcp_init.h"
117 #include "tcp_options.h"
118
119 #include "config.h"
120 #ifdef CORE_TLS
121 #include "tls/tls_config.h"
122 #endif
123
124 #ifdef DEBUG_DMALLOC
125 #include <dmalloc.h>
126 #endif
127
128 /* hack to avoid alloca usage in the generated C file (needed for compiler
129  with no built in alloca, like icc*/
130 #undef _ALLOCA_H
131
132 #define onsend_check(s) \
133         do{\
134                 if (rt!=ONSEND_ROUTE) yyerror( s " allowed only in onsend_routes");\
135         }while(0)
136
137
138 #ifdef USE_DNS_CACHE
139         #define IF_DNS_CACHE(x) x
140 #else
141         #define IF_DNS_CACHE(x) warn("dns cache support not compiled in")
142 #endif
143
144 #ifdef USE_DNS_FAILOVER
145         #define IF_DNS_FAILOVER(x) x
146 #else
147         #define IF_DNS_FAILOVER(x) warn("dns failover support not compiled in")
148 #endif
149
150 #ifdef USE_NAPTR
151         #define IF_NAPTR(x) x
152 #else
153         #define IF_NAPTR(x) warn("dns naptr support not compiled in")
154 #endif
155
156 #ifdef USE_DST_BLACKLIST
157         #define IF_DST_BLACKLIST(x) x
158 #else
159         #define IF_DST_BLACKLIST(x) warn("dst blacklist support not compiled in")
160 #endif
161
162 #ifdef USE_STUN
163         #define IF_STUN(x) x
164 #else 
165         #define IF_STUN(x) warn("stun support not compiled in")
166 #endif
167
168
169 extern int yylex();
170 static void yyerror(char* s);
171 static char* tmp;
172 static int i_tmp;
173 static struct socket_id* lst_tmp;
174 static int rt;  /* Type of route block for find_export */
175 static str* str_tmp;
176 static str s_tmp;
177 static struct ip_addr* ip_tmp;
178 static struct avp_spec* s_attr;
179 static select_t sel;
180 static select_t* sel_ptr;
181 static struct action *mod_func_action;
182
183 static void warn(char* s);
184 static struct socket_id* mk_listen_id(char*, int, int);
185
186 %}
187
188 %union {
189         long intval;
190         unsigned long uval;
191         char* strval;
192         struct expr* expr;
193         struct action* action;
194         struct net* ipnet;
195         struct ip_addr* ipaddr;
196         struct socket_id* sockid;
197         struct avp_spec* attr;
198         select_t* select;
199 }
200
201 /* terminals */
202
203
204 /* keywords */
205 %token FORWARD
206 %token FORWARD_TCP
207 %token FORWARD_TLS
208 %token FORWARD_UDP
209 %token SEND
210 %token SEND_TCP
211 %token DROP
212 %token RETURN
213 %token BREAK
214 %token LOG_TOK
215 %token ERROR
216 %token ROUTE
217 %token ROUTE_FAILURE
218 %token ROUTE_ONREPLY
219 %token ROUTE_BRANCH
220 %token ROUTE_SEND
221 %token EXEC
222 %token SET_HOST
223 %token SET_HOSTPORT
224 %token PREFIX
225 %token STRIP
226 %token STRIP_TAIL
227 %token APPEND_BRANCH
228 %token SET_USER
229 %token SET_USERPASS
230 %token SET_PORT
231 %token SET_URI
232 %token REVERT_URI
233 %token FORCE_RPORT
234 %token FORCE_TCP_ALIAS
235 %token IF
236 %token ELSE
237 %token SET_ADV_ADDRESS
238 %token SET_ADV_PORT
239 %token FORCE_SEND_SOCKET
240 %token URIHOST
241 %token URIPORT
242 %token MAX_LEN
243 %token SETFLAG
244 %token RESETFLAG
245 %token ISFLAGSET
246 %token SETAVPFLAG
247 %token RESETAVPFLAG
248 %token ISAVPFLAGSET
249 %token METHOD
250 %token URI
251 %token FROM_URI
252 %token TO_URI
253 %token SRCIP
254 %token SRCPORT
255 %token DSTIP
256 %token DSTPORT
257 %token TOIP
258 %token TOPORT
259 %token SNDIP
260 %token SNDPORT
261 %token SNDPROTO
262 %token SNDAF
263 %token PROTO
264 %token AF
265 %token MYSELF
266 %token MSGLEN
267 %token RETCODE
268 %token UDP
269 %token TCP
270 %token TLS
271
272 /* config vars. */
273 %token DEBUG_V
274 %token FORK
275 %token LOGSTDERROR
276 %token LOGFACILITY
277 %token LISTEN
278 %token ALIAS
279 %token DNS
280 %token REV_DNS
281 %token DNS_TRY_IPV6
282 %token DNS_TRY_NAPTR
283 %token DNS_SRV_LB
284 %token DNS_UDP_PREF
285 %token DNS_TCP_PREF
286 %token DNS_TLS_PREF
287 %token DNS_RETR_TIME
288 %token DNS_RETR_NO
289 %token DNS_SERVERS_NO
290 %token DNS_USE_SEARCH
291 %token DNS_SEARCH_FMATCH
292 %token DNS_USE_CACHE
293 %token DNS_USE_FAILOVER
294 %token DNS_CACHE_FLAGS
295 %token DNS_CACHE_NEG_TTL
296 %token DNS_CACHE_MIN_TTL
297 %token DNS_CACHE_MAX_TTL
298 %token DNS_CACHE_MEM
299 %token DNS_CACHE_GC_INT
300 %token DNS_CACHE_DEL_NONEXP
301 /*blacklist*/
302 %token USE_DST_BLST
303 %token DST_BLST_MEM
304 %token DST_BLST_TTL
305 %token DST_BLST_GC_INT
306
307 %token PORT
308 %token STAT
309 %token CHILDREN
310 %token CHECK_VIA
311 %token PHONE2TEL
312 %token SYN_BRANCH
313 %token MEMLOG
314 %token MEMDBG
315 %token SIP_WARNING
316 %token SERVER_SIGNATURE
317 %token REPLY_TO_VIA
318 %token LOADMODULE
319 %token MODPARAM
320 %token MAXBUFFER
321 %token USER
322 %token GROUP
323 %token CHROOT
324 %token WDIR
325 %token MHOMED
326 %token DISABLE_TCP
327 %token TCP_ACCEPT_ALIASES
328 %token TCP_CHILDREN
329 %token TCP_CONNECT_TIMEOUT
330 %token TCP_SEND_TIMEOUT
331 %token TCP_CON_LIFETIME
332 %token TCP_POLL_METHOD
333 %token TCP_MAX_CONNECTIONS
334 %token TCP_SOURCE_IPV4
335 %token TCP_SOURCE_IPV6
336 %token TCP_OPT_FD_CACHE
337 %token TCP_OPT_BUF_WRITE
338 %token TCP_OPT_CONN_WQ_MAX
339 %token TCP_OPT_WQ_MAX
340 %token TCP_OPT_DEFER_ACCEPT
341 %token TCP_OPT_DELAYED_ACK
342 %token TCP_OPT_SYNCNT
343 %token TCP_OPT_LINGER2
344 %token TCP_OPT_KEEPALIVE
345 %token TCP_OPT_KEEPIDLE
346 %token TCP_OPT_KEEPINTVL
347 %token TCP_OPT_KEEPCNT
348 %token DISABLE_TLS
349 %token ENABLE_TLS
350 %token TLSLOG
351 %token TLS_PORT_NO
352 %token TLS_METHOD
353 %token TLS_HANDSHAKE_TIMEOUT
354 %token TLS_SEND_TIMEOUT
355 %token SSLv23
356 %token SSLv2
357 %token SSLv3
358 %token TLSv1
359 %token TLS_VERIFY
360 %token TLS_REQUIRE_CERTIFICATE
361 %token TLS_CERTIFICATE
362 %token TLS_PRIVATE_KEY
363 %token TLS_CA_LIST
364 %token ADVERTISED_ADDRESS
365 %token ADVERTISED_PORT
366 %token DISABLE_CORE
367 %token OPEN_FD_LIMIT
368 %token SHM_FORCE_ALLOC
369 %token MLOCK_PAGES
370 %token REAL_TIME
371 %token RT_PRIO
372 %token RT_POLICY
373 %token RT_TIMER1_PRIO
374 %token RT_TIMER1_POLICY
375 %token RT_TIMER2_PRIO
376 %token RT_TIMER2_POLICY
377 %token MCAST_LOOPBACK
378 %token MCAST_TTL
379 %token TOS
380 %token PMTU_DISCOVERY
381 %token KILL_TIMEOUT
382
383 %token FLAGS_DECL
384 %token AVPFLAGS_DECL
385
386 %token ATTR_MARK
387 %token SELECT_MARK
388 %token ATTR_FROM
389 %token ATTR_TO
390 %token ATTR_FROMURI
391 %token ATTR_TOURI
392 %token ATTR_FROMUSER
393 %token ATTR_TOUSER
394 %token ATTR_FROMDOMAIN
395 %token ATTR_TODOMAIN
396 %token ATTR_GLOBAL
397 %token ADDEQ
398
399 %token STUN_REFRESH_INTERVAL
400 %token STUN_ALLOW_STUN
401 %token STUN_ALLOW_FP
402
403
404 /* operators */
405 %nonassoc EQUAL
406 %nonassoc EQUAL_T
407 %nonassoc GT
408 %nonassoc LT
409 %nonassoc GTE
410 %nonassoc LTE
411 %nonassoc DIFF
412 %nonassoc MATCH
413 %left LOG_OR
414 %left LOG_AND
415 %left BIN_OR
416 %left BIN_AND
417 %left PLUS MINUS
418 %right NOT
419
420 /* values */
421 %token <intval> NUMBER
422 %token <strval> ID
423 %token <strval> STRING
424 %token <strval> IPV6ADDR
425
426 /* other */
427 %token COMMA
428 %token SEMICOLON
429 %token RPAREN
430 %token LPAREN
431 %token LBRACE
432 %token RBRACE
433 %token LBRACK
434 %token RBRACK
435 %token SLASH
436 %token DOT
437 %token CR
438 %token COLON
439 %token STAR
440
441
442 /*non-terminals */
443 %type <expr> exp exp_elem /*, condition*/
444 %type <action> action actions cmd fcmd if_cmd stm exp_stm assign_action
445 %type <ipaddr> ipv4 ipv6 ipv6addr ip
446 %type <ipnet> ipnet
447 %type <strval> host
448 %type <strval> listen_id
449 %type <sockid>  id_lst
450 %type <sockid>  phostport
451 %type <intval> proto port
452 %type <intval> equalop strop intop binop
453 %type <strval> host_sep
454 %type <intval> uri_type
455 %type <attr> attr_id
456 %type <attr> attr_id_num_idx
457 %type <attr> attr_id_no_idx
458 %type <attr> attr_id_ass
459 %type <attr> attr_id_val
460 %type <attr> attr_id_any
461 %type <attr> attr_id_any_str
462 /* %type <intval> class_id */
463 %type <intval> assign_op
464 %type <select> select_id
465 %type <strval>  flag_name;
466 %type <strval>  route_name;
467 %type <intval> avpflag_oper
468
469 /*%type <route_el> rules;
470   %type <route_el> rule;
471 */
472
473 %%
474
475
476 cfg:
477         statements
478         ;
479 statements:
480         statements statement {}
481         | statement {}
482         | statements error { yyerror(""); YYABORT;}
483         ;
484 statement:
485         assign_stm
486         | flags_decl
487         | avpflags_decl
488         | module_stm
489         | {rt=REQUEST_ROUTE;} route_stm
490         | {rt=FAILURE_ROUTE;} failure_route_stm
491         | {rt=ONREPLY_ROUTE;} onreply_route_stm
492         | {rt=BRANCH_ROUTE;} branch_route_stm
493         | {rt=ONSEND_ROUTE;}   send_route_stm
494         | SEMICOLON     /* null statement */
495         | CR    /* null statement*/
496         ;
497 listen_id:
498         ip {
499                 tmp=ip_addr2a($1);
500                 if (tmp==0) {
501                         LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
502                                         "address.\n");
503                         $$=0;
504                 } else {
505                         $$=pkg_malloc(strlen(tmp)+1);
506                         if ($$==0) {
507                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
508                                                 "memory.\n");
509                         } else {
510                                 strncpy($$, tmp, strlen(tmp)+1);
511                         }
512                 }
513         }
514         | STRING {
515                 $$=pkg_malloc(strlen($1)+1);
516                 if ($$==0) {
517                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
518                                                 "memory.\n");
519                 } else {
520                                 strncpy($$, $1, strlen($1)+1);
521                 }
522         }
523         | host {
524                 $$=pkg_malloc(strlen($1)+1);
525                 if ($$==0) {
526                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
527                                                 "memory.\n");
528                 } else {
529                                 strncpy($$, $1, strlen($1)+1);
530                 }
531         }
532         ;
533 proto:
534         UDP     { $$=PROTO_UDP; }
535         | TCP   { $$=PROTO_TCP; }
536         | TLS   { $$=PROTO_TLS; }
537         | STAR  { $$=0; }
538         ;
539 port:
540         NUMBER  { $$=$1; }
541         | STAR  { $$=0; }
542 ;
543 phostport:
544         listen_id               { $$=mk_listen_id($1, 0, 0); }
545         | listen_id COLON port  { $$=mk_listen_id($1, 0, $3); }
546         | proto COLON listen_id { $$=mk_listen_id($3, $1, 0); }
547         | proto COLON listen_id COLON port      { $$=mk_listen_id($3, $1, $5);}
548         | listen_id COLON error { $$=0; yyerror(" port number expected"); }
549         ;
550 id_lst:
551         phostport               {  $$=$1 ; }
552         | phostport id_lst      { $$=$1; $$->next=$2; }
553         ;
554
555 flags_decl:             FLAGS_DECL      flag_list
556                         |       FLAGS_DECL error { yyerror("flag list expected\n"); }
557 ;
558 flag_list:              flag_spec
559                         |       flag_spec COMMA flag_list
560 ;
561
562 flag_spec:              flag_name       { if (register_flag($1,-1)<0)
563                                                                 yyerror("register flag failed");
564                                                 }
565                         |       flag_name COLON NUMBER {
566                                                 if (register_flag($1, $3)<0)
567                                                                 yyerror("register flag failed");
568                                                                                 }
569 ;
570
571 flag_name:              STRING  { $$=$1; }
572                         |       ID              { $$=$1; }
573 ;
574
575 avpflags_decl:
576         AVPFLAGS_DECL avpflag_list
577         | AVPFLAGS_DECL error { yyerror("avpflag list expected\n"); }
578         ;
579 avpflag_list:
580         avpflag_spec
581         | avpflag_spec COMMA avpflag_list
582         ;
583 avpflag_spec:
584         flag_name {
585                 if (register_avpflag($1)==0)
586                         yyerror("cannot declare avpflag");
587         }
588         ;
589 assign_stm:
590         DEBUG_V EQUAL NUMBER { debug=$3; }
591         | DEBUG_V EQUAL error  { yyerror("number  expected"); }
592         | FORK  EQUAL NUMBER { dont_fork= ! $3; }
593         | FORK  EQUAL error  { yyerror("boolean value expected"); }
594         | LOGSTDERROR EQUAL NUMBER { if (!config_check) log_stderr=$3; }
595         | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
596         | LOGFACILITY EQUAL ID {
597                 if ( (i_tmp=str2facility($3))==-1)
598                         yyerror("bad facility (see syslog(3) man page)");
599                 if (!config_check)
600                         log_facility=i_tmp;
601         }
602         | LOGFACILITY EQUAL error { yyerror("ID expected"); }
603         | DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
604         | DNS EQUAL error { yyerror("boolean value expected"); }
605         | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
606         | REV_DNS EQUAL error { yyerror("boolean value expected"); }
607         | DNS_TRY_IPV6 EQUAL NUMBER   { dns_try_ipv6=$3; }
608         | DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
609         | DNS_TRY_NAPTR EQUAL NUMBER   { IF_NAPTR(dns_try_naptr=$3); }
610         | DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
611         | DNS_SRV_LB EQUAL NUMBER   { IF_DNS_FAILOVER(dns_srv_lb=$3); }
612         | DNS_SRV_LB error { yyerror("boolean value expected"); }
613         | DNS_UDP_PREF EQUAL NUMBER   { IF_NAPTR(dns_udp_pref=$3); }
614         | DNS_UDP_PREF error { yyerror("number expected"); }
615         | DNS_TCP_PREF EQUAL NUMBER   { IF_NAPTR(dns_tcp_pref=$3); }
616         | DNS_TCP_PREF error { yyerror("number expected"); }
617         | DNS_TLS_PREF EQUAL NUMBER   { IF_NAPTR(dns_tls_pref=$3); }
618         | DNS_TLS_PREF error { yyerror("number expected"); }
619         | DNS_RETR_TIME EQUAL NUMBER   { dns_retr_time=$3; }
620         | DNS_RETR_TIME error { yyerror("number expected"); }
621         | DNS_RETR_NO EQUAL NUMBER   { dns_retr_no=$3; }
622         | DNS_RETR_NO error { yyerror("number expected"); }
623         | DNS_SERVERS_NO EQUAL NUMBER   { dns_servers_no=$3; }
624         | DNS_SERVERS_NO error { yyerror("number expected"); }
625         | DNS_USE_SEARCH EQUAL NUMBER   { dns_search_list=$3; }
626         | DNS_USE_SEARCH error { yyerror("boolean value expected"); }
627         | DNS_SEARCH_FMATCH EQUAL NUMBER   { dns_search_fmatch=$3; }
628         | DNS_SEARCH_FMATCH error { yyerror("boolean value expected"); }
629         | DNS_USE_CACHE EQUAL NUMBER   { IF_DNS_CACHE(use_dns_cache=$3); }
630         | DNS_USE_CACHE error { yyerror("boolean value expected"); }
631         | DNS_USE_FAILOVER EQUAL NUMBER   { IF_DNS_FAILOVER(use_dns_failover=$3);}
632         | DNS_USE_FAILOVER error { yyerror("boolean value expected"); }
633         | DNS_CACHE_FLAGS EQUAL NUMBER   { IF_DNS_CACHE(dns_flags=$3); }
634         | DNS_CACHE_FLAGS error { yyerror("boolean value expected"); }
635         | DNS_CACHE_NEG_TTL EQUAL NUMBER   { IF_DNS_CACHE(dns_neg_cache_ttl=$3); }
636         | DNS_CACHE_NEG_TTL error { yyerror("boolean value expected"); }
637         | DNS_CACHE_MAX_TTL EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_max_ttl=$3); }
638         | DNS_CACHE_MAX_TTL error { yyerror("boolean value expected"); }
639         | DNS_CACHE_MIN_TTL EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_min_ttl=$3); }
640         | DNS_CACHE_MIN_TTL error { yyerror("boolean value expected"); }
641         | DNS_CACHE_MEM EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_max_mem=$3); }
642         | DNS_CACHE_MEM error { yyerror("boolean value expected"); }
643         | DNS_CACHE_GC_INT EQUAL NUMBER   { IF_DNS_CACHE(dns_timer_interval=$3); }
644         | DNS_CACHE_GC_INT error { yyerror("boolean value expected"); }
645         | DNS_CACHE_DEL_NONEXP EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_del_nonexp=$3); }
646         | DNS_CACHE_DEL_NONEXP error { yyerror("boolean value expected"); }
647         | USE_DST_BLST EQUAL NUMBER   { IF_DST_BLACKLIST(use_dst_blacklist=$3); }
648         | USE_DST_BLST error { yyerror("boolean value expected"); }
649         | DST_BLST_MEM EQUAL NUMBER   { IF_DST_BLACKLIST(blst_max_mem=$3); }
650         | DST_BLST_MEM error { yyerror("boolean value expected"); }
651         | DST_BLST_TTL EQUAL NUMBER   { IF_DST_BLACKLIST(blst_timeout=$3); }
652         | DST_BLST_TTL error { yyerror("boolean value expected"); }
653         | DST_BLST_GC_INT EQUAL NUMBER { IF_DST_BLACKLIST(blst_timer_interval=$3);}
654         | DST_BLST_GC_INT error { yyerror("boolean value expected"); }
655         | PORT EQUAL NUMBER   { port_no=$3; }
656         | STAT EQUAL STRING {
657                 #ifdef STATS
658                                 stat_file=$3;
659                 #endif
660         }
661         | MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
662         | MAXBUFFER EQUAL error { yyerror("number expected"); }
663         | PORT EQUAL error    { yyerror("number expected"); }
664         | CHILDREN EQUAL NUMBER { children_no=$3; }
665         | CHILDREN EQUAL error { yyerror("number expected"); }
666         | CHECK_VIA EQUAL NUMBER { check_via=$3; }
667         | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
668         | PHONE2TEL EQUAL NUMBER { phone2tel=$3; }
669         | PHONE2TEL EQUAL error { yyerror("boolean value expected"); }
670         | SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
671         | SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
672         | MEMLOG EQUAL NUMBER { memlog=$3; }
673         | MEMLOG EQUAL error { yyerror("int value expected"); }
674         | MEMDBG EQUAL NUMBER { memdbg=$3; }
675         | MEMDBG EQUAL error { yyerror("int value expected"); }
676         | SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
677         | SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
678         | USER EQUAL STRING     { user=$3; }
679         | USER EQUAL ID         { user=$3; }
680         | USER EQUAL error      { yyerror("string value expected"); }
681         | GROUP EQUAL STRING     { group=$3; }
682         | GROUP EQUAL ID         { group=$3; }
683         | GROUP EQUAL error      { yyerror("string value expected"); }
684         | CHROOT EQUAL STRING     { chroot_dir=$3; }
685         | CHROOT EQUAL ID         { chroot_dir=$3; }
686         | CHROOT EQUAL error      { yyerror("string value expected"); }
687         | WDIR EQUAL STRING     { working_dir=$3; }
688         | WDIR EQUAL ID         { working_dir=$3; }
689         | WDIR EQUAL error      { yyerror("string value expected"); }
690         | MHOMED EQUAL NUMBER { mhomed=$3; }
691         | MHOMED EQUAL error { yyerror("boolean value expected"); }
692         | DISABLE_TCP EQUAL NUMBER {
693                 #ifdef USE_TCP
694                         tcp_disable=$3;
695                 #else
696                         warn("tcp support not compiled in");
697                 #endif
698         }
699         | DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
700         | TCP_ACCEPT_ALIASES EQUAL NUMBER {
701                 #ifdef USE_TCP
702                         tcp_accept_aliases=$3;
703                 #else
704                         warn("tcp support not compiled in");
705                 #endif
706         }
707         | TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
708         | TCP_CHILDREN EQUAL NUMBER {
709                 #ifdef USE_TCP
710                         tcp_children_no=$3;
711                 #else
712                         warn("tcp support not compiled in");
713                 #endif
714         }
715         | TCP_CHILDREN EQUAL error { yyerror("number expected"); }
716         | TCP_CONNECT_TIMEOUT EQUAL NUMBER {
717                 #ifdef USE_TCP
718                         tcp_connect_timeout=$3;
719                 #else
720                         warn("tcp support not compiled in");
721                 #endif
722         }
723         | TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
724         | TCP_SEND_TIMEOUT EQUAL NUMBER {
725                 #ifdef USE_TCP
726                         tcp_send_timeout=$3;
727                 #else
728                         warn("tcp support not compiled in");
729                 #endif
730         }
731         | TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
732         | TCP_CON_LIFETIME EQUAL NUMBER {
733                 #ifdef USE_TCP
734                         tcp_con_lifetime=$3;
735                 #else
736                         warn("tcp support not compiled in");
737                 #endif
738         }
739         | TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
740         | TCP_POLL_METHOD EQUAL ID {
741                 #ifdef USE_TCP
742                         tcp_poll_method=get_poll_type($3);
743                         if (tcp_poll_method==POLL_NONE) {
744                                 LOG(L_CRIT, "bad poll method name:"
745                                                 " %s\n, try one of %s.\n",
746                                                 $3, poll_support);
747                                 yyerror("bad tcp_poll_method "
748                                                 "value");
749                         }
750                 #else
751                         warn("tcp support not compiled in");
752                 #endif
753         }
754         | TCP_POLL_METHOD EQUAL STRING {
755                 #ifdef USE_TCP
756                         tcp_poll_method=get_poll_type($3);
757                         if (tcp_poll_method==POLL_NONE) {
758                                 LOG(L_CRIT, "bad poll method name:"
759                                                 " %s\n, try one of %s.\n",
760                                                 $3, poll_support);
761                                 yyerror("bad tcp_poll_method "
762                                                 "value");
763                         }
764                 #else
765                         warn("tcp support not compiled in");
766                 #endif
767         }
768         | TCP_POLL_METHOD EQUAL error { yyerror("poll method name expected"); }
769         | TCP_MAX_CONNECTIONS EQUAL NUMBER {
770                 #ifdef USE_TCP
771                         tcp_max_connections=$3;
772                 #else
773                         warn("tcp support not compiled in");
774                 #endif
775         }
776         | TCP_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
777         | TCP_SOURCE_IPV4 EQUAL ipv4 {
778                 #ifdef USE_TCP
779                         if (tcp_set_src_addr($3)<0)
780                                 warn("tcp_source_ipv4 failed");
781                 #else
782                         warn("tcp support not compiled in");
783                 #endif
784                 pkg_free($3);
785         }
786         | TCP_SOURCE_IPV4 EQUAL error { yyerror("IPv4 address expected"); }
787         | TCP_SOURCE_IPV6 EQUAL ipv6 {
788                 #ifdef USE_TCP
789                         #ifdef USE_IPV6
790                                 if (tcp_set_src_addr($3)<0)
791                                         warn("tcp_source_ipv6 failed");
792                         #else
793                                 warn("IPv6 support not compiled in");
794                         #endif
795                 #else
796                         warn("tcp support not compiled in");
797                 #endif
798                 pkg_free($3);
799         }
800         | TCP_SOURCE_IPV6 EQUAL error { yyerror("IPv6 address expected"); }
801         | TCP_OPT_FD_CACHE EQUAL NUMBER {
802                 #ifdef USE_TCP
803                         tcp_options.fd_cache=$3;
804                 #else
805                         warn("tcp support not compiled in");
806                 #endif
807         }
808         | TCP_OPT_FD_CACHE EQUAL error { yyerror("boolean value expected"); }
809         | TCP_OPT_BUF_WRITE EQUAL NUMBER {
810                 #ifdef USE_TCP
811                         tcp_options.tcp_buf_write=$3;
812                 #else
813                         warn("tcp support not compiled in");
814                 #endif
815         }
816         | TCP_OPT_BUF_WRITE EQUAL error { yyerror("boolean value expected"); }
817         | TCP_OPT_CONN_WQ_MAX EQUAL NUMBER {
818                 #ifdef USE_TCP
819                         tcp_options.tcpconn_wq_max=$3;
820                 #else
821                         warn("tcp support not compiled in");
822                 #endif
823         }
824         | TCP_OPT_CONN_WQ_MAX error { yyerror("boolean value expected"); }
825         | TCP_OPT_WQ_MAX EQUAL NUMBER {
826                 #ifdef USE_TCP
827                         tcp_options.tcp_wq_max=$3;
828                 #else
829                         warn("tcp support not compiled in");
830                 #endif
831         }
832         | TCP_OPT_WQ_MAX error { yyerror("boolean value expected"); }
833         | TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
834                 #ifdef USE_TCP
835                         tcp_options.defer_accept=$3;
836                 #else
837                         warn("tcp support not compiled in");
838                 #endif
839         }
840         | TCP_OPT_DEFER_ACCEPT EQUAL error { yyerror("boolean value expected"); }
841         | TCP_OPT_DELAYED_ACK EQUAL NUMBER {
842                 #ifdef USE_TCP
843                         tcp_options.delayed_ack=$3;
844                 #else
845                         warn("tcp support not compiled in");
846                 #endif
847         }
848         | TCP_OPT_DELAYED_ACK EQUAL error { yyerror("boolean value expected"); }
849         | TCP_OPT_SYNCNT EQUAL NUMBER {
850                 #ifdef USE_TCP
851                         tcp_options.syncnt=$3;
852                 #else
853                         warn("tcp support not compiled in");
854                 #endif
855         }
856         | TCP_OPT_SYNCNT EQUAL error { yyerror("number expected"); }
857         | TCP_OPT_LINGER2 EQUAL NUMBER {
858                 #ifdef USE_TCP
859                         tcp_options.linger2=$3;
860                 #else
861                         warn("tcp support not compiled in");
862                 #endif
863         }
864         | TCP_OPT_LINGER2 EQUAL error { yyerror("number expected"); }
865         | TCP_OPT_KEEPALIVE EQUAL NUMBER {
866                 #ifdef USE_TCP
867                         tcp_options.keepalive=$3;
868                 #else
869                         warn("tcp support not compiled in");
870                 #endif
871         }
872         | TCP_OPT_KEEPALIVE EQUAL error { yyerror("boolean value expected");}
873         | TCP_OPT_KEEPIDLE EQUAL NUMBER {
874                 #ifdef USE_TCP
875                         tcp_options.keepidle=$3;
876                 #else
877                         warn("tcp support not compiled in");
878                 #endif
879         }
880         | TCP_OPT_KEEPIDLE EQUAL error { yyerror("number expected"); }
881         | TCP_OPT_KEEPINTVL EQUAL NUMBER {
882                 #ifdef USE_TCP
883                         tcp_options.keepintvl=$3;
884                 #else
885                         warn("tcp support not compiled in");
886                 #endif
887         }
888         | TCP_OPT_KEEPINTVL EQUAL error { yyerror("number expected"); }
889         | TCP_OPT_KEEPCNT EQUAL NUMBER {
890                 #ifdef USE_TCP
891                         tcp_options.keepcnt=$3;
892                 #else
893                         warn("tcp support not compiled in");
894                 #endif
895         }
896         | TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
897         | DISABLE_TLS EQUAL NUMBER {
898                 #ifdef USE_TLS
899                         tls_disable=$3;
900                 #else
901                         warn("tls support not compiled in");
902                 #endif
903         }
904         | DISABLE_TLS EQUAL error { yyerror("boolean value expected"); }
905         | ENABLE_TLS EQUAL NUMBER {
906                 #ifdef USE_TLS
907                         tls_disable=!($3);
908                 #else
909                         warn("tls support not compiled in");
910                 #endif
911         }
912         | ENABLE_TLS EQUAL error { yyerror("boolean value expected"); }
913         | TLSLOG EQUAL NUMBER {
914                 #ifdef CORE_TLS
915                         tls_log=$3;
916                 #else
917                         warn("tls-in-core support not compiled in");
918                 #endif
919         }
920         | TLSLOG EQUAL error { yyerror("int value expected"); }
921         | TLS_PORT_NO EQUAL NUMBER {
922                 #ifdef USE_TLS
923                         tls_port_no=$3;
924                 #else
925                         warn("tls support not compiled in");
926                 #endif
927         }
928         | TLS_PORT_NO EQUAL error { yyerror("number expected"); }
929         | TLS_METHOD EQUAL SSLv23 {
930                 #ifdef CORE_TLS
931                         tls_method=TLS_USE_SSLv23;
932                 #else
933                         warn("tls-in-core support not compiled in");
934                 #endif
935         }
936         | TLS_METHOD EQUAL SSLv2 {
937                 #ifdef CORE_TLS
938                         tls_method=TLS_USE_SSLv2;
939                 #else
940                         warn("tls-in-core support not compiled in");
941                 #endif
942         }
943         | TLS_METHOD EQUAL SSLv3 {
944                 #ifdef CORE_TLS
945                         tls_method=TLS_USE_SSLv3;
946                 #else
947                         warn("tls-in-core support not compiled in");
948                 #endif
949         }
950         | TLS_METHOD EQUAL TLSv1 {
951                 #ifdef CORE_TLS
952                         tls_method=TLS_USE_TLSv1;
953                 #else
954                         warn("tls-in-core support not compiled in");
955                 #endif
956         }
957         | TLS_METHOD EQUAL error {
958                 #ifdef CORE_TLS
959                         yyerror("SSLv23, SSLv2, SSLv3 or TLSv1 expected");
960                 #else
961                         warn("tls-in-core support not compiled in");
962                 #endif
963         }
964         | TLS_VERIFY EQUAL NUMBER {
965                 #ifdef CORE_TLS
966                         tls_verify_cert=$3;
967                 #else
968                         warn("tls-in-core support not compiled in");
969                 #endif
970         }
971         | TLS_VERIFY EQUAL error { yyerror("boolean value expected"); }
972         | TLS_REQUIRE_CERTIFICATE EQUAL NUMBER {
973                 #ifdef CORE_TLS
974                         tls_require_cert=$3;
975                 #else
976                         warn( "tls-in-core support not compiled in");
977                 #endif
978         }
979         | TLS_REQUIRE_CERTIFICATE EQUAL error { yyerror("boolean value expected"); }
980         | TLS_CERTIFICATE EQUAL STRING {
981                 #ifdef CORE_TLS
982                         tls_cert_file=$3;
983                 #else
984                         warn("tls-in-core support not compiled in");
985                 #endif
986         }
987         | TLS_CERTIFICATE EQUAL error { yyerror("string value expected"); }
988         | TLS_PRIVATE_KEY EQUAL STRING {
989                 #ifdef CORE_TLS
990                         tls_pkey_file=$3;
991                 #else
992                         warn("tls-in-core support not compiled in");
993                 #endif
994         }
995         | TLS_PRIVATE_KEY EQUAL error { yyerror("string value expected"); }
996         | TLS_CA_LIST EQUAL STRING {
997                 #ifdef CORE_TLS
998                         tls_ca_file=$3;
999                 #else
1000                         warn("tls-in-core support not compiled in");
1001                 #endif
1002         }
1003         | TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
1004         | TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
1005                 #ifdef CORE_TLS
1006                         tls_handshake_timeout=$3;
1007                 #else
1008                         warn("tls-in-core support not compiled in");
1009                 #endif
1010         }
1011         | TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
1012         | TLS_SEND_TIMEOUT EQUAL NUMBER {
1013                 #ifdef CORE_TLS
1014                         tls_send_timeout=$3;
1015                 #else
1016                         warn("tls-in-core support not compiled in");
1017                 #endif
1018         }
1019         | TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
1020         | SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
1021         | SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
1022         | REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
1023         | REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
1024         | LISTEN EQUAL id_lst {
1025                 for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1026                         if (add_listen_iface(lst_tmp->name, lst_tmp->port, lst_tmp->proto, 0)!=0) {
1027                                 LOG(L_CRIT,  "ERROR: cfg. parser: failed to add listen address\n");
1028                                 break;
1029                         }
1030                 }
1031         }
1032         | LISTEN EQUAL  error { yyerror("ip address or hostname expected"); }
1033         | ALIAS EQUAL  id_lst {
1034                 for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
1035                         add_alias(lst_tmp->name, strlen(lst_tmp->name), lst_tmp->port, lst_tmp->proto);
1036         }
1037         | ALIAS  EQUAL error  { yyerror(" hostname expected"); }
1038         | ADVERTISED_ADDRESS EQUAL listen_id {
1039                 default_global_address.s=$3;
1040                 default_global_address.len=strlen($3);
1041         }
1042         | ADVERTISED_ADDRESS EQUAL error {yyerror("ip address or hostname expected"); }
1043         | ADVERTISED_PORT EQUAL NUMBER {
1044                 tmp=int2str($3, &i_tmp);
1045                 if ((default_global_port.s=pkg_malloc(i_tmp))==0) {
1046                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1047                         default_global_port.len=0;
1048                 } else {
1049                         default_global_port.len=i_tmp;
1050                         memcpy(default_global_port.s, tmp, default_global_port.len);
1051                 };
1052         }
1053         |ADVERTISED_PORT EQUAL error {yyerror("ip address or hostname expected"); }
1054         | DISABLE_CORE EQUAL NUMBER { disable_core_dump=$3; }
1055         | DISABLE_CORE EQUAL error { yyerror("boolean value expected"); }
1056         | OPEN_FD_LIMIT EQUAL NUMBER { open_files_limit=$3; }
1057         | OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); }
1058         | SHM_FORCE_ALLOC EQUAL NUMBER { shm_force_alloc=$3; }
1059         | SHM_FORCE_ALLOC EQUAL error { yyerror("boolean value expected"); }
1060         | MLOCK_PAGES EQUAL NUMBER { mlock_pages=$3; }
1061         | MLOCK_PAGES EQUAL error { yyerror("boolean value expected"); }
1062         | REAL_TIME EQUAL NUMBER { real_time=$3; }
1063         | REAL_TIME EQUAL error { yyerror("boolean value expected"); }
1064         | RT_PRIO EQUAL NUMBER { rt_prio=$3; }
1065         | RT_PRIO EQUAL error { yyerror("boolean value expected"); }
1066         | RT_POLICY EQUAL NUMBER { rt_policy=$3; }
1067         | RT_POLICY EQUAL error { yyerror("boolean value expected"); }
1068         | RT_TIMER1_PRIO EQUAL NUMBER { rt_timer1_prio=$3; }
1069         | RT_TIMER1_PRIO EQUAL error { yyerror("boolean value expected"); }
1070         | RT_TIMER1_POLICY EQUAL NUMBER { rt_timer1_policy=$3; }
1071         | RT_TIMER1_POLICY EQUAL error { yyerror("boolean value expected"); }
1072         | RT_TIMER2_PRIO EQUAL NUMBER { rt_timer2_prio=$3; }
1073         | RT_TIMER2_PRIO EQUAL error { yyerror("boolean value expected"); }
1074         | RT_TIMER2_POLICY EQUAL NUMBER { rt_timer2_policy=$3; }
1075         | RT_TIMER2_POLICY EQUAL error { yyerror("boolean value expected"); }
1076         | MCAST_LOOPBACK EQUAL NUMBER {
1077                 #ifdef USE_MCAST
1078                         mcast_loopback=$3;
1079                 #else
1080                         warn("no multicast support compiled in");
1081                 #endif
1082         }
1083         | MCAST_LOOPBACK EQUAL error { yyerror("boolean value expected"); }
1084         | MCAST_TTL EQUAL NUMBER {
1085                 #ifdef USE_MCAST
1086                         mcast_ttl=$3;
1087                 #else
1088                         warn("no multicast support compiled in");
1089                 #endif
1090         }
1091         | MCAST_TTL EQUAL error { yyerror("number expected"); }
1092         | TOS EQUAL NUMBER { tos=$3; }
1093         | TOS EQUAL error { yyerror("number expected"); }
1094         | PMTU_DISCOVERY EQUAL NUMBER { pmtu_discovery=$3; }
1095         | PMTU_DISCOVERY error { yyerror("number expected"); }
1096         | KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
1097         | KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
1098         | STUN_REFRESH_INTERVAL EQUAL NUMBER { IF_STUN(stun_refresh_interval=$3); }
1099         | STUN_REFRESH_INTERVAL EQUAL error{ yyerror("number expected"); }
1100         | STUN_ALLOW_STUN EQUAL NUMBER { IF_STUN(stun_allow_stun=$3); }
1101         | STUN_ALLOW_STUN EQUAL error{ yyerror("number expected"); }
1102         | STUN_ALLOW_FP EQUAL NUMBER { IF_STUN(stun_allow_fp=$3) ; }
1103         | STUN_ALLOW_FP EQUAL error{ yyerror("number expected"); }
1104         | error EQUAL { yyerror("unknown config variable"); }
1105         ;
1106 module_stm:
1107         LOADMODULE STRING {
1108                 DBG("loading module %s\n", $2);
1109                         if (load_module($2)!=0) {
1110                                 yyerror("failed to load module");
1111                         }
1112         }
1113         | LOADMODULE error      { yyerror("string expected"); }
1114         | MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
1115                 if (set_mod_param_regex($3, $5, PARAM_STRING, $7) != 0) {
1116                          yyerror("Can't set module parameter");
1117                 }
1118         }
1119         | MODPARAM LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
1120                 if (set_mod_param_regex($3, $5, PARAM_INT, (void*)$7) != 0) {
1121                          yyerror("Can't set module parameter");
1122                 }
1123         }
1124         | MODPARAM error { yyerror("Invalid arguments"); }
1125         ;
1126 ip:
1127         ipv4  { $$=$1; }
1128         | ipv6  { $$=$1; }
1129         ;
1130 ipv4:
1131         NUMBER DOT NUMBER DOT NUMBER DOT NUMBER {
1132                 $$=pkg_malloc(sizeof(struct ip_addr));
1133                 if ($$==0) {
1134                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1135                 } else {
1136                         memset($$, 0, sizeof(struct ip_addr));
1137                         $$->af=AF_INET;
1138                         $$->len=4;
1139                         if (($1>255) || ($1<0) ||
1140                                 ($3>255) || ($3<0) ||
1141                                 ($5>255) || ($5<0) ||
1142                                 ($7>255) || ($7<0)) {
1143                                 yyerror("invalid ipv4 address");
1144                                 $$->u.addr32[0]=0;
1145                                 /* $$=0; */
1146                         } else {
1147                                 $$->u.addr[0]=$1;
1148                                 $$->u.addr[1]=$3;
1149                                 $$->u.addr[2]=$5;
1150                                 $$->u.addr[3]=$7;
1151                                 /*
1152                                 $$=htonl( ($1<<24)|
1153                                 ($3<<16)| ($5<<8)|$7 );
1154                                 */
1155                         }
1156                 }
1157         }
1158         ;
1159 ipv6addr:
1160         IPV6ADDR {
1161                 $$=pkg_malloc(sizeof(struct ip_addr));
1162                 if ($$==0) {
1163                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1164                 } else {
1165                         memset($$, 0, sizeof(struct ip_addr));
1166                         $$->af=AF_INET6;
1167                         $$->len=16;
1168                 #ifdef USE_IPV6
1169                         if (inet_pton(AF_INET6, $1, $$->u.addr)<=0) {
1170                                 yyerror("bad ipv6 address");
1171                         }
1172                 #else
1173                         yyerror("ipv6 address & no ipv6 support compiled in");
1174                         YYABORT;
1175                 #endif
1176                 }
1177         }
1178         ;
1179 ipv6:
1180         ipv6addr { $$=$1; }
1181         | LBRACK ipv6addr RBRACK {$$=$2; }
1182 ;
1183
1184
1185 route_name:             NUMBER  {
1186                                         tmp=int2str($1, &i_tmp);
1187                                         if (($$=pkg_malloc(i_tmp+1))==0) {
1188                                                 yyerror("out of  memory");
1189                                                 YYABORT;
1190                                         } else {
1191                                                 memcpy($$, tmp, i_tmp);
1192                                                 $$[i_tmp]=0;
1193                                         }
1194                                                 }
1195                         |       ID              { $$=$1; }
1196                         |       STRING  { $$=$1; }
1197 ;
1198
1199 route_stm:
1200         ROUTE LBRACE actions RBRACE { push($3, &main_rt.rlist[DEFAULT_RT]); }
1201         | ROUTE LBRACK route_name RBRACK LBRACE actions RBRACE {
1202                 i_tmp=route_get(&main_rt, $3);
1203                 if (i_tmp==-1){
1204                         yyerror("internal error");
1205                         YYABORT;
1206                 }
1207                 if (main_rt.rlist[i_tmp]){
1208                         yyerror("duplicate route");
1209                         YYABORT;
1210                 }
1211                 push($6, &main_rt.rlist[i_tmp]);
1212         }
1213         | ROUTE error { yyerror("invalid  route  statement"); }
1214         ;
1215 failure_route_stm:
1216         ROUTE_FAILURE LBRACE actions RBRACE {
1217                                                                         push($3, &failure_rt.rlist[DEFAULT_RT]);
1218                                                                                 }
1219         | ROUTE_FAILURE LBRACK route_name RBRACK LBRACE actions RBRACE {
1220                 i_tmp=route_get(&failure_rt, $3);
1221                 if (i_tmp==-1){
1222                         yyerror("internal error");
1223                         YYABORT;
1224                 }
1225                 if (failure_rt.rlist[i_tmp]){
1226                         yyerror("duplicate route");
1227                         YYABORT;
1228                 }
1229                 push($6, &failure_rt.rlist[i_tmp]);
1230         }
1231         | ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
1232         ;
1233 onreply_route_stm:
1234         ROUTE_ONREPLY LBRACE actions RBRACE {
1235                                                                         push($3, &onreply_rt.rlist[DEFAULT_RT]);
1236                                                                                 }
1237         | ROUTE_ONREPLY LBRACK route_name RBRACK LBRACE actions RBRACE {
1238                 i_tmp=route_get(&onreply_rt, $3);
1239                 if (i_tmp==-1){
1240                         yyerror("internal error");
1241                         YYABORT;
1242                 }
1243                 if (onreply_rt.rlist[i_tmp]){
1244                         yyerror("duplicate route");
1245                         YYABORT;
1246                 }
1247                 push($6, &onreply_rt.rlist[i_tmp]);
1248         }
1249         | ROUTE_ONREPLY error { yyerror("invalid onreply_route statement"); }
1250         ;
1251 branch_route_stm:
1252         ROUTE_BRANCH LBRACE actions RBRACE {
1253                                                                         push($3, &branch_rt.rlist[DEFAULT_RT]);
1254                                                                                 }
1255         | ROUTE_BRANCH LBRACK route_name RBRACK LBRACE actions RBRACE {
1256                 i_tmp=route_get(&branch_rt, $3);
1257                 if (i_tmp==-1){
1258                         yyerror("internal error");
1259                         YYABORT;
1260                 }
1261                 if (branch_rt.rlist[i_tmp]){
1262                         yyerror("duplicate route");
1263                         YYABORT;
1264                 }
1265                 push($6, &branch_rt.rlist[i_tmp]);
1266         }
1267         | ROUTE_BRANCH error { yyerror("invalid branch_route statement"); }
1268         ;
1269 send_route_stm: ROUTE_SEND LBRACE actions RBRACE {
1270                                                                         push($3, &onsend_rt.rlist[DEFAULT_RT]);
1271                                                                                                 }
1272         | ROUTE_SEND LBRACK route_name RBRACK LBRACE actions RBRACE {
1273                 i_tmp=route_get(&onsend_rt, $3);
1274                 if (i_tmp==-1){
1275                         yyerror("internal error");
1276                         YYABORT;
1277                 }
1278                 if (onsend_rt.rlist[i_tmp]){
1279                         yyerror("duplicate route");
1280                         YYABORT;
1281                 }
1282                 push($6, &onsend_rt.rlist[i_tmp]);
1283         }
1284         | ROUTE_SEND error { yyerror("invalid onsend_route statement"); }
1285         ;
1286 /*
1287 rules:
1288         rules rule { push($2, &$1); $$=$1; }
1289         | rule {$$=$1; }
1290         | rules error { $$=0; yyerror("invalid rule"); }
1291         ;
1292 rule:
1293         condition actions CR {
1294                 $$=0;
1295                 if (add_rule($1, $2, &$$)<0) {
1296                         yyerror("error calling add_rule");
1297                         YYABORT;
1298                 }
1299         }
1300         | CR    { $$=0;}
1301         | condition error { $$=0; yyerror("bad actions in rule"); }
1302         ;
1303 condition:
1304         exp {$$=$1;}
1305 */
1306 exp:    exp LOG_AND exp         { $$=mk_exp(LOGAND_OP, $1, $3); }
1307         | exp LOG_OR exp        { $$=mk_exp(LOGOR_OP, $1, $3);  }
1308         | NOT exp               { $$=mk_exp(NOT_OP, $2, 0);  }
1309         | LPAREN exp RPAREN     { $$=$2; }
1310         | exp_elem              { $$=$1; }
1311         ;
1312 equalop:
1313         EQUAL_T {$$=EQUAL_OP; }
1314         | DIFF  {$$=DIFF_OP; }
1315         ;
1316 intop:  equalop {$$=$1; }
1317         | GT    {$$=GT_OP; }
1318         | LT    {$$=LT_OP; }
1319         | GTE   {$$=GTE_OP; }
1320         | LTE   {$$=LTE_OP; }
1321         ;
1322 binop :
1323         BIN_OR { $$= BINOR_OP; }
1324         | BIN_AND { $$ = BINAND_OP; }
1325         ;
1326 strop:
1327         equalop {$$=$1; }
1328         | MATCH {$$=MATCH_OP; }
1329         ;
1330 uri_type:
1331         URI             {$$=URI_O;}
1332         | FROM_URI      {$$=FROM_URI_O;}
1333         | TO_URI        {$$=TO_URI_O;}
1334         ;
1335
1336 exp_elem:
1337         METHOD strop STRING     {$$= mk_elem($2, METHOD_O, 0, STRING_ST, $3);}
1338         | METHOD strop attr_id_val  {$$ = mk_elem($2, METHOD_O, 0, AVP_ST, $3); }
1339         | METHOD strop select_id {$$ = mk_elem($2, METHOD_O, 0, SELECT_ST, $3); }
1340         | METHOD strop  ID      {$$ = mk_elem($2, METHOD_O, 0, STRING_ST,$3); }
1341         | METHOD strop error { $$=0; yyerror("string expected"); }
1342         | METHOD error  { $$=0; yyerror("invalid operator,== , !=, or =~ expected"); }
1343         | uri_type strop STRING {$$ = mk_elem($2, $1, 0, STRING_ST, $3); }
1344         | uri_type strop host   {$$ = mk_elem($2, $1, 0, STRING_ST, $3); }
1345         | uri_type strop attr_id_val {$$ = mk_elem($2, $1, 0, AVP_ST, $3); }
1346         | uri_type strop select_id {$$ = mk_elem($2, $1, 0, SELECT_ST, $3); }
1347         | uri_type equalop MYSELF {$$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
1348         | uri_type strop error { $$=0; yyerror("string or MYSELF expected"); }
1349         | uri_type error        { $$=0; yyerror("invalid operator, == , != or =~ expected"); }
1350
1351         | SRCPORT intop NUMBER { $$=mk_elem($2, SRCPORT_O, 0, NUMBER_ST, (void*)$3 ); }
1352         | SRCPORT intop attr_id_val { $$=mk_elem($2, SRCPORT_O, 0, AVP_ST, (void*)$3 ); }
1353         | SRCPORT intop error { $$=0; yyerror("number expected"); }
1354         | SRCPORT error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
1355
1356         | DSTPORT intop NUMBER  { $$=mk_elem($2, DSTPORT_O, 0, NUMBER_ST, (void*)$3 ); }
1357         | DSTPORT intop attr_id_val     { $$=mk_elem($2, DSTPORT_O, 0, AVP_ST, (void*)$3 ); }
1358         | DSTPORT intop error { $$=0; yyerror("number expected"); }
1359         | DSTPORT error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
1360
1361         | SNDPORT intop NUMBER {
1362                 onsend_check("snd_port");
1363                 $$=mk_elem($2, SNDPORT_O, 0, NUMBER_ST, (void*)$3 );
1364         }
1365         | SNDPORT intop attr_id_val {
1366                 onsend_check("snd_port");
1367                 $$=mk_elem($2, SNDPORT_O, 0, AVP_ST, (void*)$3 );
1368         }
1369         | SNDPORT intop error { $$=0; yyerror("number expected"); }
1370         | SNDPORT error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
1371
1372         | TOPORT intop NUMBER {
1373                 onsend_check("to_port");
1374                 $$=mk_elem($2, TOPORT_O, 0, NUMBER_ST, (void*)$3 );
1375         }
1376         | TOPORT intop attr_id_val {
1377                 onsend_check("to_port");
1378                 $$=mk_elem($2, TOPORT_O, 0, AVP_ST, (void*)$3 );
1379         }
1380         | TOPORT intop error { $$=0; yyerror("number expected"); }
1381         | TOPORT error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
1382
1383         | PROTO intop proto     { $$=mk_elem($2, PROTO_O, 0, NUMBER_ST, (void*)$3 ); }
1384         | PROTO intop attr_id_val       { $$=mk_elem($2, PROTO_O, 0, AVP_ST, (void*)$3 ); }
1385         | PROTO intop error { $$=0; yyerror("protocol expected (udp, tcp or tls)"); }
1386
1387         | PROTO error { $$=0; yyerror("equal/!= operator expected"); }
1388
1389         | SNDPROTO intop proto  {
1390                 onsend_check("snd_proto");
1391                 $$=mk_elem($2, SNDPROTO_O, 0, NUMBER_ST, (void*)$3 );
1392         }
1393         | SNDPROTO intop attr_id_val {
1394                 onsend_check("snd_proto");
1395                 $$=mk_elem($2, SNDPROTO_O, 0, AVP_ST, (void*)$3 );
1396         }
1397         | SNDPROTO intop error { $$=0; yyerror("protocol expected (udp, tcp or tls)"); }
1398         | SNDPROTO error { $$=0; yyerror("equal/!= operator expected"); }
1399
1400         | AF intop NUMBER       { $$=mk_elem($2, AF_O, 0, NUMBER_ST,(void *) $3 ); }
1401         | AF intop attr_id_val  { $$=mk_elem($2, AF_O, 0, AVP_ST,(void *) $3 ); }
1402         | AF intop error { $$=0; yyerror("number expected"); }
1403         | AF error { $$=0; yyerror("equal/!= operator expected"); }
1404
1405         | SNDAF intop NUMBER {
1406                 onsend_check("snd_af");
1407                 $$=mk_elem($2, SNDAF_O, 0, NUMBER_ST, (void *) $3 ); }
1408         | SNDAF intop attr_id_val {
1409                 onsend_check("snd_af");
1410                 $$=mk_elem($2, SNDAF_O, 0, AVP_ST, (void *) $3 );
1411         }
1412         | SNDAF intop error { $$=0; yyerror("number expected"); }
1413         | SNDAF error { $$=0; yyerror("equal/!= operator expected"); }
1414
1415         | MSGLEN intop NUMBER           { $$=mk_elem($2, MSGLEN_O, 0, NUMBER_ST, (void *) $3 ); }
1416         | MSGLEN intop attr_id_val      { $$=mk_elem($2, MSGLEN_O, 0, AVP_ST, (void *) $3 ); }
1417         | MSGLEN intop MAX_LEN          { $$=mk_elem($2, MSGLEN_O, 0, NUMBER_ST, (void *) BUF_SIZE); }
1418         | MSGLEN intop error { $$=0; yyerror("number expected"); }
1419         | MSGLEN error { $$=0; yyerror("equal/!= operator expected"); }
1420
1421         | RETCODE intop NUMBER  { $$=mk_elem($2, RETCODE_O, 0, NUMBER_ST, (void *) $3 ); }
1422         | RETCODE intop attr_id_val     { $$=mk_elem($2, RETCODE_O, 0, AVP_ST, (void *) $3 ); }
1423         | RETCODE intop error { $$=0; yyerror("number expected"); }
1424         | RETCODE error { $$=0; yyerror("equal/!= operator expected"); }
1425
1426         | SRCIP equalop ipnet   { $$=mk_elem($2, SRCIP_O, 0, NET_ST, $3); }
1427         | SRCIP strop STRING {
1428                 s_tmp.s=$3;
1429                 s_tmp.len=strlen($3);
1430                 ip_tmp=str2ip(&s_tmp);
1431                 if (ip_tmp==0)
1432                         ip_tmp=str2ip6(&s_tmp);
1433                 if (ip_tmp) {
1434                         $$=mk_elem($2, SRCIP_O, 0, NET_ST, mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
1435                 } else {
1436                         $$=mk_elem($2, SRCIP_O, 0, STRING_ST, $3);
1437                 }
1438         }
1439         | SRCIP strop host      { $$=mk_elem($2, SRCIP_O, 0, STRING_ST, $3); }
1440         | SRCIP equalop MYSELF  { $$=mk_elem($2, SRCIP_O, 0, MYSELF_ST, 0);
1441                                                         }
1442         | SRCIP strop error { $$=0; yyerror( "ip address or hostname expected" ); }
1443         | SRCIP error  { $$=0; yyerror("invalid operator, ==, != or =~ expected");}
1444         | DSTIP equalop ipnet   { $$=mk_elem(   $2, DSTIP_O, 0, NET_ST, (void*)$3); }
1445         | DSTIP strop STRING    {
1446                 s_tmp.s=$3;
1447                 s_tmp.len=strlen($3);
1448                 ip_tmp=str2ip(&s_tmp);
1449                 if (ip_tmp==0)
1450                         ip_tmp=str2ip6(&s_tmp);
1451                 if (ip_tmp) {
1452                         $$=mk_elem($2, DSTIP_O, 0, NET_ST, mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
1453                 } else {
1454                         $$=mk_elem($2, DSTIP_O, 0, STRING_ST, $3);
1455                 }
1456         }
1457         | DSTIP strop host      { $$=mk_elem(   $2, DSTIP_O, 0, STRING_ST, $3); }
1458         | DSTIP equalop MYSELF  { $$=mk_elem(   $2, DSTIP_O, 0, MYSELF_ST, 0); }
1459         | DSTIP strop error { $$=0; yyerror( "ip address or hostname expected" ); }
1460         | DSTIP error { $$=0; yyerror("invalid operator, ==, != or =~ expected"); }
1461         | SNDIP equalop ipnet {
1462                 onsend_check("snd_ip");
1463                 $$=mk_elem($2, SNDIP_O, 0, NET_ST, $3);
1464         }
1465         | SNDIP strop STRING    {
1466                 onsend_check("snd_ip");
1467                 s_tmp.s=$3;
1468                 s_tmp.len=strlen($3);
1469                 ip_tmp=str2ip(&s_tmp);
1470                 if (ip_tmp==0)
1471                         ip_tmp=str2ip6(&s_tmp);
1472                 if (ip_tmp) {
1473                         $$=mk_elem($2, SNDIP_O, 0, NET_ST, mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
1474                 } else {
1475                         $$=mk_elem($2, SNDIP_O, 0, STRING_ST, $3);
1476                 }
1477         }
1478         | SNDIP strop host      {
1479                 onsend_check("snd_ip");
1480                 $$=mk_elem($2, SNDIP_O, 0, STRING_ST, $3);
1481         }
1482         | SNDIP equalop attr_id_val     {
1483                 onsend_check("snd_ip");
1484             $$=mk_elem($2, SNDIP_O, 0, AVP_ST, (void*)$3 ); 
1485         }
1486         | SNDIP equalop MYSELF  {
1487                 onsend_check("snd_ip");
1488                 $$=mk_elem($2, SNDIP_O, 0, MYSELF_ST, 0);
1489         }
1490         | SNDIP strop error { $$=0; yyerror( "ip address or hostname expected" ); }
1491         | SNDIP error  { $$=0; yyerror("invalid operator, ==, != or =~ expected"); }
1492         | TOIP equalop ipnet    {
1493                 onsend_check("to_ip");
1494                 $$=mk_elem($2, TOIP_O, 0, NET_ST, $3);
1495         }
1496         | TOIP strop STRING     {
1497                 onsend_check("to_ip");
1498                 s_tmp.s=$3;
1499                 s_tmp.len=strlen($3);
1500                 ip_tmp=str2ip(&s_tmp);
1501                 if (ip_tmp==0)
1502                         ip_tmp=str2ip6(&s_tmp);
1503                 if (ip_tmp) {
1504                         $$=mk_elem($2, TOIP_O, 0, NET_ST, mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
1505                 } else {
1506                         $$=mk_elem($2, TOIP_O, 0, STRING_ST, $3);
1507                 }
1508         }
1509         | TOIP strop host       {
1510                 onsend_check("to_ip");
1511                 $$=mk_elem($2, TOIP_O, 0, STRING_ST, $3);
1512         }
1513         | TOIP equalop attr_id_val      {
1514                 onsend_check("to_ip");
1515             $$=mk_elem($2, TOIP_O, 0, AVP_ST, (void*)$3 ); 
1516         }
1517         | TOIP equalop MYSELF  {
1518                 onsend_check("to_ip");
1519                 $$=mk_elem($2, TOIP_O, 0, MYSELF_ST, 0);
1520         }
1521         | TOIP strop error { $$=0; yyerror( "ip address or hostname expected" ); }
1522         | TOIP error  { $$=0; yyerror("invalid operator, ==, != or =~ expected"); }
1523
1524         | MYSELF equalop uri_type       { $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
1525         | MYSELF equalop SRCIP  { $$=mk_elem($2, SRCIP_O, 0, MYSELF_ST, 0); }
1526         | MYSELF equalop DSTIP  { $$=mk_elem($2, DSTIP_O, 0, MYSELF_ST, 0); }
1527         | MYSELF equalop SNDIP  {
1528                 onsend_check("snd_ip");
1529                 $$=mk_elem($2, SNDIP_O, 0, MYSELF_ST, 0);
1530         }
1531         | MYSELF equalop TOIP  {
1532                 onsend_check("to_ip");
1533                 $$=mk_elem($2, TOIP_O, 0, MYSELF_ST, 0);
1534         }
1535         | MYSELF equalop error { $$=0; yyerror(" URI, SRCIP or DSTIP expected"); }
1536         | MYSELF error  { $$=0; yyerror ("invalid operator, == or != expected"); }
1537         | exp_stm       { $$=mk_elem( NO_OP, ACTION_O, 0, ACTIONS_ST, $1);  }
1538         | NUMBER        { $$=mk_elem( NO_OP, NUMBER_O, 0, NUMBER_ST, (void*)$1 ); }
1539
1540         | attr_id_any                           {$$=mk_elem( NO_OP, AVP_O, (void*)$1, 0, 0); }
1541         | attr_id_val strop STRING      {$$=mk_elem( $2, AVP_O, (void*)$1, STRING_ST, $3); }
1542         | attr_id_val strop select_id   {$$=mk_elem( $2, AVP_O, (void*)$1, SELECT_ST, $3); }
1543         | attr_id_val intop NUMBER      {$$=mk_elem( $2, AVP_O, (void*)$1, NUMBER_ST, (void*)$3); }
1544         | attr_id_val binop NUMBER      {$$=mk_elem( $2, AVP_O, (void*)$1, NUMBER_ST, (void*)$3); }
1545         | attr_id_val strop attr_id_val {$$=mk_elem( $2, AVP_O, (void*)$1, AVP_ST, (void*)$3); }
1546
1547         | select_id                 { $$=mk_elem( NO_OP, SELECT_O, $1, 0, 0); }
1548         | select_id strop STRING    { $$=mk_elem( $2, SELECT_O, $1, STRING_ST, $3); }
1549         | select_id strop attr_id_val   { $$=mk_elem( $2, SELECT_O, $1, AVP_ST, (void*)$3); }
1550         | select_id strop select_id { $$=mk_elem( $2, SELECT_O, $1, SELECT_ST, $3); }
1551 ;
1552 ipnet:
1553         ip SLASH ip     { $$=mk_net($1, $3); }
1554         | ip SLASH NUMBER {
1555                 if (($3<0) || ($3>$1->len*8)) {
1556                         yyerror("invalid bit number in netmask");
1557                         $$=0;
1558                 } else {
1559                         $$=mk_net_bitlen($1, $3);
1560                 /*
1561                         $$=mk_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
1562                 */
1563                 }
1564         }
1565         | ip    { $$=mk_net_bitlen($1, $1->len*8); }
1566         | ip SLASH error { $$=0; yyerror("netmask (eg:255.0.0.0 or 8) expected"); }
1567         ;
1568 host_sep:
1569         DOT {$$=".";}
1570         | MINUS {$$="-"; }
1571         ;
1572
1573 host:
1574         ID { $$=$1; }
1575         | host host_sep ID {
1576                 $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1577                 if ($$==0) {
1578                         LOG(L_CRIT, "ERROR: cfg. parser: memory allocation failure while parsing host\n");
1579                 } else {
1580                         memcpy($$, $1, strlen($1));
1581                         $$[strlen($1)]=*$2;
1582                         memcpy($$+strlen($1)+1, $3, strlen($3));
1583                         $$[strlen($1)+1+strlen($3)]=0;
1584                 }
1585                 pkg_free($1);
1586                 pkg_free($3);
1587         }
1588         | host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
1589         ;
1590 /* filtered cmd */
1591 fcmd:
1592         cmd {
1593                 /* check if allowed */
1594                 if ($1 && rt==ONSEND_ROUTE) {
1595                         switch($1->type) {
1596                                 case DROP_T:
1597                                 case SEND_T:
1598                                 case SEND_TCP_T:
1599                                 case LOG_T:
1600                                 case SETFLAG_T:
1601                                 case RESETFLAG_T:
1602                                 case ISFLAGSET_T:
1603                                 case IF_T:
1604                                 case MODULE_T:
1605                                         $$=$1;
1606                                         break;
1607                                 default:
1608                                         $$=0;
1609                                         yyerror("command not allowed in onsend_route\n");
1610                         }
1611                 } else {
1612                         $$=$1;
1613                 }
1614         }
1615         ;
1616 exp_stm:
1617         fcmd    { $$=$1; }
1618         | if_cmd        { $$=$1; }
1619         | assign_action { $$ = $1; }
1620         | LBRACE actions RBRACE { $$=$2; }
1621         ;
1622 stm:
1623         action  { $$=$1; }
1624         | LBRACE actions RBRACE { $$=$2; }
1625         ;
1626 actions:
1627         actions action  {$$=append_action($1, $2); }
1628         | action        {$$=$1;}
1629         | actions error { $$=0; yyerror("bad command"); }
1630         ;
1631 action:
1632         fcmd SEMICOLON {$$=$1;}
1633         | if_cmd {$$=$1;}
1634         | assign_action SEMICOLON {$$=$1;}
1635         | SEMICOLON /* null action */ {$$=0;}
1636         | fcmd error { $$=0; yyerror("bad command: missing ';'?"); }
1637         ;
1638 if_cmd:
1639         IF exp stm              { $$=mk_action( IF_T, 3, EXPR_ST, $2, ACTIONS_ST, $3, NOSUBTYPE, 0); }
1640         | IF exp stm ELSE stm   { $$=mk_action( IF_T, 3, EXPR_ST, $2, ACTIONS_ST, $3, ACTIONS_ST, $5); }
1641         ;
1642 /* class_id:
1643         LBRACK ATTR_USER RBRACK { $$ = AVP_CLASS_USER; }
1644         | LBRACK ATTR_DOMAIN RBRACK { $$ = AVP_CLASS_DOMAIN; }
1645         | LBRACK ATTR_GLOBAL RBRACK { $$ = AVP_CLASS_GLOBAL; }
1646         ;
1647 */
1648 select_param:
1649         ID {
1650                 if (sel.n >= MAX_SELECT_PARAMS-1) {
1651                         yyerror("Select identifier too long\n");
1652                 }
1653                 sel.params[sel.n].type = SEL_PARAM_STR;
1654                 sel.params[sel.n].v.s.s = $1;
1655                 sel.params[sel.n].v.s.len = strlen($1);
1656                 sel.n++;
1657         }
1658         | ID LBRACK NUMBER RBRACK {
1659                 if (sel.n >= MAX_SELECT_PARAMS-2) {
1660                         yyerror("Select identifier too long\n");
1661                 }
1662                 sel.params[sel.n].type = SEL_PARAM_STR;
1663                 sel.params[sel.n].v.s.s = $1;
1664                 sel.params[sel.n].v.s.len = strlen($1);
1665                 sel.n++;
1666                 sel.params[sel.n].type = SEL_PARAM_INT;
1667                 sel.params[sel.n].v.i = $3;
1668                 sel.n++;
1669         }
1670         | ID LBRACK STRING RBRACK {
1671                 if (sel.n >= MAX_SELECT_PARAMS-2) {
1672                         yyerror("Select identifier too long\n");
1673                 }
1674                 sel.params[sel.n].type = SEL_PARAM_STR;
1675                 sel.params[sel.n].v.s.s = $1;
1676                 sel.params[sel.n].v.s.len = strlen($1);
1677                 sel.n++;
1678                 sel.params[sel.n].type = SEL_PARAM_STR;
1679                 sel.params[sel.n].v.s.s = $3;
1680                 sel.params[sel.n].v.s.len = strlen($3);
1681                 sel.n++;
1682         }
1683         ;
1684 select_params:
1685         select_params DOT select_param
1686         | select_param
1687         ;
1688 select_id:
1689         SELECT_MARK { sel.n = 0; sel.f[0] = 0; } select_params {
1690                 sel_ptr = (select_t*)pkg_malloc(sizeof(select_t));
1691                 if (!sel_ptr) {
1692                         yyerror("No memory left to allocate select structure\n");
1693                 }
1694                 memcpy(sel_ptr, &sel, sizeof(select_t));
1695                 $$ = sel_ptr;
1696         }
1697         ;
1698 attr_class_spec:
1699         ATTR_FROM { s_attr->type |= AVP_TRACK_FROM; }
1700         | ATTR_TO { s_attr->type |= AVP_TRACK_TO; }
1701         | ATTR_FROMURI { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_URI; }
1702         | ATTR_TOURI { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_URI; }
1703         | ATTR_FROMUSER { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_USER; }
1704         | ATTR_TOUSER { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_USER; }
1705         | ATTR_FROMDOMAIN { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_DOMAIN; }
1706         | ATTR_TODOMAIN { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_DOMAIN; }
1707         | ATTR_GLOBAL { s_attr->type |= AVP_TRACK_ALL | AVP_CLASS_GLOBAL; }
1708         ;
1709 attr_name_spec:
1710         ID { s_attr->type |= AVP_NAME_STR; s_attr->name.s.s = $1; s_attr->name.s.len = strlen ($1); }
1711         ;
1712 attr_spec:
1713         attr_name_spec
1714         | attr_class_spec DOT attr_name_spec
1715         ;
1716 attr_mark:
1717         ATTR_MARK {
1718                 s_attr = (struct avp_spec*)pkg_malloc(sizeof(struct avp_spec));
1719                 if (!s_attr) { yyerror("No memory left"); }
1720                 s_attr->type = 0;
1721         }
1722         ;
1723 attr_id:
1724         attr_mark attr_spec { $$ = s_attr; }
1725         ;
1726 attr_id_num_idx:
1727         attr_mark attr_spec LBRACK NUMBER RBRACK {
1728                 s_attr->type|= (AVP_NAME_STR | ($4<0?AVP_INDEX_BACKWARD:AVP_INDEX_FORWARD));
1729                 s_attr->index = ($4<0?-$4:$4);
1730                 $$ = s_attr;
1731         }
1732         ;
1733 attr_id_no_idx:
1734         attr_mark attr_spec LBRACK RBRACK {
1735                 s_attr->type|= AVP_INDEX_ALL;
1736                 $$ = s_attr;
1737         }
1738         ;
1739 attr_id_ass:
1740         attr_id
1741         | attr_id_no_idx
1742         ;
1743 attr_id_val:
1744         attr_id
1745         | attr_id_num_idx
1746         ;
1747 attr_id_any:
1748         attr_id
1749         | attr_id_no_idx
1750         | attr_id_num_idx
1751 ;
1752 attr_id_any_str:
1753         attr_id
1754         | STRING {
1755                 avp_spec_t *avp_spec;
1756                 str s;
1757                 int type, idx;
1758                 avp_spec = pkg_malloc(sizeof(*avp_spec));
1759                 if (!avp_spec) {
1760                         yyerror("Not enough memory");
1761                         YYABORT;
1762                 }
1763                 s.s = $1;
1764                 if (s.s[0] == '$')
1765                         s.s++;
1766                 s.len = strlen(s.s);
1767                 if (parse_avp_name(&s, &type, &avp_spec->name, &idx)) {
1768                         yyerror("error when parsing AVP");
1769                         pkg_free(avp_spec);
1770                         YYABORT;
1771                 }
1772                 avp_spec->type = type;
1773                 avp_spec->index = idx;
1774                 $$ = avp_spec;
1775         }
1776         ;
1777 /*
1778 assign_op:
1779         ADDEQ { $$ = ADD_T; }
1780         | EQUAL { $$ = ASSIGN_T; }
1781         ;
1782 */
1783 assign_op:
1784         EQUAL { $$ = ASSIGN_T; }
1785         ;
1786 assign_action:
1787         attr_id_ass assign_op STRING  { $$=mk_action($2, 2, AVP_ST, $1, STRING_ST, $3); }
1788         | attr_id_ass assign_op NUMBER  { $$=mk_action($2, 2, AVP_ST, $1, NUMBER_ST, (void*)$3); }
1789         | attr_id_ass assign_op fcmd    { $$=mk_action($2, 2, AVP_ST, $1, ACTION_ST, $3); }
1790         | attr_id_ass assign_op attr_id_any { $$=mk_action($2, 2, AVP_ST, $1, AVP_ST, $3); }
1791         | attr_id_ass assign_op select_id { $$=mk_action($2, 2, AVP_ST, (void*)$1, SELECT_ST, (void*)$3); }
1792         | attr_id_ass assign_op LPAREN exp RPAREN { $$ = mk_action($2, 2, AVP_ST, $1, EXPR_ST, $4); }
1793         ;
1794 avpflag_oper:
1795         SETAVPFLAG { $$ = 1; }
1796         | RESETAVPFLAG { $$ = 0; }
1797         | ISAVPFLAGSET { $$ = -1; }
1798         ;
1799 cmd:
1800         FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1801         | FORWARD LPAREN STRING RPAREN  { $$=mk_action( FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1802         | FORWARD LPAREN ip RPAREN      { $$=mk_action( FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
1803         | FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1804         | FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1805         | FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
1806         | FORWARD LPAREN URIHOST COMMA URIPORT RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); }
1807         | FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); }
1808         | FORWARD LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); }
1809         | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
1810         | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward argument"); }
1811         | FORWARD_UDP LPAREN host RPAREN        { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1812         | FORWARD_UDP LPAREN STRING RPAREN      { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1813         | FORWARD_UDP LPAREN ip RPAREN  { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
1814         | FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1815         | FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1816         | FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
1817         | FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); }
1818         | FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); }
1819         | FORWARD_UDP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); }
1820         | FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
1821         | FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp argument"); }
1822         | FORWARD_TCP LPAREN host RPAREN        { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1823         | FORWARD_TCP LPAREN STRING RPAREN      { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1824         | FORWARD_TCP LPAREN ip RPAREN  { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
1825         | FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1826         | FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1827         | FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
1828         | FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); }
1829         | FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); }
1830         | FORWARD_TCP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); }
1831         | FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
1832         | FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp argument"); }
1833         | FORWARD_TLS LPAREN host RPAREN {
1834                 #ifdef USE_TLS
1835                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0);
1836                 #else
1837                         $$=0;
1838                         yyerror("tls support not compiled in");
1839                 #endif
1840         }
1841         | FORWARD_TLS LPAREN STRING RPAREN {
1842                 #ifdef USE_TLS
1843                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0);
1844                 #else
1845                         $$=0;
1846                         yyerror("tls support not compiled in");
1847                 #endif
1848         }
1849         | FORWARD_TLS LPAREN ip RPAREN  {
1850                 #ifdef USE_TLS
1851                         $$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0);
1852                 #else
1853                         $$=0;
1854                         yyerror("tls support not compiled in");
1855                 #endif
1856         }
1857         | FORWARD_TLS LPAREN host COMMA NUMBER RPAREN {
1858                 #ifdef USE_TLS
1859                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5);
1860                 #else
1861                         $$=0;
1862                         yyerror("tls support not compiled in");
1863                 #endif
1864         }
1865         | FORWARD_TLS LPAREN STRING COMMA NUMBER RPAREN {
1866                 #ifdef USE_TLS
1867                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5);
1868                 #else
1869                         $$=0;
1870                         yyerror("tls support not compiled in");
1871                 #endif
1872         }
1873         | FORWARD_TLS LPAREN ip COMMA NUMBER RPAREN {
1874                 #ifdef USE_TLS
1875                         $$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5);
1876                 #else
1877                         $$=0;
1878                         yyerror("tls support not compiled in");
1879                 #endif
1880                                         }
1881         | FORWARD_TLS LPAREN URIHOST COMMA URIPORT RPAREN {
1882                 #ifdef USE_TLS
1883                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, URIPORT_ST, 0);
1884                 #else
1885                         $$=0;
1886                         yyerror("tls support not compiled in");
1887                 #endif
1888         }
1889         | FORWARD_TLS LPAREN URIHOST COMMA NUMBER RPAREN {
1890                 #ifdef USE_TLS
1891                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5);
1892                 #else
1893                         $$=0;
1894                         yyerror("tls support not compiled in");
1895                 #endif
1896         }
1897         | FORWARD_TLS LPAREN URIHOST RPAREN {
1898                 #ifdef USE_TLS
1899                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, 0);
1900                 #else
1901                         $$=0;
1902                         yyerror("tls support not compiled in");
1903                 #endif
1904         }
1905         | FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
1906         | FORWARD_TLS LPAREN error RPAREN { $$=0; yyerror("bad forward_tls argument"); }
1907         | SEND LPAREN host RPAREN       { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1908         | SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1909         | SEND LPAREN ip RPAREN         { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
1910         | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1911         | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1912         | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
1913         | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
1914         | SEND LPAREN error RPAREN { $$=0; yyerror("bad send argument"); }
1915         | SEND_TCP LPAREN host RPAREN   { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1916         | SEND_TCP LPAREN STRING RPAREN { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1917         | SEND_TCP LPAREN ip RPAREN     { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
1918         | SEND_TCP LPAREN host COMMA NUMBER RPAREN      { $$=mk_action( SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5);}
1919         | SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
1920         | SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
1921         | SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
1922         | SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp argument"); }
1923         | DROP LPAREN RPAREN            {$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F); }
1924         | DROP LPAREN NUMBER RPAREN     {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)$3, NUMBER_ST, (void*)EXIT_R_F); }
1925         | DROP NUMBER                   {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)$2, NUMBER_ST, (void*)EXIT_R_F); }
1926         | DROP RETCODE                  {$$=mk_action(DROP_T, 2, RETCODE_ST, 0, NUMBER_ST, (void*)EXIT_R_F); }
1927         | DROP                          {$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F); }
1928         | RETURN                        {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST, (void*)RETURN_R_F); }
1929         | RETURN NUMBER                 {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)$2, NUMBER_ST, (void*)RETURN_R_F);}
1930         | RETURN RETCODE                {$$=mk_action(DROP_T, 2, RETCODE_ST, 0, NUMBER_ST, (void*)RETURN_R_F);}
1931         | BREAK                         {$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)RETURN_R_F); }
1932         | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(LOG_T, 2, NUMBER_ST, (void*)4, STRING_ST, $3); }
1933         | LOG_TOK LPAREN NUMBER COMMA STRING RPAREN     {$$=mk_action(LOG_T, 2, NUMBER_ST, (void*)$3, STRING_ST, $5); }
1934         | LOG_TOK error                 { $$=0; yyerror("missing '(' or ')' ?"); }
1935         | LOG_TOK LPAREN error RPAREN   { $$=0; yyerror("bad log argument"); }
1936         | SETFLAG LPAREN NUMBER RPAREN  {
1937                                                         if (check_flag($3)==-1)
1938                                                                 yyerror("bad flag value");
1939                                                         $$=mk_action(SETFLAG_T, 1, NUMBER_ST,
1940                                                                                                         (void*)$3);
1941                                                                         }
1942         | SETFLAG LPAREN flag_name RPAREN       {
1943                                                         i_tmp=get_flag_no($3, strlen($3));
1944                                                         if (i_tmp<0) yyerror("flag not declared");
1945                                                         $$=mk_action(SETFLAG_T, 1, NUMBER_ST,
1946                                                                                 (void*)(long)i_tmp);
1947                                                                         }
1948         | SETFLAG error                 { $$=0; yyerror("missing '(' or ')'?"); }
1949         | RESETFLAG LPAREN NUMBER RPAREN {
1950                                                         if (check_flag($3)==-1)
1951                                                                 yyerror("bad flag value");
1952                                                         $$=mk_action(RESETFLAG_T, 1, NUMBER_ST, (void*)$3);
1953                                                                         }
1954         | RESETFLAG LPAREN flag_name RPAREN     {
1955                                                         i_tmp=get_flag_no($3, strlen($3));
1956                                                         if (i_tmp<0) yyerror("flag not declared");
1957                                                         $$=mk_action(RESETFLAG_T, 1, NUMBER_ST,
1958                                                                                 (void*)(long)i_tmp);
1959                                                                         }
1960         | RESETFLAG error               { $$=0; yyerror("missing '(' or ')'?"); }
1961         | ISFLAGSET LPAREN NUMBER RPAREN {
1962                                                         if (check_flag($3)==-1)
1963                                                                 yyerror("bad flag value");
1964                                                         $$=mk_action(ISFLAGSET_T, 1, NUMBER_ST, (void*)$3);
1965                                                                         }
1966         | ISFLAGSET LPAREN flag_name RPAREN     {
1967                                                         i_tmp=get_flag_no($3, strlen($3));
1968                                                         if (i_tmp<0) yyerror("flag not declared");
1969                                                         $$=mk_action(ISFLAGSET_T, 1, NUMBER_ST,
1970                                                                                 (void*)(long)i_tmp);
1971                                                                         }
1972         | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
1973         | avpflag_oper LPAREN attr_id_any_str COMMA flag_name RPAREN {
1974                 i_tmp=get_avpflag_no($5);
1975                 if (i_tmp==0) yyerror("avpflag not declared");
1976                 $$=mk_action(AVPFLAG_OPER_T, 3, AVP_ST, $3, NUMBER_ST, (void*)(long)i_tmp, NUMBER_ST, (void*)$1);
1977         }
1978         | avpflag_oper error { $$=0; yyerror("missing '(' or ')'?"); }
1979         | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T, 2, STRING_ST, $3, STRING_ST, $5); }
1980         | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
1981         | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error argument"); }
1982         | ROUTE LPAREN route_name RPAREN        {
1983                                                 i_tmp=route_get(&main_rt, $3);
1984                                                 if (i_tmp==-1){
1985                                                         yyerror("internal error");
1986                                                         YYABORT;
1987                                                 }
1988                                                 $$=mk_action(ROUTE_T, 1, NUMBER_ST,(void*)(long)i_tmp);
1989                                                                                 }
1990         | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
1991         | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route argument"); }
1992         | EXEC LPAREN STRING RPAREN     { $$=mk_action(EXEC_T, 1, STRING_ST, $3); }
1993         | SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, 1, STRING_ST, $3); }
1994         | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
1995         | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
1996         | PREFIX LPAREN STRING RPAREN { $$=mk_action(PREFIX_T, 1, STRING_ST,  $3); }
1997         | PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); }
1998         | PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
1999         | STRIP_TAIL LPAREN NUMBER RPAREN { $$=mk_action(STRIP_TAIL_T, 1, NUMBER_ST, (void*)$3); }
2000         | STRIP_TAIL error { $$=0; yyerror("missing '(' or ')' ?"); }
2001         | STRIP_TAIL LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
2002         | STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, 1, NUMBER_ST, (void*) $3); }
2003         | STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
2004         | STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
2005         | APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN {
2006                 qvalue_t q;
2007                 if (str2q(&q, $5, strlen($5)) < 0) {
2008                         yyerror("bad argument, q value expected");
2009                 }
2010                 $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, $3, NUMBER_ST, (void *)(long)q);
2011         }
2012         | APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, $3, NUMBER_ST, (void *)Q_UNSPECIFIED); }
2013         | APPEND_BRANCH LPAREN RPAREN { $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, 0, NUMBER_ST, (void *)Q_UNSPECIFIED); }
2014         | APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, 1, STRING_ST, 0); }
2015         | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORT_T, 1, STRING_ST, $3); }
2016         | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2017         | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2018         | SET_PORT LPAREN STRING RPAREN { $$=mk_action(SET_PORT_T, 1, STRING_ST, $3); }
2019         | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2020         | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2021         | SET_USER LPAREN STRING RPAREN { $$=mk_action(SET_USER_T, 1, STRING_ST, $3); }
2022         | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
2023         | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2024         | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action(SET_USERPASS_T, 1, STRING_ST, $3); }
2025         | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
2026         | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2027         | SET_URI LPAREN STRING RPAREN { $$=mk_action(SET_URI_T, 1, STRING_ST,$3); }
2028         | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
2029         | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2030         | REVERT_URI LPAREN RPAREN { $$=mk_action(REVERT_URI_T, 0); }
2031         | REVERT_URI { $$=mk_action(REVERT_URI_T, 0); }
2032         | FORCE_RPORT LPAREN RPAREN     { $$=mk_action(FORCE_RPORT_T, 0); }
2033         | FORCE_RPORT   {$$=mk_action(FORCE_RPORT_T, 0); }
2034         | FORCE_TCP_ALIAS LPAREN NUMBER RPAREN  {
2035                 #ifdef USE_TCP
2036                         $$=mk_action(FORCE_TCP_ALIAS_T, 1, NUMBER_ST, (void*)$3);
2037                 #else
2038                         yyerror("tcp support not compiled in");
2039                 #endif
2040         }
2041         | FORCE_TCP_ALIAS LPAREN RPAREN {
2042                 #ifdef USE_TCP
2043                         $$=mk_action(FORCE_TCP_ALIAS_T, 0);
2044                 #else
2045                         yyerror("tcp support not compiled in");
2046                 #endif
2047         }
2048         | FORCE_TCP_ALIAS                               {
2049                 #ifdef USE_TCP
2050                         $$=mk_action(FORCE_TCP_ALIAS_T, 0);
2051                 #else
2052                         yyerror("tcp support not compiled in");
2053                 #endif
2054         }
2055         | FORCE_TCP_ALIAS LPAREN error RPAREN   {$$=0; yyerror("bad argument, number expected"); }
2056         | SET_ADV_ADDRESS LPAREN listen_id RPAREN {
2057                 $$=0;
2058                 if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
2059                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2060                 } else {
2061                         str_tmp->s=$3;
2062                         str_tmp->len=strlen($3);
2063                         $$=mk_action(SET_ADV_ADDR_T, 1, STR_ST, str_tmp);
2064                 }
2065         }
2066         | SET_ADV_ADDRESS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2067         | SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); }
2068         | SET_ADV_PORT LPAREN NUMBER RPAREN {
2069                 $$=0;
2070                 tmp=int2str($3, &i_tmp);
2071                 if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
2072                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2073                 } else {
2074                         if ((str_tmp->s=pkg_malloc(i_tmp))==0) {
2075                                 LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2076                         } else {
2077                                 memcpy(str_tmp->s, tmp, i_tmp);
2078                                 str_tmp->len=i_tmp;
2079                                 $$=mk_action(SET_ADV_PORT_T, 1, STR_ST, str_tmp);
2080                         }
2081                 }
2082         }
2083         | SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2084         | SET_ADV_PORT  error {$$=0; yyerror("missing '(' or ')' ?"); }
2085         | FORCE_SEND_SOCKET LPAREN phostport RPAREN { $$=mk_action(FORCE_SEND_SOCKET_T, 1, SOCKID_ST, $3); }
2086         | FORCE_SEND_SOCKET LPAREN error RPAREN { $$=0; yyerror("bad argument, [proto:]host[:port] expected"); }
2087         | FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
2088         | ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST, 0); } LPAREN func_params RPAREN      {
2089                 mod_func_action->val[0].u.data = find_export_record($1, mod_func_action->val[1].u.number, rt);
2090                 if (mod_func_action->val[0].u.data == 0) {
2091                         if (find_export_record($1, mod_func_action->val[1].u.number, 0) ) {
2092                                         yyerror("Command cannot be used in the block\n");
2093                         } else {
2094                                 yyerror("unknown command, missing loadmodule?\n");
2095                         }
2096                         pkg_free(mod_func_action);
2097                         mod_func_action=0;
2098                 }
2099                 $$ = mod_func_action;
2100         }
2101         ;
2102 func_params:
2103         /* empty */
2104         | func_params COMMA func_param { }
2105         | func_param {}
2106         | func_params error { yyerror("call params error\n"); YYABORT; }
2107         ;
2108 func_param:
2109         NUMBER {
2110                 if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
2111                         mod_func_action->val[mod_func_action->val[1].u.number+2].type = NUMBER_ST;
2112                         mod_func_action->val[mod_func_action->val[1].u.number+2].u.number = $1;
2113                         mod_func_action->val[1].u.number++;
2114                 } else {
2115                         yyerror("Too many arguments\n");
2116                 }
2117         }
2118         | STRING {
2119                 if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
2120                         mod_func_action->val[mod_func_action->val[1].u.number+2].type = STRING_ST;
2121                         mod_func_action->val[mod_func_action->val[1].u.number+2].u.string = $1;
2122                         mod_func_action->val[1].u.number++;
2123                 } else {
2124                         yyerror("Too many arguments\n");
2125                 }
2126         }
2127         ;
2128 %%
2129
2130 extern int line;
2131 extern int column;
2132 extern int startcolumn;
2133 static void warn(char* s)
2134 {
2135         LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n", line, startcolumn,
2136                         column, s);
2137         cfg_warnings++;
2138 }
2139
2140 static void yyerror(char* s)
2141 {
2142         LOG(L_CRIT, "parse error (%d,%d-%d): %s\n", line, startcolumn,
2143                         column, s);
2144         cfg_errors++;
2145 }
2146
2147
2148 static struct socket_id* mk_listen_id(char* host, int proto, int port)
2149 {
2150         struct socket_id* l;
2151         l=pkg_malloc(sizeof(struct socket_id));
2152         if (l==0) {
2153                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
2154         } else {
2155                 l->name=host;
2156                 l->port=port;
2157                 l->proto=proto;
2158                 l->next=0;
2159         }
2160         return l;
2161 }
2162
2163
2164 /*
2165 int main(int argc, char ** argv)
2166 {
2167         if (yyparse()!=0)
2168                 fprintf(stderr, "parsing error\n");
2169 }
2170 */