cfg.y
3c1a8ef8
 /*
  *  cfg grammar
2d4b798e
  *
53c7e0f1
  * Copyright (C) 2001-2003 FhG Fokus
2d4b798e
  *
493ef6c1
  * This file is part of Kamailio, a free SIP server.
2d4b798e
  *
493ef6c1
  * Kamailio is free software; you can redistribute it and/or modify
2d4b798e
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
  * For a license to use the ser software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    info@iptel.org
  *
493ef6c1
  * Kamailio is distributed in the hope that it will be useful,
2d4b798e
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
fb851d7e
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
aeb805d5
  */
2d4b798e
 
415f24a4
 %expect 6
0dabc34a
 
3c1a8ef8
 %{
 
3e429f5c
 #include <stdlib.h>
63fa628f
 #include <stdio.h>
8a0c71c9
 #include <stdarg.h>
c75aa645
 #include <sys/types.h>
7268726e
 #include <sys/socket.h>
 #include <netinet/in.h>
d3eb5d4f
 #include <netinet/ip.h>
7268726e
 #include <arpa/inet.h>
f20a56a2
 #include <string.h>
4e2fdd79
 #include <errno.h>
c07508e2
 #include "route_struct.h"
3e429f5c
 #include "globals.h"
6f722344
 #ifdef SHM_MEM
 #include "shm_init.h"
 #endif /* SHM_MEM */
3e429f5c
 #include "route.h"
a29a8b6d
 #include "switch.h"
7268726e
 #include "dprint.h"
3bf76e49
 #include "sr_module.h"
31309a3a
 #include "modparam.h"
4e2fdd79
 #include "ip_addr.h"
5260ef32
 #include "resolve.h"
9f4c52ce
 #include "socket_info.h"
e278821b
 #include "name_alias.h"
6bfaa042
 #include "ut.h"
035f593c
 #include "dset.h"
3fb428ed
 #include "select.h"
65938e0e
 #include "flags.h"
205fcb02
 #include "tcp_init.h"
20c64cc6
 #include "tcp_options.h"
7f8e7a85
 #include "sctp_core.h"
cddb9399
 #include "pvar.h"
 #include "lvalue.h"
 #include "rvalue.h"
 #include "sr_compat.h"
f62c96d8
 #include "msg_translator.h"
d5a22ca8
 #include "async_task.h"
3e429f5c
 
98fa9495
 #include "kemi.h"
20cddb28
 #include "ppcfg.h"
7614a1d0
 #include "pvapi.h"
1f377e97
 #include "config.h"
7ac069af
 #include "cfg_core.h"
140137c9
 #include "cfg/cfg.h"
6c53d41a
 #ifdef CORE_TLS
8737eaf4
 #include "tls/tls_config.h"
 #endif
9a74e06a
 #include "timer_ticks.h"
f571aa35
 
03150098
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
 #endif
 
f3f0a4de
 /* hack to avoid alloca usage in the generated C file (needed for compiler
  with no built in alloca, like icc*/
 #undef _ALLOCA_H
1f377e97
 
0d88ce78
 #define onsend_check(s) \
 	do{\
 		if (rt!=ONSEND_ROUTE) yyerror( s " allowed only in onsend_routes");\
 	}while(0)
57e2cd15
 
bd3d3546
 	#define IF_AUTO_BIND_IPV6(x) x
dcb59e67
 
 #ifdef USE_DNS_CACHE
 	#define IF_DNS_CACHE(x) x
 #else
 	#define IF_DNS_CACHE(x) warn("dns cache support not compiled in")
 #endif
 
 #ifdef USE_DNS_FAILOVER
 	#define IF_DNS_FAILOVER(x) x
 #else
 	#define IF_DNS_FAILOVER(x) warn("dns failover support not compiled in")
 #endif
 
dd4ffbb7
 #ifdef USE_NAPTR
 	#define IF_NAPTR(x) x
 #else
 	#define IF_NAPTR(x) warn("dns naptr support not compiled in")
 #endif
 
dcb59e67
 #ifdef USE_DST_BLACKLIST
 	#define IF_DST_BLACKLIST(x) x
 #else
 	#define IF_DST_BLACKLIST(x) warn("dst blacklist support not compiled in")
 #endif
 
b73d58cf
 #ifdef USE_SCTP
 	#define IF_SCTP(x) x
 #else
 	#define IF_SCTP(x) warn("sctp support not compiled in")
 #endif
 
e92fe8b4
 #ifdef USE_RAW_SOCKS
 	#define IF_RAW_SOCKS(x) x
 #else
 	#define IF_RAW_SOCKS(x) warn("raw socket support not compiled in")
 #endif
 
dcb59e67
 
e22bbdb8
 extern int yylex();
f9276a5b
 /* safer then using yytext which can be array or pointer */
 extern char* yy_number_str;
 
8a0c71c9
 static void yyerror(char* s, ...);
d14a718f
 static void yyerror_at(struct cfg_pos* pos, char* s, ...);
6bfaa042
 static char* tmp;
 static int i_tmp;
2873d384
 static unsigned u_tmp;
6cd48835
 static struct socket_id* lst_tmp;
eb321e3f
 static struct name_lst*  nl_tmp;
6bfaa042
 static int rt;  /* Type of route block for find_export */
 static str* str_tmp;
5260ef32
 static str s_tmp;
 static struct ip_addr* ip_tmp;
74ce7043
 static struct avp_spec* s_attr;
3fb428ed
 static select_t sel;
 static select_t* sel_ptr;
26a886bc
 static pv_spec_t* pv_spec;
f141bc93
 static struct action *mod_func_action;
cddb9399
 static struct lvalue* lval_tmp;
80ae84b9
 static struct rvalue* rval_tmp;
26a886bc
 
d14a718f
 static void warn(char* s, ...);
 static void warn_at(struct cfg_pos* pos, char* s, ...);
9a31872c
 static void get_cpos(struct cfg_pos* pos);
8a0c71c9
 static struct rval_expr* mk_rve_rval(enum rval_type, void* v);
 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1);
 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
 									struct rval_expr* rve2);
8637f340
 static int rval_expr_int_check(struct rval_expr *rve);
 static int warn_ct_rve(struct rval_expr *rve, char* name);
6cd48835
 static struct socket_id* mk_listen_id(char*, int, int);
eb321e3f
 static struct name_lst* mk_name_lst(char* name, int flags);
 static struct socket_id* mk_listen_id2(struct name_lst*, int, int);
 static void free_name_lst(struct name_lst* lst);
 static void free_socket_id_lst(struct socket_id* i);
c07508e2
 
8c09d09b
 static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re, 
 									struct action* a, int* err);
 static int case_check_type(struct case_stms* stms);
 static int case_check_default(struct case_stms* stms);
cad98b04
 static int mod_f_params_pre_fixup(struct action* a);
 static void free_mod_func_action(struct action* a);
8c09d09b
 
a29a8b6d
 
eac773a6
 extern int line;
 extern int column;
 extern int startcolumn;
 extern int startline;
 extern char *finame;
c44685cb
 extern char *routename;
 extern char *default_routename;
eac773a6
 
 #define set_cfg_pos(x) \
 	do{\
 		if(x) {\
 		(x)->cline = line;\
 		(x)->cfile = (finame!=0)?finame:((cfg_file!=0)?cfg_file:"default");\
c44685cb
 		(x)->rname = (routename!=0)?routename:((default_routename!=0)?default_routename:"DEFAULT");\
eac773a6
 		}\
 	}while(0)
 
 
3c1a8ef8
 %}
 
 %union {
9a694681
 	long intval;
 	unsigned long uval;
3c1a8ef8
 	char* strval;
c07508e2
 	struct expr* expr;
 	struct action* action;
a29a8b6d
 	struct case_stms* case_stms;
4e2fdd79
 	struct net* ipnet;
 	struct ip_addr* ipaddr;
6cd48835
 	struct socket_id* sockid;
eb321e3f
 	struct name_lst* name_l;
74ce7043
 	struct avp_spec* attr;
cddb9399
 	struct _pv_spec* pvar;
 	struct lvalue* lval;
 	struct rvalue* rval;
 	struct rval_expr* rv_expr;
3fb428ed
 	select_t* select;
3c1a8ef8
 }
 
 /* terminals */
 
 
3e429f5c
 /* keywords */
3c1a8ef8
 %token FORWARD
0c5da34b
 %token FORWARD_TCP
e9b02e8e
 %token FORWARD_TLS
ed990c31
 %token FORWARD_SCTP
f2f969dd
 %token FORWARD_UDP
8ebb586d
 %token EXIT
3c1a8ef8
 %token DROP
fb851d7e
 %token RETURN
01dea124
 %token BREAK
7268726e
 %token LOG_TOK
3c1a8ef8
 %token ERROR
 %token ROUTE
3bf9b2c6
 %token ROUTE_REQUEST
15dde484
 %token ROUTE_FAILURE
 %token ROUTE_ONREPLY
1d2246f4
 %token ROUTE_REPLY
7662b2e7
 %token ROUTE_BRANCH
0d88ce78
 %token ROUTE_SEND
31b5e3d0
 %token ROUTE_EVENT
09e52ebb
 %token EXEC
7268726e
 %token SET_HOST
 %token SET_HOSTPORT
6973e34c
 %token SET_HOSTPORTTRANS
1f377e97
 %token PREFIX
 %token STRIP
1d9f91d6
 %token STRIP_TAIL
536065b8
 %token SET_USERPHONE
caf80ae6
 %token APPEND_BRANCH
9fa304f1
 %token REMOVE_BRANCH
 %token CLEAR_BRANCHES
7268726e
 %token SET_USER
 %token SET_USERPASS
 %token SET_PORT
 %token SET_URI
caf80ae6
 %token REVERT_URI
3e8c3475
 %token FORCE_RPORT
c37c22b4
 %token ADD_LOCAL_RPORT
59653eb8
 %token FORCE_TCP_ALIAS
f62c96d8
 %token UDP_MTU
 %token UDP_MTU_TRY_PROTO
e92fe8b4
 %token UDP4_RAW
 %token UDP4_RAW_MTU
2556cd84
 %token UDP4_RAW_TTL
f20a56a2
 %token IF
 %token ELSE
6bfaa042
 %token SET_ADV_ADDRESS
 %token SET_ADV_PORT
6cd48835
 %token FORCE_SEND_SOCKET
58cbf7f7
 %token SET_FWD_NO_CONNECT
 %token SET_RPL_NO_CONNECT
 %token SET_FWD_CLOSE
 %token SET_RPL_CLOSE
a29a8b6d
 %token SWITCH
 %token CASE
 %token DEFAULT
d14a718f
 %token WHILE
415f24a4
 %token CFG_SELECT
 %token CFG_RESET
5ada8f8a
 %token URIHOST
 %token URIPORT
1f377e97
 %token MAX_LEN
3881f12c
 %token SETFLAG
 %token RESETFLAG
 %token ISFLAGSET
85d4627f
 %token SETAVPFLAG
 %token RESETAVPFLAG
 %token ISAVPFLAGSET
3c1a8ef8
 %token METHOD
 %token URI
6b7de230
 %token FROM_URI
 %token TO_URI
3c1a8ef8
 %token SRCIP
049f64c2
 %token SRCPORT
3c1a8ef8
 %token DSTIP
aeb805d5
 %token DSTPORT
0d88ce78
 %token TOIP
 %token TOPORT
 %token SNDIP
 %token SNDPORT
 %token SNDPROTO
 %token SNDAF
aeb805d5
 %token PROTO
 %token AF
855c2e68
 %token MYSELF
fb851d7e
 %token MSGLEN
e5f4cdaf
 %token UDP
 %token TCP
 %token TLS
c9831d2a
 %token SCTP
8c6f700b
 %token WS
8393efff
 %token WSS
3c1a8ef8
 
 /* config vars. */
a86d53b0
 %token DEBUG_V
3c1a8ef8
 %token FORK
c2429a58
 %token FORK_DELAY
52d33940
 %token MODINIT_DELAY
3c1a8ef8
 %token LOGSTDERROR
26456ace
 %token LOGFACILITY
95bf8645
 %token LOGNAME
fe00a334
 %token LOGCOLOR
35e94c97
 %token LOGPREFIX
b36f7c9a
 %token LOGPREFIXMODE
88b06d1f
 %token LOGENGINETYPE
 %token LOGENGINEDATA
3c1a8ef8
 %token LISTEN
574daa6d
 %token ADVERTISE
e278821b
 %token ALIAS
bb4cd6b0
 %token SR_AUTO_ALIASES
3c1a8ef8
 %token DNS
 %token REV_DNS
878fc194
 %token DNS_TRY_IPV6
dd4ffbb7
 %token DNS_TRY_NAPTR
 %token DNS_SRV_LB
 %token DNS_UDP_PREF
 %token DNS_TCP_PREF
 %token DNS_TLS_PREF
7d11cc0c
 %token DNS_SCTP_PREF
878fc194
 %token DNS_RETR_TIME
 %token DNS_RETR_NO
 %token DNS_SERVERS_NO
 %token DNS_USE_SEARCH
740a5978
 %token DNS_SEARCH_FMATCH
a9fc979c
 %token DNS_NAPTR_IGNORE_RFC
7905e2d6
 %token DNS_CACHE_INIT
dcb59e67
 %token DNS_USE_CACHE
 %token DNS_USE_FAILOVER
 %token DNS_CACHE_FLAGS
 %token DNS_CACHE_NEG_TTL
 %token DNS_CACHE_MIN_TTL
 %token DNS_CACHE_MAX_TTL
 %token DNS_CACHE_MEM
 %token DNS_CACHE_GC_INT
4136d191
 %token DNS_CACHE_DEL_NONEXP
0d4d530e
 %token DNS_CACHE_REC_PREF
bd3d3546
 
 /* ipv6 auto bind */
 %token AUTO_BIND_IPV6
 
dcb59e67
 /*blacklist*/
7905e2d6
 %token DST_BLST_INIT
dcb59e67
 %token USE_DST_BLST
 %token DST_BLST_MEM
 %token DST_BLST_TTL
 %token DST_BLST_GC_INT
0e055147
 %token DST_BLST_UDP_IMASK
 %token DST_BLST_TCP_IMASK
 %token DST_BLST_TLS_IMASK
 %token DST_BLST_SCTP_IMASK
dcb59e67
 
7268726e
 %token PORT
f571aa35
 %token STAT
7268726e
 %token CHILDREN
edf5e385
 %token SOCKET_WORKERS
d5a22ca8
 %token ASYNC_WORKERS
55be13df
 %token ASYNC_USLEEP
7268726e
 %token CHECK_VIA
face488e
 %token PHONE2TEL
843b2927
 %token MEMLOG
58d0d1b5
 %token MEMDBG
d740c34e
 %token MEMSUM
ffb8754f
 %token MEMSAFETY
d89420df
 %token MEMJOIN
7e2e4ff4
 %token CORELOG
caf80ae6
 %token SIP_WARNING
 %token SERVER_SIGNATURE
c745469f
 %token SERVER_HEADER
 %token USER_AGENT_HEADER
caf80ae6
 %token REPLY_TO_VIA
3bf76e49
 %token LOADMODULE
6c8f8d5b
 %token LOADPATH
31309a3a
 %token MODPARAM
98fa9495
 %token CFGENGINE
c3ce2841
 %token MAXBUFFER
5cd87175
 %token SQL_BUFFER_SIZE
054cb6cf
 %token USER
 %token GROUP
3e8c3475
 %token CHROOT
 %token WDIR
ca1358f2
 %token RUNDIR
2d4b798e
 %token MHOMED
5dcfb23d
 %token DISABLE_TCP
59653eb8
 %token TCP_ACCEPT_ALIASES
5dcfb23d
 %token TCP_CHILDREN
bc977837
 %token TCP_CONNECT_TIMEOUT
 %token TCP_SEND_TIMEOUT
55d8155e
 %token TCP_CON_LIFETIME
 %token TCP_POLL_METHOD
 %token TCP_MAX_CONNECTIONS
61f8b970
 %token TLS_MAX_CONNECTIONS
de223f01
 %token TCP_NO_CONNECT
761bd309
 %token TCP_SOURCE_IPV4
 %token TCP_SOURCE_IPV6
20c64cc6
 %token TCP_OPT_FD_CACHE
885b9f62
 %token TCP_OPT_BUF_WRITE
 %token TCP_OPT_CONN_WQ_MAX
 %token TCP_OPT_WQ_MAX
e655392a
 %token TCP_OPT_RD_BUF
 %token TCP_OPT_WQ_BLK
20c64cc6
 %token TCP_OPT_DEFER_ACCEPT
 %token TCP_OPT_DELAYED_ACK
 %token TCP_OPT_SYNCNT
 %token TCP_OPT_LINGER2
 %token TCP_OPT_KEEPALIVE
 %token TCP_OPT_KEEPIDLE
 %token TCP_OPT_KEEPINTVL
 %token TCP_OPT_KEEPCNT
c7337a27
 %token TCP_OPT_CRLF_PING
d4cc4103
 %token TCP_OPT_ACCEPT_NO_CL
691a3439
 %token TCP_CLONE_RCVBUF
46506980
 %token DISABLE_TLS
6c53d41a
 %token ENABLE_TLS
8737eaf4
 %token TLSLOG
057f0454
 %token TLS_PORT_NO
8737eaf4
 %token TLS_METHOD
 %token TLS_HANDSHAKE_TIMEOUT
 %token TLS_SEND_TIMEOUT
 %token SSLv23
 %token SSLv2
 %token SSLv3
 %token TLSv1
 %token TLS_VERIFY
 %token TLS_REQUIRE_CERTIFICATE
 %token TLS_CERTIFICATE
 %token TLS_PRIVATE_KEY
 %token TLS_CA_LIST
ed990c31
 %token DISABLE_SCTP
c8e95587
 %token ENABLE_SCTP
ed990c31
 %token SCTP_CHILDREN
6bfaa042
 %token ADVERTISED_ADDRESS
 %token ADVERTISED_PORT
385c63eb
 %token DISABLE_CORE
 %token OPEN_FD_LIMIT
647cc983
 %token SHM_MEM_SZ
71a0a583
 %token SHM_FORCE_ALLOC
 %token MLOCK_PAGES
 %token REAL_TIME
 %token RT_PRIO
 %token RT_POLICY
 %token RT_TIMER1_PRIO
 %token RT_TIMER1_POLICY
 %token RT_TIMER2_PRIO
 %token RT_TIMER2_POLICY
2ba73117
 %token MCAST_LOOPBACK
956d111a
 %token MCAST_TTL
fe09f315
 %token TOS
f3a26797
 %token PMTU_DISCOVERY
96d09107
 %token KILL_TIMEOUT
d14a718f
 %token MAX_WLOOPS
7614a1d0
 %token PVBUFSIZE
 %token PVBUFSLOTS
adf32ec8
 %token HTTP_REPLY_PARSE
8fb8b261
 %token VERSION_TABLE_CFG
140137c9
 %token CFG_DESCRIPTION
89fde575
 %token SERVER_ID
d1c60718
 %token MAX_RECURSIVE_LEVEL
e008edb9
 %token MAX_BRANCHES_PARAM
e80c2473
 %token LATENCY_CFG_LOG
930aba29
 %token LATENCY_LOG
 %token LATENCY_LIMIT_DB
 %token LATENCY_LIMIT_ACTION
d4ed4771
 %token MSG_TIME
214b161e
 %token ONSEND_RT_REPLY
5dcfb23d
 
65938e0e
 %token FLAGS_DECL
85d4627f
 %token AVPFLAGS_DECL
65938e0e
 
74ce7043
 %token ATTR_MARK
3fb428ed
 %token SELECT_MARK
fd6d4dc9
 %token ATTR_FROM
 %token ATTR_TO
e61ba5d2
 %token ATTR_FROMURI
 %token ATTR_TOURI
18cf23c0
 %token ATTR_FROMUSER
 %token ATTR_TOUSER
 %token ATTR_FROMDOMAIN
 %token ATTR_TODOMAIN
74ce7043
 %token ATTR_GLOBAL
8126b425
 %token ADDEQ
3c1a8ef8
 
26a886bc
 
20cddb28
 /*pre-processor*/
 %token SUBST
78d26523
 %token SUBSTDEF
8198fd2b
 %token SUBSTDEFS
face488e
 
80ae84b9
 /* operators, C like precedence */
 %right EQUAL
74ce7043
 %left LOG_OR
 %left LOG_AND
 %left BIN_OR
fb851d7e
 %left BIN_AND
508ad1c0
 %left BIN_XOR
 %left BIN_LSHIFT
 %left BIN_RSHIFT
298512a2
 %left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
80ae84b9
 %left GT LT GTE LTE
74ce7043
 %left PLUS MINUS
333a3335
 %left STAR SLASH MODULO
508ad1c0
 %right NOT UNARY BIN_NOT
d4799027
 %right DEFINED
e41bc057
 %right INTCAST STRCAST
80ae84b9
 %left DOT
3c1a8ef8
 
d4799027
 /* no precedence, they use () */
 %token STRLEN
 %token STREMPTY
 
3c1a8ef8
 /* values */
c07508e2
 %token <intval> NUMBER
 %token <strval> ID
f9276a5b
 %token <strval> NUM_ID
c07508e2
 %token <strval> STRING
4e2fdd79
 %token <strval> IPV6ADDR
26a886bc
 %token <strval> PVAR
 /* not clear yet if this is an avp or pvar */
 %token <strval> AVP_OR_PVAR
31b5e3d0
 %token <strval> EVENT_RT_NAME
3c1a8ef8
 
 /* other */
 %token COMMA
 %token SEMICOLON
 %token RPAREN
 %token LPAREN
 %token LBRACE
 %token RBRACE
 %token LBRACK
 %token RBRACK
 %token CR
e5f4cdaf
 %token COLON
3c1a8ef8
 
 
 /*non-terminals */
8637f340
 /*%type <expr> exp */
 %type <expr> exp_elem
80ae84b9
 %type <intval> intno eint_op eint_op_onsend
 %type <intval> eip_op eip_op_onsend
 %type <action> action actions cmd fcmd if_cmd stm /*exp_stm*/ assign_action
6c51c69f
 %type <action> switch_cmd while_cmd ret_cmd
a29a8b6d
 %type <case_stms> single_case case_stms
e5f4cdaf
 %type <ipaddr> ipv4 ipv6 ipv6addr ip
4e2fdd79
 %type <ipnet> ipnet
f9276a5b
 %type <strval> host host_or_if host_if_id
57e2cd15
 %type <strval> listen_id
eb321e3f
 %type <name_l> listen_id_lst
 %type <name_l> listen_id2
6cd48835
 %type <sockid>  id_lst
 %type <sockid>  phostport
eb321e3f
 %type <sockid>  listen_phostport
8393efff
 %type <intval> proto eqproto port
bf7485ba
 %type <intval> equalop strop cmpop rve_cmpop rve_equalop
6b7de230
 %type <intval> uri_type
74ce7043
 %type <attr> attr_id
145e3fb3
 %type <attr> attr_id_num_idx
 %type <attr> attr_id_no_idx
 %type <attr> attr_id_ass
80ae84b9
 /*%type <attr> attr_id_val*/
145e3fb3
 %type <attr> attr_id_any
85d4627f
 %type <attr> attr_id_any_str
26a886bc
 %type <pvar> pvar
cddb9399
 %type <lval> lval
a29a8b6d
 %type <rv_expr> rval rval_expr ct_rval
cddb9399
 %type <lval> avp_pvar
90d859b2
 /* %type <intval> class_id */
74ce7043
 %type <intval> assign_op
3fb428ed
 %type <select> select_id
65938e0e
 %type <strval>	flag_name;
93349b4e
 %type <strval>	route_name;
85d4627f
 %type <intval> avpflag_oper
cddb9399
 %type <intval> rve_un_op
b269c881
 %type <strval> cfg_var_id
80ae84b9
 /* %type <intval> rve_op */
65938e0e
 
f20a56a2
 /*%type <route_el> rules;
   %type <route_el> rule;
 */
3c1a8ef8
 
 %%
 
 
f141bc93
 cfg:
 	statements
3c1a8ef8
 	;
f141bc93
 statements:
 	statements statement {}
 	| statement {}
 	| statements error { yyerror(""); YYABORT;}
3c1a8ef8
 	;
f141bc93
 statement:
 	assign_stm
20cddb28
 	| preprocess_stm
65938e0e
 	| flags_decl
85d4627f
 	| avpflags_decl
f141bc93
 	| module_stm
 	| {rt=REQUEST_ROUTE;} route_stm
 	| {rt=FAILURE_ROUTE;} failure_route_stm
5e0e999a
 	| onreply_route_stm
f141bc93
 	| {rt=BRANCH_ROUTE;} branch_route_stm
 	| {rt=ONSEND_ROUTE;}   send_route_stm
31b5e3d0
 	| {rt=EVENT_ROUTE;}   event_route_stm
f141bc93
 	| SEMICOLON	/* null statement */
 	| CR	/* null statement*/
3c1a8ef8
 	;
f141bc93
 listen_id:
 	ip {
06020e85
 		if ($1){
 			tmp=ip_addr2a($1);
 			if (tmp==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
 						"address.\n");
 				$$=0;
f141bc93
 			} else {
06020e85
 				$$=pkg_malloc(strlen(tmp)+1);
 				if ($$==0) {
 					LOG(L_CRIT, "ERROR: cfg. parser: out of "
 							"memory.\n");
 				} else {
 					strncpy($$, tmp, strlen(tmp)+1);
 				}
f141bc93
 			}
 		}
 	}
 	| STRING {
 		$$=pkg_malloc(strlen($1)+1);
 		if ($$==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: out of "
 						"memory.\n");
 		} else {
 				strncpy($$, $1, strlen($1)+1);
 		}
 	}
f9276a5b
 	| host_or_if {
06020e85
 		if ($1){
 			$$=pkg_malloc(strlen($1)+1);
 			if ($$==0) {
 					LOG(L_CRIT, "ERROR: cfg. parser: out of "
 							"memory.\n");
 			} else {
 					strncpy($$, $1, strlen($1)+1);
 			}
f141bc93
 		}
 	}
57e2cd15
 	;
eb321e3f
 
 
 listen_id_lst:
 	listen_id	{ $$=mk_name_lst($1, SI_IS_MHOMED); }
 	| listen_id COMMA listen_id_lst	{ $$=mk_name_lst($1, SI_IS_MHOMED); 
 										if ($$) $$->next=$3;
 									}
 	;
 
 listen_id2:
 	LPAREN listen_id_lst RPAREN { $$=$2; }
 	| listen_id	{ $$=mk_name_lst($1, 0); }
 	;
 
f141bc93
 proto:
 	UDP	{ $$=PROTO_UDP; }
 	| TCP	{ $$=PROTO_TCP; }
 	| TLS	{ $$=PROTO_TLS; }
c9831d2a
 	| SCTP	{ $$=PROTO_SCTP; }
f141bc93
 	| STAR	{ $$=0; }
 	;
8393efff
 eqproto:
 	UDP	{ $$=PROTO_UDP; }
 	| TCP	{ $$=PROTO_TCP; }
 	| TLS	{ $$=PROTO_TLS; }
 	| SCTP	{ $$=PROTO_SCTP; }
 	| WS	{ $$=PROTO_WS; }
 	| WSS	{ $$=PROTO_WSS; }
 	| STAR	{ $$=0; }
 	;
f141bc93
 port:
 	NUMBER	{ $$=$1; }
 	| STAR	{ $$=0; }
e5f4cdaf
 ;
f141bc93
 phostport:
 	listen_id		{ $$=mk_listen_id($1, 0, 0); }
 	| listen_id COLON port	{ $$=mk_listen_id($1, 0, $3); }
 	| proto COLON listen_id	{ $$=mk_listen_id($3, $1, 0); }
 	| proto COLON listen_id COLON port	{ $$=mk_listen_id($3, $1, $5);}
 	| listen_id COLON error { $$=0; yyerror(" port number expected"); }
3c1a8ef8
 	;
eb321e3f
 
 listen_phostport:
 	listen_id2		{ $$=mk_listen_id2($1, 0, 0); }
 	| listen_id2 COLON port	{ $$=mk_listen_id2($1, 0, $3); }
 	| proto COLON listen_id2	{ $$=mk_listen_id2($3, $1, 0); }
 	| proto COLON listen_id2 COLON port	{ $$=mk_listen_id2($3, $1, $5);}
 	| listen_id2 COLON error { $$=0; yyerror(" port number expected"); }
 	;
 
f141bc93
 id_lst:
eb321e3f
 	listen_phostport		{  $$=$1 ; }
06020e85
 	| listen_phostport id_lst	{ $$=$1;  if ($$) $$->next=$2; }
3c1a8ef8
 	;
65938e0e
 
80ae84b9
 intno: NUMBER
835c266e
 	|  MINUS NUMBER %prec UNARY { $$=-$2; }
80ae84b9
 	;
 
65938e0e
 flags_decl:		FLAGS_DECL	flag_list
4a745629
 			|	FLAGS_DECL error { yyerror("flag list expected\n"); }
65938e0e
 ;
 flag_list:		flag_spec
 			|	flag_spec COMMA flag_list
 ;
 
 flag_spec:		flag_name	{ if (register_flag($1,-1)<0)
 								yyerror("register flag failed");
 						}
 			|	flag_name COLON NUMBER {
 						if (register_flag($1, $3)<0)
 								yyerror("register flag failed");
 										}
 ;
 
 flag_name:		STRING	{ $$=$1; }
 			|	ID		{ $$=$1; }
 ;
 
85d4627f
 avpflags_decl:
 	AVPFLAGS_DECL avpflag_list
 	| AVPFLAGS_DECL error { yyerror("avpflag list expected\n"); }
 	;
 avpflag_list:
 	avpflag_spec
 	| avpflag_spec COMMA avpflag_list
 	;
 avpflag_spec:
 	flag_name {
 		if (register_avpflag($1)==0)
 			yyerror("cannot declare avpflag");
 	}
 	;
f141bc93
 assign_stm:
80ae84b9
 	DEBUG_V EQUAL intno { default_core_cfg.debug=$3; }
f141bc93
 	| DEBUG_V EQUAL error  { yyerror("number  expected"); }
 	| FORK  EQUAL NUMBER { dont_fork= ! $3; }
 	| FORK  EQUAL error  { yyerror("boolean value expected"); }
c2429a58
 	| FORK_DELAY  EQUAL NUMBER { set_fork_delay($3); }
 	| FORK_DELAY  EQUAL error  { yyerror("number expected"); }
52d33940
 	| MODINIT_DELAY  EQUAL NUMBER { set_modinit_delay($3); }
 	| MODINIT_DELAY  EQUAL error  { yyerror("number expected"); }
9d5ef992
 	| LOGSTDERROR EQUAL NUMBER { if (!config_check)  /* if set from cmd line, don't overwrite from yyparse()*/ 
 					if(log_stderr == 0) log_stderr=$3; 
 				   }
f141bc93
 	| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
 	| LOGFACILITY EQUAL ID {
 		if ( (i_tmp=str2facility($3))==-1)
 			yyerror("bad facility (see syslog(3) man page)");
 		if (!config_check)
0d09b88d
 			default_core_cfg.log_facility=i_tmp;
f141bc93
 	}
 	| LOGFACILITY EQUAL error { yyerror("ID expected"); }
95bf8645
 	| LOGNAME EQUAL STRING { log_name=$3; }
 	| LOGNAME EQUAL error { yyerror("string value expected"); }
fe00a334
 	| LOGCOLOR EQUAL NUMBER { log_color=$3; }
 	| LOGCOLOR EQUAL error { yyerror("boolean value expected"); }
35e94c97
 	| LOGPREFIX EQUAL STRING { log_prefix_fmt=$3; }
 	| LOGPREFIX EQUAL error { yyerror("string value expected"); }
b36f7c9a
 	| LOGPREFIXMODE EQUAL NUMBER { log_prefix_mode=$3; }
 	| LOGPREFIXMODE EQUAL error { yyerror("number expected"); }
88b06d1f
 	| LOGENGINETYPE EQUAL STRING { _km_log_engine_type=$3; }
 	| LOGENGINETYPE EQUAL error { yyerror("string value expected"); }
 	| LOGENGINEDATA EQUAL STRING { _km_log_engine_data=$3; }
 	| LOGENGINEDATA EQUAL error { yyerror("string value expected"); }
f141bc93
 	| DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
 	| DNS EQUAL error { yyerror("boolean value expected"); }
 	| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
 	| REV_DNS EQUAL error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_TRY_IPV6 EQUAL NUMBER   { default_core_cfg.dns_try_ipv6=$3; }
f141bc93
 	| DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_TRY_NAPTR EQUAL NUMBER   { IF_NAPTR(default_core_cfg.dns_try_naptr=$3); }
dd4ffbb7
 	| DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_SRV_LB EQUAL NUMBER   { IF_DNS_FAILOVER(default_core_cfg.dns_srv_lb=$3); }
dd4ffbb7
 	| DNS_SRV_LB error { yyerror("boolean value expected"); }
80ae84b9
 	| DNS_UDP_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_udp_pref=$3);}
dd4ffbb7
 	| DNS_UDP_PREF error { yyerror("number expected"); }
80ae84b9
 	| DNS_TCP_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tcp_pref=$3);}
dd4ffbb7
 	| DNS_TCP_PREF error { yyerror("number expected"); }
80ae84b9
 	| DNS_TLS_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tls_pref=$3);}
dd4ffbb7
 	| DNS_TLS_PREF error { yyerror("number expected"); }
80ae84b9
 	| DNS_SCTP_PREF EQUAL intno { 
7d11cc0c
 								IF_NAPTR(default_core_cfg.dns_sctp_pref=$3); }
 	| DNS_SCTP_PREF error { yyerror("number expected"); }
2cfcc6bb
 	| DNS_RETR_TIME EQUAL NUMBER   { default_core_cfg.dns_retr_time=$3; }
f141bc93
 	| DNS_RETR_TIME error { yyerror("number expected"); }
2cfcc6bb
 	| DNS_RETR_NO EQUAL NUMBER   { default_core_cfg.dns_retr_no=$3; }
f141bc93
 	| DNS_RETR_NO error { yyerror("number expected"); }
2cfcc6bb
 	| DNS_SERVERS_NO EQUAL NUMBER   { default_core_cfg.dns_servers_no=$3; }
f141bc93
 	| DNS_SERVERS_NO error { yyerror("number expected"); }
2cfcc6bb
 	| DNS_USE_SEARCH EQUAL NUMBER   { default_core_cfg.dns_search_list=$3; }
f141bc93
 	| DNS_USE_SEARCH error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_SEARCH_FMATCH EQUAL NUMBER   { default_core_cfg.dns_search_fmatch=$3; }
740a5978
 	| DNS_SEARCH_FMATCH error { yyerror("boolean value expected"); }
a9fc979c
 	| DNS_NAPTR_IGNORE_RFC EQUAL NUMBER   { default_core_cfg.dns_naptr_ignore_rfc=$3; }
 	| DNS_NAPTR_IGNORE_RFC error { yyerror("boolean value expected"); }
7905e2d6
 	| DNS_CACHE_INIT EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_init=$3); }
 	| DNS_CACHE_INIT error { yyerror("boolean value expected"); }
 	| DNS_USE_CACHE EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.use_dns_cache=$3); }
dcb59e67
 	| DNS_USE_CACHE error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_USE_FAILOVER EQUAL NUMBER   { IF_DNS_FAILOVER(default_core_cfg.use_dns_failover=$3);}
dcb59e67
 	| DNS_USE_FAILOVER error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_CACHE_FLAGS EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_flags=$3); }
dcb59e67
 	| DNS_CACHE_FLAGS error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_CACHE_NEG_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_neg_cache_ttl=$3); }
dcb59e67
 	| DNS_CACHE_NEG_TTL error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_CACHE_MAX_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_max_ttl=$3); }
dcb59e67
 	| DNS_CACHE_MAX_TTL error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_CACHE_MIN_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_min_ttl=$3); }
dcb59e67
 	| DNS_CACHE_MIN_TTL error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_CACHE_MEM EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_max_mem=$3); }
dcb59e67
 	| DNS_CACHE_MEM error { yyerror("boolean value expected"); }
 	| DNS_CACHE_GC_INT EQUAL NUMBER   { IF_DNS_CACHE(dns_timer_interval=$3); }
 	| DNS_CACHE_GC_INT error { yyerror("boolean value expected"); }
2cfcc6bb
 	| DNS_CACHE_DEL_NONEXP EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_del_nonexp=$3); }
4136d191
 	| DNS_CACHE_DEL_NONEXP error { yyerror("boolean value expected"); }
0d4d530e
 	| DNS_CACHE_REC_PREF EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_rec_pref=$3); }
 	| DNS_CACHE_REC_PREF error { yyerror("boolean value expected"); }
3e154160
 	| AUTO_BIND_IPV6 EQUAL NUMBER {IF_AUTO_BIND_IPV6(auto_bind_ipv6 = $3);}
bd3d3546
 	| AUTO_BIND_IPV6 error { yyerror("boolean value expected"); }
7905e2d6
 	| DST_BLST_INIT EQUAL NUMBER   { IF_DST_BLACKLIST(dst_blacklist_init=$3); }
 	| DST_BLST_INIT error { yyerror("boolean value expected"); }
0e055147
 	| USE_DST_BLST EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.use_dst_blacklist=$3);
 	}
dcb59e67
 	| USE_DST_BLST error { yyerror("boolean value expected"); }
0e055147
 	| DST_BLST_MEM EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.blst_max_mem=$3); 
 	}
dcb59e67
 	| DST_BLST_MEM error { yyerror("boolean value expected"); }
0e055147
 	| DST_BLST_TTL EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.blst_timeout=$3);
 	}
dcb59e67
 	| DST_BLST_TTL error { yyerror("boolean value expected"); }
 	| DST_BLST_GC_INT EQUAL NUMBER { IF_DST_BLACKLIST(blst_timer_interval=$3);}
 	| DST_BLST_GC_INT error { yyerror("boolean value expected"); }
0e055147
 	| DST_BLST_UDP_IMASK EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.blst_udp_imask=$3);
 	}
 	| DST_BLST_UDP_IMASK error { yyerror("number(flags) expected"); }
 	| DST_BLST_TCP_IMASK EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.blst_tcp_imask=$3);
 	}
 	| DST_BLST_TCP_IMASK error { yyerror("number(flags) expected"); }
 	| DST_BLST_TLS_IMASK EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.blst_tls_imask=$3);
 	}
 	| DST_BLST_TLS_IMASK error { yyerror("number(flags) expected"); }
 	| DST_BLST_SCTP_IMASK EQUAL NUMBER {
 		IF_DST_BLACKLIST(default_core_cfg.blst_sctp_imask=$3);
 	}
 	| DST_BLST_SCTP_IMASK error { yyerror("number(flags) expected"); }
f141bc93
 	| PORT EQUAL NUMBER   { port_no=$3; }
 	| STAT EQUAL STRING {
 		#ifdef STATS
 				stat_file=$3;
 		#endif
 	}
 	| MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
 	| MAXBUFFER EQUAL error { yyerror("number expected"); }
5cd87175
     | SQL_BUFFER_SIZE EQUAL NUMBER { sql_buffer_size=$3; }
 	| SQL_BUFFER_SIZE EQUAL error { yyerror("number expected"); }
f141bc93
 	| PORT EQUAL error    { yyerror("number expected"); }
 	| CHILDREN EQUAL NUMBER { children_no=$3; }
 	| CHILDREN EQUAL error { yyerror("number expected"); }
edf5e385
 	| SOCKET_WORKERS EQUAL NUMBER { socket_workers=$3; }
 	| SOCKET_WORKERS EQUAL error { yyerror("number expected"); }
d5a22ca8
 	| ASYNC_WORKERS EQUAL NUMBER { async_task_set_workers($3); }
 	| ASYNC_WORKERS EQUAL error { yyerror("number expected"); }
55be13df
 	| ASYNC_USLEEP EQUAL NUMBER { async_task_set_usleep($3); }
 	| ASYNC_USLEEP EQUAL error { yyerror("number expected"); }
f141bc93
 	| CHECK_VIA EQUAL NUMBER { check_via=$3; }
 	| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
face488e
 	| PHONE2TEL EQUAL NUMBER { phone2tel=$3; }
 	| PHONE2TEL EQUAL error { yyerror("boolean value expected"); }
e4f42ce1
 	| MEMLOG EQUAL intno { default_core_cfg.memlog=$3; }
f141bc93
 	| MEMLOG EQUAL error { yyerror("int value expected"); }
e4f42ce1
 	| MEMDBG EQUAL intno { default_core_cfg.memdbg=$3; }
58d0d1b5
 	| MEMDBG EQUAL error { yyerror("int value expected"); }
d740c34e
 	| MEMSUM EQUAL intno { default_core_cfg.mem_summary=$3; }
 	| MEMSUM EQUAL error { yyerror("int value expected"); }
ffb8754f
 	| MEMSAFETY EQUAL intno { default_core_cfg.mem_safety=$3; }
 	| MEMSAFETY EQUAL error { yyerror("int value expected"); }
d89420df
 	| MEMJOIN EQUAL intno { default_core_cfg.mem_join=$3; }
 	| MEMJOIN EQUAL error { yyerror("int value expected"); }
7e2e4ff4
 	| CORELOG EQUAL intno { default_core_cfg.corelog=$3; }
 	| CORELOG EQUAL error { yyerror("int value expected"); }
f141bc93
 	| SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
 	| SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
8fb8b261
 	| VERSION_TABLE_CFG EQUAL STRING { version_table.s=$3;
 			version_table.len=strlen(version_table.s);
 	}
 	| VERSION_TABLE_CFG EQUAL error { yyerror("string value expected"); }
6f722344
 	| USER EQUAL STRING     {
 		if (shm_initialized())
 			yyerror("user must be before any modparam or the"
 					" route blocks");
 		else if (user==0)
 			user=$3; 
 	}
 	| USER EQUAL ID         {
 		if (shm_initialized())
 			yyerror("user must be before any modparam or the"
 					" route blocks");
 		else if (user==0)
 			user=$3;
 	}
f141bc93
 	| USER EQUAL error      { yyerror("string value expected"); }
 	| GROUP EQUAL STRING     { group=$3; }
 	| GROUP EQUAL ID         { group=$3; }
 	| GROUP EQUAL error      { yyerror("string value expected"); }
 	| CHROOT EQUAL STRING     { chroot_dir=$3; }
 	| CHROOT EQUAL ID         { chroot_dir=$3; }
 	| CHROOT EQUAL error      { yyerror("string value expected"); }
 	| WDIR EQUAL STRING     { working_dir=$3; }
 	| WDIR EQUAL ID         { working_dir=$3; }
 	| WDIR EQUAL error      { yyerror("string value expected"); }
ca1358f2
 	| RUNDIR EQUAL STRING     { runtime_dir=$3; }
 	| RUNDIR EQUAL ID         { runtime_dir=$3; }
 	| RUNDIR EQUAL error      { yyerror("string value expected"); }
f141bc93
 	| MHOMED EQUAL NUMBER { mhomed=$3; }
 	| MHOMED EQUAL error { yyerror("boolean value expected"); }
 	| DISABLE_TCP EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_disable=$3;
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
 	| TCP_ACCEPT_ALIASES EQUAL NUMBER {
 		#ifdef USE_TCP
3dc4f620
 			tcp_default_cfg.accept_aliases=$3;
f141bc93
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
 	| TCP_CHILDREN EQUAL NUMBER {
 		#ifdef USE_TCP
edf5e385
 			tcp_cfg_children_no=$3;
f141bc93
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_CHILDREN EQUAL error { yyerror("number expected"); }
80ae84b9
 	| TCP_CONNECT_TIMEOUT EQUAL intno {
f141bc93
 		#ifdef USE_TCP
3dc4f620
 			tcp_default_cfg.connect_timeout_s=$3;
f141bc93
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
80ae84b9
 	| TCP_SEND_TIMEOUT EQUAL intno {
f141bc93
 		#ifdef USE_TCP
ffc72fcf
 			tcp_default_cfg.send_timeout=S_TO_TICKS($3);
f141bc93
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
80ae84b9
 	| TCP_CON_LIFETIME EQUAL intno {
f141bc93
 		#ifdef USE_TCP
9a74e06a
 			if ($3<0)
 				tcp_default_cfg.con_lifetime=-1;
 			else
 				tcp_default_cfg.con_lifetime=S_TO_TICKS($3);
f141bc93
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
 	| TCP_POLL_METHOD EQUAL ID {
 		#ifdef USE_TCP
 			tcp_poll_method=get_poll_type($3);
 			if (tcp_poll_method==POLL_NONE) {
 				LOG(L_CRIT, "bad poll method name:"
 						" %s\n, try one of %s.\n",
 						$3, poll_support);
 				yyerror("bad tcp_poll_method "
 						"value");
 			}
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_POLL_METHOD EQUAL STRING {
 		#ifdef USE_TCP
 			tcp_poll_method=get_poll_type($3);
 			if (tcp_poll_method==POLL_NONE) {
 				LOG(L_CRIT, "bad poll method name:"
 						" %s\n, try one of %s.\n",
 						$3, poll_support);
 				yyerror("bad tcp_poll_method "
 						"value");
 			}
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_POLL_METHOD EQUAL error { yyerror("poll method name expected"); }
 	| TCP_MAX_CONNECTIONS EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_max_connections=$3;
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
61f8b970
 	| TLS_MAX_CONNECTIONS EQUAL NUMBER {
 		#ifdef USE_TLS
 			tls_max_connections=$3;
 		#else
 			warn("tls support not compiled in");
 		#endif
 	}
 	| TLS_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
de223f01
 	| TCP_NO_CONNECT EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_default_cfg.no_connect=$3;
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_NO_CONNECT EQUAL error { yyerror("boolean value expected"); }
761bd309
 	| TCP_SOURCE_IPV4 EQUAL ipv4 {
 		#ifdef USE_TCP
205fcb02
 			if (tcp_set_src_addr($3)<0)
 				warn("tcp_source_ipv4 failed");
761bd309
 		#else
 			warn("tcp support not compiled in");
 		#endif
 		pkg_free($3);
 	}
 	| TCP_SOURCE_IPV4 EQUAL error { yyerror("IPv4 address expected"); }
 	| TCP_SOURCE_IPV6 EQUAL ipv6 {
 		#ifdef USE_TCP
205fcb02
 				if (tcp_set_src_addr($3)<0)
 					warn("tcp_source_ipv6 failed");
761bd309
 		#else
 			warn("tcp support not compiled in");
 		#endif
 		pkg_free($3);
 	}
 	| TCP_SOURCE_IPV6 EQUAL error { yyerror("IPv6 address expected"); }
20c64cc6
 	| TCP_OPT_FD_CACHE EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.fd_cache=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_FD_CACHE EQUAL error { yyerror("boolean value expected"); }
885b9f62
 	| TCP_OPT_BUF_WRITE EQUAL NUMBER {
 		#ifdef USE_TCP
76cb799e
 			tcp_default_cfg.async=$3;
885b9f62
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_BUF_WRITE EQUAL error { yyerror("boolean value expected"); }
 	| TCP_OPT_CONN_WQ_MAX EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.tcpconn_wq_max=$3;
885b9f62
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_CONN_WQ_MAX error { yyerror("boolean value expected"); }
 	| TCP_OPT_WQ_MAX EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.tcp_wq_max=$3;
885b9f62
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
e655392a
 	| TCP_OPT_WQ_MAX error { yyerror("number expected"); }
 	| TCP_OPT_RD_BUF EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_default_cfg.rd_buf_size=$3;
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_RD_BUF error { yyerror("number expected"); }
 	| TCP_OPT_WQ_BLK EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_default_cfg.wq_blk_size=$3;
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_WQ_BLK error { yyerror("number expected"); }
20c64cc6
 	| TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.defer_accept=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_DEFER_ACCEPT EQUAL error { yyerror("boolean value expected"); }
 	| TCP_OPT_DELAYED_ACK EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.delayed_ack=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_DELAYED_ACK EQUAL error { yyerror("boolean value expected"); }
 	| TCP_OPT_SYNCNT EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.syncnt=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_SYNCNT EQUAL error { yyerror("number expected"); }
 	| TCP_OPT_LINGER2 EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.linger2=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_LINGER2 EQUAL error { yyerror("number expected"); }
 	| TCP_OPT_KEEPALIVE EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.keepalive=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_KEEPALIVE EQUAL error { yyerror("boolean value expected");}
 	| TCP_OPT_KEEPIDLE EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.keepidle=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_KEEPIDLE EQUAL error { yyerror("number expected"); }
 	| TCP_OPT_KEEPINTVL EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.keepintvl=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_KEEPINTVL EQUAL error { yyerror("number expected"); }
 	| TCP_OPT_KEEPCNT EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.keepcnt=$3;
20c64cc6
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
c7337a27
 	| TCP_OPT_CRLF_PING EQUAL NUMBER {
 		#ifdef USE_TCP
22db42e4
 			tcp_default_cfg.crlf_ping=$3;
c7337a27
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_CRLF_PING EQUAL error { yyerror("boolean value expected"); }
d4cc4103
 	| TCP_OPT_ACCEPT_NO_CL EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_default_cfg.accept_no_cl=$3;
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_OPT_ACCEPT_NO_CL EQUAL error { yyerror("boolean value expected"); }
691a3439
 	| TCP_CLONE_RCVBUF EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_set_clone_rcvbuf($3);
 		#else
 			warn("tcp support not compiled in");
 		#endif
 	}
 	| TCP_CLONE_RCVBUF EQUAL error { yyerror("number expected"); }
8737eaf4
 	| DISABLE_TLS EQUAL NUMBER {
 		#ifdef USE_TLS
 			tls_disable=$3;
 		#else
 			warn("tls support not compiled in");
 		#endif
 	}
 	| DISABLE_TLS EQUAL error { yyerror("boolean value expected"); }
6c53d41a
 	| ENABLE_TLS EQUAL NUMBER {
8737eaf4
 		#ifdef USE_TLS
6c53d41a
 			tls_disable=!($3);
8737eaf4
 		#else
 			warn("tls support not compiled in");
 		#endif
 	}
6c53d41a
 	| ENABLE_TLS EQUAL error { yyerror("boolean value expected"); }
 	| TLSLOG EQUAL NUMBER {
 		#ifdef CORE_TLS
 			tls_log=$3;
 		#else
 			warn("tls-in-core support not compiled in");
 		#endif
 	}
8737eaf4
 	| TLSLOG EQUAL error { yyerror("int value expected"); }
 	| TLS_PORT_NO EQUAL NUMBER {
 		#ifdef USE_TLS
 			tls_port_no=$3;
 		#else
 			warn("tls support not compiled in");
 		#endif
 	}
 	| TLS_PORT_NO EQUAL error { yyerror("number expected"); }
 	| TLS_METHOD EQUAL SSLv23 {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_method=TLS_USE_SSLv23;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_METHOD EQUAL SSLv2 {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_method=TLS_USE_SSLv2;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_METHOD EQUAL SSLv3 {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_method=TLS_USE_SSLv3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_METHOD EQUAL TLSv1 {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_method=TLS_USE_TLSv1;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_METHOD EQUAL error {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			yyerror("SSLv23, SSLv2, SSLv3 or TLSv1 expected");
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_VERIFY EQUAL NUMBER {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_verify_cert=$3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_VERIFY EQUAL error { yyerror("boolean value expected"); }
 	| TLS_REQUIRE_CERTIFICATE EQUAL NUMBER {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_require_cert=$3;
 		#else
6c53d41a
 			warn( "tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_REQUIRE_CERTIFICATE EQUAL error { yyerror("boolean value expected"); }
 	| TLS_CERTIFICATE EQUAL STRING {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_cert_file=$3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_CERTIFICATE EQUAL error { yyerror("string value expected"); }
 	| TLS_PRIVATE_KEY EQUAL STRING {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_pkey_file=$3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_PRIVATE_KEY EQUAL error { yyerror("string value expected"); }
 	| TLS_CA_LIST EQUAL STRING {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_ca_file=$3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
 	| TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_handshake_timeout=$3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
 	| TLS_SEND_TIMEOUT EQUAL NUMBER {
6c53d41a
 		#ifdef CORE_TLS
8737eaf4
 			tls_send_timeout=$3;
 		#else
6c53d41a
 			warn("tls-in-core support not compiled in");
8737eaf4
 		#endif
 	}
 	| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
ed990c31
 	| DISABLE_SCTP EQUAL NUMBER {
 		#ifdef USE_SCTP
 			sctp_disable=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
 	}
 	| DISABLE_SCTP EQUAL error { yyerror("boolean value expected"); }
c8e95587
 	| ENABLE_SCTP EQUAL NUMBER {
 		#ifdef USE_SCTP
 			sctp_disable=($3<=1)?!$3:$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
 	}
 	| ENABLE_SCTP EQUAL error { yyerror("boolean or number expected"); }
ed990c31
 	| SCTP_CHILDREN EQUAL NUMBER {
 		#ifdef USE_SCTP
 			sctp_children_no=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
 	}
 	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
f141bc93
 	| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
 	| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
c745469f
 	| SERVER_HEADER EQUAL STRING { server_hdr.s=$3;
 			server_hdr.len=strlen(server_hdr.s);
 	}
 	| SERVER_HEADER EQUAL error { yyerror("string value expected"); }
 	| USER_AGENT_HEADER EQUAL STRING { user_agent_hdr.s=$3;
 			user_agent_hdr.len=strlen(user_agent_hdr.s);
 	}
 	| USER_AGENT_HEADER EQUAL error { yyerror("string value expected"); }
f141bc93
 	| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
 	| REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
 	| LISTEN EQUAL id_lst {
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
eb321e3f
 			if (add_listen_iface(	lst_tmp->addr_lst->name,
 									lst_tmp->addr_lst->next,
 									lst_tmp->port, lst_tmp->proto,
 									lst_tmp->flags)!=0) {
 				LOG(L_CRIT,  "ERROR: cfg. parser: failed to add listen"
 								" address\n");
f141bc93
 				break;
 			}
 		}
eb321e3f
 		free_socket_id_lst($3);
f141bc93
 	}
574daa6d
 	| LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER {
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
 			if (add_listen_advertise_iface(	lst_tmp->addr_lst->name,
 									lst_tmp->addr_lst->next,
 									lst_tmp->port, lst_tmp->proto,
 									$5, $7,
 									lst_tmp->flags)!=0) {
 				LOG(L_CRIT,  "ERROR: cfg. parser: failed to add listen"
 								" address\n");
 				break;
 			}
 		}
 		free_socket_id_lst($3);
 	}
06020e85
 	| LISTEN EQUAL  error { yyerror("ip address, interface name or"
 									" hostname expected"); }
f141bc93
 	| ALIAS EQUAL  id_lst {
eb321e3f
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
 			add_alias(	lst_tmp->addr_lst->name,
 						strlen(lst_tmp->addr_lst->name),
 						lst_tmp->port, lst_tmp->proto);
 			for (nl_tmp=lst_tmp->addr_lst->next; nl_tmp; nl_tmp=nl_tmp->next)
 				add_alias(nl_tmp->name, strlen(nl_tmp->name),
 							lst_tmp->port, lst_tmp->proto);
 		}
 		free_socket_id_lst($3);
f141bc93
 	}
 	| ALIAS  EQUAL error  { yyerror(" hostname expected"); }
bb4cd6b0
 	| SR_AUTO_ALIASES EQUAL NUMBER { sr_auto_aliases=$3; }
 	| SR_AUTO_ALIASES EQUAL error  { yyerror("boolean value expected"); }
f141bc93
 	| ADVERTISED_ADDRESS EQUAL listen_id {
06020e85
 		if ($3){
 			default_global_address.s=$3;
 			default_global_address.len=strlen($3);
 		}
f141bc93
 	}
 	| ADVERTISED_ADDRESS EQUAL error {yyerror("ip address or hostname expected"); }
 	| ADVERTISED_PORT EQUAL NUMBER {
 		tmp=int2str($3, &i_tmp);
 		if ((default_global_port.s=pkg_malloc(i_tmp))==0) {
 			LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
 			default_global_port.len=0;
 		} else {
 			default_global_port.len=i_tmp;
 			memcpy(default_global_port.s, tmp, default_global_port.len);
 		};
 	}
 	|ADVERTISED_PORT EQUAL error {yyerror("ip address or hostname expected"); }
 	| DISABLE_CORE EQUAL NUMBER { disable_core_dump=$3; }
 	| DISABLE_CORE EQUAL error { yyerror("boolean value expected"); }
 	| OPEN_FD_LIMIT EQUAL NUMBER { open_files_limit=$3; }
 	| OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); }
647cc983
 	| SHM_MEM_SZ EQUAL NUMBER {
 		if (shm_initialized())
 			yyerror("shm/shm_mem_size must be before any modparam or the"
 					" route blocks");
 		else if (shm_mem_size == 0)
 			shm_mem_size=$3 * 1024 * 1024;
 	}
 	| SHM_MEM_SZ EQUAL error { yyerror("number expected"); }
6f722344
 	| SHM_FORCE_ALLOC EQUAL NUMBER {
 		if (shm_initialized())
 			yyerror("shm_force_alloc must be before any modparam or the"
 					" route blocks");
 		else
 			shm_force_alloc=$3;
 	}
71a0a583
 	| SHM_FORCE_ALLOC EQUAL error { yyerror("boolean value expected"); }
 	| MLOCK_PAGES EQUAL NUMBER { mlock_pages=$3; }
 	| MLOCK_PAGES EQUAL error { yyerror("boolean value expected"); }
 	| REAL_TIME EQUAL NUMBER { real_time=$3; }
 	| REAL_TIME EQUAL error { yyerror("boolean value expected"); }
 	| RT_PRIO EQUAL NUMBER { rt_prio=$3; }
 	| RT_PRIO EQUAL error { yyerror("boolean value expected"); }
 	| RT_POLICY EQUAL NUMBER { rt_policy=$3; }
 	| RT_POLICY EQUAL error { yyerror("boolean value expected"); }
 	| RT_TIMER1_PRIO EQUAL NUMBER { rt_timer1_prio=$3; }
 	| RT_TIMER1_PRIO EQUAL error { yyerror("boolean value expected"); }
 	| RT_TIMER1_POLICY EQUAL NUMBER { rt_timer1_policy=$3; }
 	| RT_TIMER1_POLICY EQUAL error { yyerror("boolean value expected"); }
 	| RT_TIMER2_PRIO EQUAL NUMBER { rt_timer2_prio=$3; }
 	| RT_TIMER2_PRIO EQUAL error { yyerror("boolean value expected"); }
 	| RT_TIMER2_POLICY EQUAL NUMBER { rt_timer2_policy=$3; }
 	| RT_TIMER2_POLICY EQUAL error { yyerror("boolean value expected"); }
f141bc93
 	| MCAST_LOOPBACK EQUAL NUMBER {
 		#ifdef USE_MCAST
 			mcast_loopback=$3;
 		#else
 			warn("no multicast support compiled in");
 		#endif
 	}
 	| MCAST_LOOPBACK EQUAL error { yyerror("boolean value expected"); }
 	| MCAST_TTL EQUAL NUMBER {
 		#ifdef USE_MCAST
 			mcast_ttl=$3;
 		#else
 			warn("no multicast support compiled in");
 		#endif
 	}
 	| MCAST_TTL EQUAL error { yyerror("number expected"); }
 	| TOS EQUAL NUMBER { tos=$3; }
d3eb5d4f
 	| TOS EQUAL ID { if (strcasecmp($3,"IPTOS_LOWDELAY")) {
 			tos=IPTOS_LOWDELAY;
 		} else if (strcasecmp($3,"IPTOS_THROUGHPUT")) {
 			tos=IPTOS_THROUGHPUT;
 		} else if (strcasecmp($3,"IPTOS_RELIABILITY")) {
 			tos=IPTOS_RELIABILITY;
 #if defined(IPTOS_MINCOST)
 		} else if (strcasecmp($3,"IPTOS_MINCOST")) {
 			tos=IPTOS_MINCOST;
 #endif
 #if defined(IPTOS_LOWCOST)
 		} else if (strcasecmp($3,"IPTOS_LOWCOST")) {
 			tos=IPTOS_LOWCOST;
 #endif
 		} else {
 			yyerror("invalid tos value - allowed: "
 				"IPTOS_LOWDELAY,IPTOS_THROUGHPUT,"
 				"IPTOS_RELIABILITY"
 #if defined(IPTOS_LOWCOST)
 				",IPTOS_LOWCOST"
 #endif
 #if !defined(IPTOS_MINCOST)
 				",IPTOS_MINCOST"
 #endif
 				"\n");
 		}
 	}
f141bc93
 	| TOS EQUAL error { yyerror("number expected"); }
f3a26797
 	| PMTU_DISCOVERY EQUAL NUMBER { pmtu_discovery=$3; }
 	| PMTU_DISCOVERY error { yyerror("number expected"); }
96d09107
 	| KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
 	| KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
d14a718f
 	| MAX_WLOOPS EQUAL NUMBER { default_core_cfg.max_while_loops=$3; }
 	| MAX_WLOOPS EQUAL error { yyerror("number expected"); }
7614a1d0
 	| PVBUFSIZE EQUAL NUMBER { pv_set_buffer_size($3); }
 	| PVBUFSIZE EQUAL error { yyerror("number expected"); }
 	| PVBUFSLOTS EQUAL NUMBER { pv_set_buffer_slots($3); }
 	| PVBUFSLOTS EQUAL error { yyerror("number expected"); }
adf32ec8
 	| HTTP_REPLY_PARSE EQUAL NUMBER { http_reply_parse=$3; }
 	| HTTP_REPLY_PARSE EQUAL error { yyerror("boolean value expected"); }
89fde575
     | SERVER_ID EQUAL NUMBER { server_id=$3; }
d1c60718
     | MAX_RECURSIVE_LEVEL EQUAL NUMBER { set_max_recursive_level($3); }
e008edb9
     | MAX_BRANCHES_PARAM EQUAL NUMBER { sr_dst_max_branches = $3; }
6e950945
     | LATENCY_LOG EQUAL intno { default_core_cfg.latency_log=$3; }
930aba29
 	| LATENCY_LOG EQUAL error  { yyerror("number  expected"); }
6e950945
     | LATENCY_CFG_LOG EQUAL intno { default_core_cfg.latency_cfg_log=$3; }
e80c2473
 	| LATENCY_CFG_LOG EQUAL error  { yyerror("number  expected"); }
930aba29
     | LATENCY_LIMIT_DB EQUAL NUMBER { default_core_cfg.latency_limit_db=$3; }
 	| LATENCY_LIMIT_DB EQUAL error  { yyerror("number  expected"); }
     | LATENCY_LIMIT_ACTION EQUAL NUMBER { default_core_cfg.latency_limit_action=$3; }
 	| LATENCY_LIMIT_ACTION EQUAL error  { yyerror("number  expected"); }
d4ed4771
     | MSG_TIME EQUAL NUMBER { sr_msg_time=$3; }
 	| MSG_TIME EQUAL error  { yyerror("number  expected"); }
214b161e
 	| ONSEND_RT_REPLY EQUAL NUMBER { onsend_route_reply=$3; }
 	| ONSEND_RT_REPLY EQUAL error { yyerror("int value expected"); }
f62c96d8
 	| UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
 	| UDP_MTU EQUAL error { yyerror("number expected"); }
e80c2473
 	| FORCE_RPORT EQUAL NUMBER
33bfeb9d
 		{ default_core_cfg.force_rport=$3; fix_global_req_flags(0, 0); }
f62c96d8
 	| FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
 	| UDP_MTU_TRY_PROTO EQUAL proto
33bfeb9d
 		{ default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0, 0); }
f62c96d8
 	| UDP_MTU_TRY_PROTO EQUAL error
 		{ yyerror("TCP, TLS, SCTP or UDP expected"); }
e92fe8b4
 	| UDP4_RAW EQUAL intno { IF_RAW_SOCKS(default_core_cfg.udp4_raw=$3); }
 	| UDP4_RAW EQUAL error { yyerror("number expected"); }
 	| UDP4_RAW_MTU EQUAL NUMBER {
 		IF_RAW_SOCKS(default_core_cfg.udp4_raw_mtu=$3);
 	}
 	| UDP4_RAW_MTU EQUAL error { yyerror("number expected"); }
2556cd84
 	| UDP4_RAW_TTL EQUAL NUMBER {
 		IF_RAW_SOCKS(default_core_cfg.udp4_raw_ttl=$3);
 	}
 	| UDP4_RAW_TTL EQUAL error { yyerror("number expected"); }
140137c9
 	| cfg_var
96227c65
 	| error EQUAL { yyerror("unknown config variable"); }
4e2fdd79
 	;
b269c881
 	
 cfg_var_id: ID 
 	| DEFAULT { $$="default" ; } /*needed to allow default as cfg var. name*/
 	;
 	
140137c9
 cfg_var:
b269c881
 	cfg_var_id DOT cfg_var_id EQUAL NUMBER {
c092bd34
 		if (cfg_declare_int($1, $3, $5, 0, 0, NULL)) {
41f2e49c
 			yyerror("variable cannot be declared");
 		}
140137c9
 	}
b269c881
 	| cfg_var_id DOT cfg_var_id EQUAL STRING {
41f2e49c
 		if (cfg_declare_str($1, $3, $5, NULL)) {
 			yyerror("variable cannot be declared");
 		}
140137c9
 	}
b269c881
 	| cfg_var_id DOT cfg_var_id EQUAL NUMBER CFG_DESCRIPTION STRING {
c092bd34
 		if (cfg_declare_int($1, $3, $5, 0, 0, $7)) {
41f2e49c
 			yyerror("variable cannot be declared");
 		}
140137c9
 	}
b269c881
 	| cfg_var_id DOT cfg_var_id EQUAL STRING CFG_DESCRIPTION STRING {
41f2e49c
 		if (cfg_declare_str($1, $3, $5, $7)) {
 			yyerror("variable cannot be declared");
 		}
140137c9
 	}
b269c881
 	| cfg_var_id DOT cfg_var_id EQUAL error { 
 		yyerror("number or string expected"); 
 	}
9235f7d5
 	| cfg_var_id LBRACK NUMBER RBRACK DOT cfg_var_id EQUAL NUMBER {
 		if (cfg_ginst_var_int($1, $3, $6, $8)) {
 			yyerror("variable cannot be added to the group instance");
 		}
 	}
 	| cfg_var_id LBRACK NUMBER RBRACK DOT cfg_var_id EQUAL STRING {
 		if (cfg_ginst_var_string($1, $3, $6, $8)) {
 			yyerror("variable cannot be added to the group instance");
 		}
 	}
140137c9
 	;
b269c881
 
f141bc93
 module_stm:
 	LOADMODULE STRING {
 		DBG("loading module %s\n", $2);
 			if (load_module($2)!=0) {
 				yyerror("failed to load module");
 			}
 	}
 	| LOADMODULE error	{ yyerror("string expected"); }
6c8f8d5b
 	| LOADPATH STRING {
e1e40d3a
 		if(mods_dir_cmd==0) {
 			DBG("loading modules under %s\n", $2);
 			printf("loading modules under config path: %s\n", $2);
 			mods_dir = $2;
 		} else {
 			DBG("ignoring mod path given in config: %s\n", $2);
 			printf("loading modules under command line path: %s\n", mods_dir);
 		}
6c8f8d5b
 	}
 	| LOADPATH error	{ yyerror("string expected"); }
8d503e9e
 	| LOADPATH EQUAL STRING {
e1e40d3a
 		if(mods_dir_cmd==0) {
 			DBG("loading modules under %s\n", $3);
 			printf("loading modules under config path: %s\n", $3);
 			mods_dir = $3;
 		} else {
 			DBG("ignoring mod path given in config: %s\n", $3);
 			printf("loading modules under command line path: %s\n", mods_dir);
 		}
8d503e9e
 	}
 	| LOADPATH EQUAL error	{ yyerror("string expected"); }
f141bc93
 	| MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
f141bc93
 		if (set_mod_param_regex($3, $5, PARAM_STRING, $7) != 0) {
 			 yyerror("Can't set module parameter");
 		}
 	}
d4b2eee2
 	| MODPARAM LPAREN STRING COMMA STRING COMMA intno RPAREN {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
f141bc93
 		if (set_mod_param_regex($3, $5, PARAM_INT, (void*)$7) != 0) {
 			 yyerror("Can't set module parameter");
 		}
 	}
 	| MODPARAM error { yyerror("Invalid arguments"); }
98fa9495
 	| CFGENGINE STRING {
 		if(sr_kemi_eng_setz($2, NULL)) {
 			yyerror("Can't set config routing engine");
 			YYABORT;
 		}
 	}
 	| CFGENGINE error	{ yyerror("string expected"); }
 	| CFGENGINE EQUAL STRING {
 		if(sr_kemi_eng_setz($3, NULL)) {
 			yyerror("Can't set config routing engine");
 			YYABORT;
 		}
 	}
 	| CFGENGINE EQUAL error	{ yyerror("string expected"); }
 
f141bc93
 	;
 ip:
 	ipv4  { $$=$1; }
 	| ipv6  { $$=$1; }
 	;
 ipv4:
 	NUMBER DOT NUMBER DOT NUMBER DOT NUMBER {
 		$$=pkg_malloc(sizeof(struct ip_addr));
 		if ($$==0) {
 			LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
 		} else {
 			memset($$, 0, sizeof(struct ip_addr));
 			$$->af=AF_INET;
 			$$->len=4;
 			if (($1>255) || ($1<0) ||
 				($3>255) || ($3<0) ||
 				($5>255) || ($5<0) ||
 				($7>255) || ($7<0)) {
 				yyerror("invalid ipv4 address");
 				$$->u.addr32[0]=0;
 				/* $$=0; */
 			} else {
 				$$->u.addr[0]=$1;
 				$$->u.addr[1]=$3;
 				$$->u.addr[2]=$5;
 				$$->u.addr[3]=$7;
 				/*
 				$$=htonl( ($1<<24)|
 				($3<<16)| ($5<<8)|$7 );
 				*/
 			}
 		}
 	}
 	;
 ipv6addr:
 	IPV6ADDR {
 		$$=pkg_malloc(sizeof(struct ip_addr));
 		if ($$==0) {
 			LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
 		} else {
 			memset($$, 0, sizeof(struct ip_addr));
 			$$->af=AF_INET6;
 			$$->len=16;
 			if (inet_pton(AF_INET6, $1, $$->u.addr)<=0) {
 				yyerror("bad ipv6 address");
 			}
 		}
 	}
 	;
 ipv6:
 	ipv6addr { $$=$1; }
e5f4cdaf
 	| LBRACK ipv6addr RBRACK {$$=$2; }
 ;
93349b4e
 
 
 route_name:		NUMBER	{
 					tmp=int2str($1, &i_tmp);
 					if (($$=pkg_malloc(i_tmp+1))==0) {
 						yyerror("out of  memory");
 						YYABORT;
 					} else {
 						memcpy($$, tmp, i_tmp);
 						$$[i_tmp]=0;
 					}
c44685cb
 					routename = tmp;
93349b4e
 						}
c44685cb
 			|	ID		{ routename = $1; $$=$1; }
 			|	STRING	{ routename = $1; $$=$1; }
93349b4e
 ;
 
3bf9b2c6
 
11bcc806
 route_main:	ROUTE { routename=NULL; }
 		  | ROUTE_REQUEST { routename=NULL; }
3bf9b2c6
 ;
 
f141bc93
 route_stm:
3bf9b2c6
 	route_main LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
 		push($3, &main_rt.rlist[DEFAULT_RT]);
 	}
93349b4e
 	| ROUTE LBRACK route_name RBRACK LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
93349b4e
 		i_tmp=route_get(&main_rt, $3);
 		if (i_tmp==-1){
 			yyerror("internal error");
 			YYABORT;
 		}
 		if (main_rt.rlist[i_tmp]){
 			yyerror("duplicate route");
f141bc93
 			YYABORT;
 		}
93349b4e
 		push($6, &main_rt.rlist[i_tmp]);
f141bc93
 	}
 	| ROUTE error { yyerror("invalid  route  statement"); }
3bf9b2c6
 	| ROUTE_REQUEST error { yyerror("invalid  request_route  statement"); }
3c1a8ef8
 	;
f141bc93
 failure_route_stm:
85d4627f
 	ROUTE_FAILURE LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
 		push($3, &failure_rt.rlist[DEFAULT_RT]);
 	}
93349b4e
 	| ROUTE_FAILURE LBRACK route_name RBRACK LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
93349b4e
 		i_tmp=route_get(&failure_rt, $3);
 		if (i_tmp==-1){
 			yyerror("internal error");
 			YYABORT;
 		}
 		if (failure_rt.rlist[i_tmp]){
 			yyerror("duplicate route");
f141bc93
 			YYABORT;
 		}
93349b4e
 		push($6, &failure_rt.rlist[i_tmp]);
f141bc93
 	}
 	| ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
87405423
 	;
5e0e999a
 
1d2246f4
 
11bcc806
 route_reply_main:	ROUTE_ONREPLY { routename=NULL; }
 		  | ROUTE_REPLY { routename=NULL; }
1d2246f4
 ;
 
 
f141bc93
 onreply_route_stm:
1d2246f4
 	route_reply_main LBRACE {rt=CORE_ONREPLY_ROUTE;} actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
5e0e999a
 		push($4, &onreply_rt.rlist[DEFAULT_RT]);
6f722344
 	}
5e0e999a
 	| ROUTE_ONREPLY error { yyerror("invalid onreply_route statement"); }
1d2246f4
 	| ROUTE_REPLY error { yyerror("invalid onreply_route statement"); }
5e0e999a
 	| ROUTE_ONREPLY LBRACK route_name RBRACK 
 		{rt=(*$3=='0' && $3[1]==0)?CORE_ONREPLY_ROUTE:TM_ONREPLY_ROUTE;}
 		LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
5e0e999a
 		if (*$3=='0' && $3[1]==0){
 			/* onreply_route[0] {} is equivalent with onreply_route {}*/
 			push($7, &onreply_rt.rlist[DEFAULT_RT]);
 		}else{
 			i_tmp=route_get(&onreply_rt, $3);
 			if (i_tmp==-1){
 				yyerror("internal error");
 				YYABORT;
 			}
 			if (onreply_rt.rlist[i_tmp]){
 				yyerror("duplicate route");
 				YYABORT;
 			}
 			push($7, &onreply_rt.rlist[i_tmp]);
f141bc93
 		}
 	}
5e0e999a
 	| ROUTE_ONREPLY LBRACK route_name RBRACK error {
 		yyerror("invalid onreply_route statement");
 	}
caf80ae6
 	;
f141bc93
 branch_route_stm:
85d4627f
 	ROUTE_BRANCH LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
 		push($3, &branch_rt.rlist[DEFAULT_RT]);
 	}
93349b4e
 	| ROUTE_BRANCH LBRACK route_name RBRACK LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
93349b4e
 		i_tmp=route_get(&branch_rt, $3);
 		if (i_tmp==-1){
 			yyerror("internal error");
f141bc93
 			YYABORT;
 		}
93349b4e
 		if (branch_rt.rlist[i_tmp]){
 			yyerror("duplicate route");
 			YYABORT;
 		}
 		push($6, &branch_rt.rlist[i_tmp]);
f141bc93
 	}
 	| ROUTE_BRANCH error { yyerror("invalid branch_route statement"); }
7662b2e7
 	;
93349b4e
 send_route_stm: ROUTE_SEND LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
 		push($3, &onsend_rt.rlist[DEFAULT_RT]);
 	}
93349b4e
 	| ROUTE_SEND LBRACK route_name RBRACK LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
93349b4e
 		i_tmp=route_get(&onsend_rt, $3);
 		if (i_tmp==-1){
 			yyerror("internal error");
 			YYABORT;
 		}
 		if (onsend_rt.rlist[i_tmp]){
 			yyerror("duplicate route");
f141bc93
 			YYABORT;
 		}
93349b4e
 		push($6, &onsend_rt.rlist[i_tmp]);
f141bc93
 	}
 	| ROUTE_SEND error { yyerror("invalid onsend_route statement"); }
0d88ce78
 	;
31b5e3d0
 event_route_stm: ROUTE_EVENT LBRACK EVENT_RT_NAME RBRACK LBRACE actions RBRACE {
6f722344
 	#ifdef SHM_MEM
 		if (!shm_initialized() && init_shm()<0) {
 			yyerror("Can't initialize shared memory");
 			YYABORT;
 		}
 	#endif /* SHM_MEM */
31b5e3d0
 		i_tmp=route_get(&event_rt, $3);
 		if (i_tmp==-1){
 			yyerror("internal error");
 			YYABORT;
 		}
 		if (event_rt.rlist[i_tmp]){
 			yyerror("duplicate route");
 			YYABORT;
 		}
 		push($6, &event_rt.rlist[i_tmp]);
 	}
 
 	| ROUTE_EVENT error { yyerror("invalid event_route statement"); }
 	;
20cddb28
 preprocess_stm:
 	SUBST STRING { if(pp_subst_add($2)<0) YYERROR; }
 	| SUBST error { yyerror("invalid subst preprocess statement"); }
8198fd2b
 	| SUBSTDEF STRING { if(pp_substdef_add($2, 0)<0) YYERROR; }
78d26523
 	| SUBSTDEF error { yyerror("invalid substdef preprocess statement"); }
8198fd2b
 	| SUBSTDEFS STRING { if(pp_substdef_add($2, 1)<0) YYERROR; }
 	| SUBSTDEFS error { yyerror("invalid substdefs preprocess statement"); }
20cddb28
 	;
80ae84b9
 
8637f340
 /*exp:	rval_expr
80ae84b9
 		{
36d4ed7c
 			if ($1==0){
 				yyerror("invalid expression");
 				$$=0;
 			}else if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
80ae84b9
 				yyerror("invalid expression");
 				$$=0;
 			}else if (i_tmp!=RV_INT && i_tmp!=RV_NONE){
 				yyerror("invalid expression type, int expected\n");
 				$$=0;
 			}else
 				$$=mk_elem(NO_OP, RVEXP_O, $1, 0, 0);
f141bc93
 		}
 	;
8637f340
 */
80ae84b9
 
bf7485ba
 /* exp elem operators */
f141bc93
 equalop:
bf7485ba
 	EQUAL_T {$$=EQUAL_OP; }
 	| DIFF	{$$=DIFF_OP; }
298512a2
 	| STREQ	{$$=EQUAL_OP; }  /* for expr. elems equiv. to EQUAL_T*/
 	| STRDIFF {$$=DIFF_OP; } /* for expr. elems. equiv. to DIFF */
bf7485ba
 	;
 cmpop:
 	  GT	{$$=GT_OP; }
 	| LT	{$$=LT_OP; }
 	| GTE	{$$=GTE_OP; }
 	| LTE	{$$=LTE_OP; }
 	;
 strop:
 	equalop	{$$=$1; }
 	| MATCH	{$$=MATCH_OP; }
 	;
 
 
 /* rve expr. operators */
 rve_equalop:
80ae84b9
 	EQUAL_T {$$=RVE_EQ_OP; }
 	| DIFF	{$$=RVE_DIFF_OP; }
298512a2
 	| INTEQ	{$$=RVE_IEQ_OP; }
 	| INTDIFF {$$=RVE_IDIFF_OP; }
 	| STREQ	{$$=RVE_STREQ_OP; }
 	| STRDIFF {$$=RVE_STRDIFF_OP; }
bd5099b6
 	| MATCH	{$$=RVE_MATCH_OP; }
3c1a8ef8
 	;
bf7485ba
 rve_cmpop:
80ae84b9
 	  GT	{$$=RVE_GT_OP; }
 	| LT	{$$=RVE_LT_OP; }
 	| GTE	{$$=RVE_GTE_OP; }
 	| LTE	{$$=RVE_LTE_OP; }
f141bc93
 	;
bf7485ba
 
80ae84b9
 
 
 /* boolean expression uri operands */
f141bc93
 uri_type:
 	URI		{$$=URI_O;}
 	| FROM_URI	{$$=FROM_URI_O;}
 	| TO_URI	{$$=TO_URI_O;}
 	;
74ce7043
 
80ae84b9
 
 /* boolean expression integer operands, available only in the
   onsend route */
 eint_op_onsend:
 			SNDPORT		{ $$=SNDPORT_O; }
 		|	TOPORT		{ $$=TOPORT_O; }
 		|	SNDAF		{ $$=SNDAF_O; }
 		;
 
 /* boolean expression integer operands */
 eint_op:	SRCPORT		{ $$=SRCPORT_O; }
 		|	DSTPORT		{ $$=DSTPORT_O; }
 		|	AF			{ $$=AF_O; }
 		|	MSGLEN		{ $$=MSGLEN_O; }
 		| eint_op_onsend
 	;
 
 /* boolean expression ip/ipnet operands */
 eip_op_onsend:
 			SNDIP		{ onsend_check("snd_ip"); $$=SNDIP_O; }
 		|	TOIP		{ onsend_check("to_ip");  $$=TOIP_O; }
 		;
 
 eip_op:		SRCIP		{ $$=SRCIP_O; }
 		|	DSTIP		{ $$=DSTIP_O; }
 		| eip_op_onsend
 		;
 
 
 
f141bc93
 exp_elem:
835c266e
 	METHOD strop rval_expr %prec EQUAL_T
80ae84b9
 		{$$= mk_elem($2, METHOD_O, 0, RVE_ST, $3);}
835c266e
 	| METHOD strop ID %prec EQUAL_T
80ae84b9
 		{$$ = mk_elem($2, METHOD_O, 0, STRING_ST,$3); }
f141bc93
 	| METHOD strop error { $$=0; yyerror("string expected"); }
80ae84b9
 	| METHOD error	
 		{ $$=0; yyerror("invalid operator,== , !=, or =~ expected"); }
835c266e
 	| uri_type strop rval_expr %prec EQUAL_T
80ae84b9
 		{$$ = mk_elem($2, $1, 0, RVE_ST, $3); }
835c266e
 	| uri_type strop MYSELF %prec EQUAL_T
80ae84b9
 		{$$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
835c266e
 	| uri_type strop error %prec EQUAL_T
80ae84b9
 		{ $$=0; yyerror("string or MYSELF expected"); }
 	| uri_type error
 		{ $$=0; yyerror("invalid operator, == , != or =~ expected"); }
835c266e
 	| eint_op cmpop rval_expr %prec GT { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
 	| eint_op equalop rval_expr %prec EQUAL_T
80ae84b9
 		{ $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
 	| eint_op cmpop error   { $$=0; yyerror("number expected"); }
 	| eint_op equalop error { $$=0; yyerror("number expected"); }
 	| eint_op error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
8393efff
 	| PROTO equalop eqproto %prec EQUAL_T
d29c959a
 		{ $$=mk_elem($2, PROTO_O, 0, NUMBER_ST, (void*)$3 ); }
835c266e
 	| PROTO equalop rval_expr %prec EQUAL_T
d29c959a
 		{ $$=mk_elem($2, PROTO_O, 0, RVE_ST, $3 ); }
 	| PROTO equalop error
8393efff
 		{ $$=0; yyerror("protocol expected (udp, tcp, tls, sctp, ws, or wss)"); }
 	| SNDPROTO equalop eqproto %prec EQUAL_T
58e87237
 		{ $$=mk_elem($2, SNDPROTO_O, 0, NUMBER_ST, (void*)$3 ); }
835c266e
 	| SNDPROTO equalop rval_expr %prec EQUAL_T
58e87237
 		{ $$=mk_elem($2, SNDPROTO_O, 0, RVE_ST, $3 ); }
 	| SNDPROTO equalop error
8393efff
 		{ $$=0; yyerror("protocol expected (udp, tcp, tls, sctp, ws, or wss)"); }
835c266e
 	| eip_op strop ipnet %prec EQUAL_T { $$=mk_elem($2, $1, 0, NET_ST, $3); }
 	| eip_op strop rval_expr %prec EQUAL_T {
80ae84b9
 			s_tmp.s=0;
 			$$=0;
 			if (rve_is_constant($3)){
 				i_tmp=rve_guess_type($3);
 				if (i_tmp==RV_INT)
 					yyerror("string expected");
 				else if (i_tmp==RV_STR){
 					if (((rval_tmp=rval_expr_eval(0, 0, $3))==0) ||
 								(rval_get_str(0, 0, &s_tmp, rval_tmp, 0)<0)){
 						rval_destroy(rval_tmp);
 						yyerror("bad rvalue expression");
 					}else{
 						rval_destroy(rval_tmp);
 					}
 				}else{
 					yyerror("BUG: unexpected dynamic type");
 				}
 			}else{
bd55f84d
 					/* warn("non constant rvalue in ip comparison") */;
80ae84b9
 			}
 			if (s_tmp.s){
 				ip_tmp=str2ip(&s_tmp);
 				if (ip_tmp==0)
 					ip_tmp=str2ip6(&s_tmp);
 				pkg_free(s_tmp.s);
 				if (ip_tmp) {
 					$$=mk_elem($2, $1, 0, NET_ST, 
dc4cdb29
 								mk_new_net_bitlen(ip_tmp, ip_tmp->len*8) );
80ae84b9
 				} else {
 					$$=mk_elem($2, $1, 0, RVE_ST, $3);
 				}
 			}else{
 				$$=mk_elem($2, $1, 0, RVE_ST, $3);
 			}
f141bc93
 		}
835c266e
 	| eip_op strop host %prec EQUAL_T
80ae84b9
 		{ $$=mk_elem($2, $1, 0, STRING_ST, $3); }
835c266e
 	| eip_op strop MYSELF %prec EQUAL_T
80ae84b9
 		{ $$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
835c266e
 	| eip_op strop error %prec EQUAL_T
80ae84b9
 		{ $$=0; yyerror( "ip address or hostname expected" ); }
 	| eip_op error
 		{ $$=0; yyerror("invalid operator, ==, != or =~ expected");}
 	
835c266e
 	| MYSELF equalop uri_type %prec EQUAL_T
80ae84b9
 		{ $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
835c266e
 	| MYSELF equalop eip_op %prec EQUAL_T
80ae84b9
 		{ $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
835c266e
 	| MYSELF equalop error %prec EQUAL_T
80ae84b9
 		{ $$=0; yyerror(" URI, SRCIP or DSTIP expected"); }
f141bc93
 	| MYSELF error	{ $$=0; yyerror ("invalid operator, == or != expected"); }
80ae84b9
 	;
 
f141bc93
 ipnet:
dc4cdb29
 	ip SLASH ip	{ $$=mk_new_net($1, $3); }
f141bc93
 	| ip SLASH NUMBER {
 		if (($3<0) || ($3>$1->len*8)) {
 			yyerror("invalid bit number in netmask");
 			$$=0;
 		} else {
dc4cdb29
 			$$=mk_new_net_bitlen($1, $3);
f141bc93
 		/*
dc4cdb29
 			$$=mk_new_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
f141bc93
 		*/
 		}
 	}
dc4cdb29
 	| ip	{ $$=mk_new_net_bitlen($1, $1->len*8); }
f141bc93
 	| ip SLASH error { $$=0; yyerror("netmask (eg:255.0.0.0 or 8) expected"); }
 	;
3c1a8ef8
 
f141bc93
 host:
 	ID { $$=$1; }
80ae84b9
 	| host DOT ID {
4d601c6d
 		if ($1){
 			$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
 			if ($$==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
 							" failure while parsing host\n");
 			} else {
 				memcpy($$, $1, strlen($1));
 				$$[strlen($1)]='.';
 				memcpy($$+strlen($1)+1, $3, strlen($3));
 				$$[strlen($1)+1+strlen($3)]=0;
 			}
 			pkg_free($1);
80ae84b9
 		}
c5e8ac56
 		if ($3) pkg_free($3);
80ae84b9
 	}
 	| host MINUS ID {
06020e85
 		if ($1){
 			$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
 			if ($$==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
 							" failure while parsing host\n");
 			} else {
 				memcpy($$, $1, strlen($1));
4d601c6d
 				$$[strlen($1)]='-';
06020e85
 				memcpy($$+strlen($1)+1, $3, strlen($3));
 				$$[strlen($1)+1+strlen($3)]=0;
 			}
 			pkg_free($1);
f141bc93
 		}
c5e8ac56
 		if ($3) pkg_free($3);
f141bc93
 	}
e3dccdc9
 	| host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
4d601c6d
 	| host MINUS error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
3c1a8ef8
 	;
f9276a5b
 
 host_if_id: ID
 		| NUM_ID
c5e8ac56
 		| NUMBER {
 			/* get string version */
 			$$=pkg_malloc(strlen(yy_number_str)+1);
 			if ($$)
 				strcpy($$, yy_number_str);
 		}
f9276a5b
 		;
 
 host_or_if:
 	host_if_id { $$=$1; }
4d601c6d
 	| host_or_if DOT host_if_id {
f9276a5b
 		if ($1){
 			$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
 			if ($$==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
 							" failure while parsing host/interface name\n");
 			} else {
 				memcpy($$, $1, strlen($1));
4d601c6d
 				$$[strlen($1)]='.';
f9276a5b
 				memcpy($$+strlen($1)+1, $3, strlen($3));
 				$$[strlen($1)+1+strlen($3)]=0;
 			}
 			pkg_free($1);
 		}
c5e8ac56
 		if ($3) pkg_free($3);
f9276a5b
 	}
4d601c6d
 	| host_or_if MINUS host_if_id {
 		if ($1){
 			$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
 			if ($$==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
 							" failure while parsing host/interface name\n");
 			} else {
 				memcpy($$, $1, strlen($1));
 				$$[strlen($1)]='-';
 				memcpy($$+strlen($1)+1, $3, strlen($3));
 				$$[strlen($1)+1+strlen($3)]=0;
 			}
 			pkg_free($1);
 		}
c5e8ac56
 		if ($3) pkg_free($3);
4d601c6d
 	}
 	| host_or_if DOT error { $$=0; pkg_free($1);
 								yyerror("invalid host or interface name"); }
 	| host_or_if MINUS error { $$=0; pkg_free($1);
f9276a5b
 								yyerror("invalid host or interface name"); }
3c1a8ef8
 	;
f9276a5b
 
 
0d88ce78
 /* filtered cmd */
f141bc93
 fcmd:
 	cmd {
 		/* check if allowed */
9c1c9fa8
 		if ($1 && rt==ONSEND_ROUTE) {
f141bc93
 			switch($1->type) {
 				case DROP_T:
 				case LOG_T:
 				case SETFLAG_T:
 				case RESETFLAG_T:
 				case ISFLAGSET_T:
 				case IF_T:
cad98b04
 				case MODULE0_T:
 				case MODULE1_T:
 				case MODULE2_T:
 				case MODULE3_T:
 				case MODULE4_T:
 				case MODULE5_T:
 				case MODULE6_T:
 				case MODULEX_T:
8ed91651
 				case SET_FWD_NO_CONNECT_T:
 				case SET_RPL_NO_CONNECT_T:
 				case SET_FWD_CLOSE_T:
 				case SET_RPL_CLOSE_T:
0d88ce78
 					$$=$1;
f141bc93
 					break;
 				default:
 					$$=0;
 					yyerror("command not allowed in onsend_route\n");
0d88ce78
 			}
f141bc93
 		} else {
 			$$=$1;
 		}
 	}
0d88ce78
 	;
80ae84b9
 /*
f141bc93
 exp_stm:
 	fcmd	{ $$=$1; }
 	| if_cmd	{ $$=$1; }
 	| assign_action { $$ = $1; }
 	| LBRACE actions RBRACE	{ $$=$2; }
f20a56a2
 	;
80ae84b9
 */
f141bc93
 stm:
 	action	{ $$=$1; }
 	| LBRACE actions RBRACE	{ $$=$2; }
646aef6d
 	;
f141bc93
 actions:
 	actions action	{$$=append_action($1, $2); }
 	| action	{$$=$1;}
 	| actions error { $$=0; yyerror("bad command"); }
c07508e2
 	;
f141bc93
 action:
 	fcmd SEMICOLON {$$=$1;}
 	| if_cmd {$$=$1;}
a29a8b6d
 	| switch_cmd {$$=$1;}
d14a718f
 	| while_cmd { $$=$1; }
6c51c69f
 	| ret_cmd SEMICOLON { $$=$1; }
f141bc93
 	| assign_action SEMICOLON {$$=$1;}
 	| SEMICOLON /* null action */ {$$=0;}
 	| fcmd error { $$=0; yyerror("bad command: missing ';'?"); }
3c1a8ef8
 	;
f141bc93
 if_cmd:
8637f340
 	IF rval_expr stm	{
420a756d
 		if ($2 && rval_expr_int_check($2)>=0){
8637f340
 			warn_ct_rve($2, "if");
420a756d
 			$$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, NOSUBTYPE, 0);
eac773a6
 			set_cfg_pos($$);
420a756d
 		}else
 			YYERROR;
8637f340
 	}
 	| IF rval_expr stm ELSE stm	{ 
420a756d
 		if ($2 && rval_expr_int_check($2)>=0){
8637f340
 			warn_ct_rve($2, "if");
420a756d
 			$$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, ACTIONS_ST, $5);
eac773a6
 			set_cfg_pos($$);
420a756d
 		}else
 			YYERROR;
8637f340
 	}
f20a56a2
 	;
a29a8b6d
 
 ct_rval: rval_expr {
 			$$=0;
d2871c11
 			if ($1 && !rve_is_constant($1)){
a29a8b6d
 				yyerror("constant expected");
d2871c11
 				YYERROR;
8c09d09b
 			/*
d2871c11
 			} else if ($1 &&
 						!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
a29a8b6d
 				yyerror("invalid expression (bad type)");
d2871c11
 			}else if ($1 && i_tmp!=RV_INT){
a29a8b6d
 				yyerror("invalid expression type, int expected\n");
8c09d09b
 			*/
a29a8b6d
 			}else
 				$$=$1;
 		}
 ;
 single_case:
 	CASE ct_rval COLON actions {
 		$$=0;
d2871c11
 		if ($2==0) { yyerror ("bad case label"); YYERROR; }
8c09d09b
 		else if ((($$=mk_case_stm($2, 0, $4, &i_tmp))==0) && (i_tmp==-10)){
 				YYABORT;
 		}
 	}
 | CASE SLASH ct_rval COLON actions {
 		$$=0;
d2871c11
 		if ($3==0) { yyerror ("bad case label"); YYERROR; }
8c09d09b
 		else if ((($$=mk_case_stm($3, 1, $5, &i_tmp))==0) && (i_tmp==-10)){
a29a8b6d
 				YYABORT;
 		}
 	}
 	| CASE ct_rval COLON {
 		$$=0;
d2871c11
 		if ($2==0) { yyerror ("bad case label"); YYERROR; }
8c09d09b
 		else if ((($$=mk_case_stm($2, 0, 0, &i_tmp))==0) && (i_tmp==-10)){
 				YYABORT;
 		}
 	}
 	| CASE SLASH ct_rval COLON {
 		$$=0;
d2871c11
 		if ($3==0) { yyerror ("bad regex case label"); YYERROR; }
8c09d09b
 		else if ((($$=mk_case_stm($3, 1, 0, &i_tmp))==0) && (i_tmp==-10)){
a29a8b6d
 				YYABORT;
 		}
 	}
 	| DEFAULT COLON actions {
8c09d09b
 		if ((($$=mk_case_stm(0, 0, $3, &i_tmp))==0) && (i_tmp=-10)){
a29a8b6d
 				YYABORT;
 		}
 	}
 	| DEFAULT COLON {
8c09d09b
 		if ((($$=mk_case_stm(0, 0, 0, &i_tmp))==0) && (i_tmp==-10)){
a29a8b6d
 				YYABORT;
 		}
 	}
d2871c11
 	| CASE error COLON actions { $$=0; yyerror("bad case label"); }
 	| CASE SLASH error COLON actions { $$=0; yyerror("bad case regex label"); }
 	| CASE error COLON { $$=0; yyerror("bad case label"); }
 	| CASE SLASH error COLON { $$=0; yyerror("bad case regex label"); }
a29a8b6d
 	| CASE ct_rval COLON error { $$=0; yyerror ("bad case body"); }
 ;
 case_stms:
 	case_stms single_case {
 		$$=$1;
 		if ($2==0) yyerror ("bad case");
 		if ($$){
 			*($$->append)=$2;
 			if (*($$->append)!=0)
 				$$->append=&((*($$->append))->next);
 		}
 	}
 	| single_case {
 		$$=$1;
 		if ($1==0) yyerror ("bad case");
 		else $$->append=&($$->next);
 	}
 ;
 switch_cmd:
 	  SWITCH rval_expr LBRACE case_stms RBRACE { 
 		$$=0;
84d58357
 		if ($2==0){
 			yyerror("bad expression in switch(...)");
 			YYERROR;
 		}else if ($4==0){
 			yyerror ("bad switch body");
 			YYERROR;
 		}else if (case_check_default($4)!=0){
8c09d09b
 			yyerror_at(&$2->fpos, "bad switch(): too many "
 							"\"default:\" labels\n");
84d58357
 			YYERROR;
 		}else if (case_check_type($4)!=0){
8c09d09b
 			yyerror_at(&$2->fpos, "bad switch(): mixed integer and"
 							" string/RE cases not allowed\n");
84d58357
 			YYERROR;
 		}else{
a29a8b6d
 			$$=mk_action(SWITCH_T, 2, RVE_ST, $2, CASE_ST, $4);
 			if ($$==0) {
 				yyerror("internal error");
 				YYABORT;
 			}
eac773a6
 			set_cfg_pos($$);
a29a8b6d
 		}
 	}
 	| SWITCH rval_expr LBRACE RBRACE {
 		$$=0;
 		warn("empty switch()");
84d58357
 		if ($2==0){
 			yyerror("bad expression in switch(...)");
 			YYERROR;
 		}else{
a29a8b6d
 			/* it might have sideffects, so leave it for the optimizer */
 			$$=mk_action(SWITCH_T, 2, RVE_ST, $2, CASE_ST, 0);
 			if ($$==0) {
 				yyerror("internal error");
 				YYABORT;
 			}
eac773a6
 			set_cfg_pos($$);
a29a8b6d
 		}
 	}
 	| SWITCH error { $$=0; yyerror ("bad expression in switch(...)"); }
 	| SWITCH rval_expr LBRACE error RBRACE 
 		{$$=0; yyerror ("bad switch body"); }
 ;
 
d14a718f
 while_cmd:
 	WHILE rval_expr stm {
84d58357
 		if ($2 && rval_expr_int_check($2)>=0){
 			warn_ct_rve($2, "while");
 			$$=mk_action( WHILE_T, 2, RVE_ST, $2, ACTIONS_ST, $3);
eac773a6
 			set_cfg_pos($$);
84d58357
 		}else{
d14a718f
 			yyerror_at(&$2->fpos, "bad while(...) expression");
84d58357
 			YYERROR;
 		}
d14a718f
 	}
 ;
 
f141bc93
 /* class_id:
 	LBRACK ATTR_USER RBRACK { $$ = AVP_CLASS_USER; }
 	| LBRACK ATTR_DOMAIN RBRACK { $$ = AVP_CLASS_DOMAIN; }
 	| LBRACK ATTR_GLOBAL RBRACK { $$ = AVP_CLASS_GLOBAL; }
 	;
 */
 select_param:
 	ID {
 		if (sel.n >= MAX_SELECT_PARAMS-1) {
 			yyerror("Select identifier too long\n");
 		}
 		sel.params[sel.n].type = SEL_PARAM_STR;
 		sel.params[sel.n].v.s.s = $1;
 		sel.params[sel.n].v.s.len = strlen($1);
 		sel.n++;
3fb428ed
 	}
b269c881
 	| ID LBRACK intno RBRACK {
f141bc93
 		if (sel.n >= MAX_SELECT_PARAMS-2) {
 			yyerror("Select identifier too long\n");
 		}
 		sel.params[sel.n].type = SEL_PARAM_STR;
 		sel.params[sel.n].v.s.s = $1;
 		sel.params[sel.n].v.s.len = strlen($1);
 		sel.n++;
 		sel.params[sel.n].type = SEL_PARAM_INT;
 		sel.params[sel.n].v.i = $3;
 		sel.n++;
145e3fb3
 	}
47b20f0a
 	| ID LBRACK STRING RBRACK {
 		if (sel.n >= MAX_SELECT_PARAMS-2) {
 			yyerror("Select identifier too long\n");
 		}
 		sel.params[sel.n].type = SEL_PARAM_STR;
 		sel.params[sel.n].v.s.s = $1;
 		sel.params[sel.n].v.s.len = strlen($1);
 		sel.n++;
 		sel.params[sel.n].type = SEL_PARAM_STR;
 		sel.params[sel.n].v.s.s = $3;
 		sel.params[sel.n].v.s.len = strlen($3);
 		sel.n++;
 	}
f141bc93
 	;
 select_params:
 	select_params DOT select_param
 	| select_param
 	;
 select_id:
43f88e4f
 	SELECT_MARK { sel.n = 0; sel.f[0] = 0; } select_params {
f141bc93
 		sel_ptr = (select_t*)pkg_malloc(sizeof(select_t));
 		if (!sel_ptr) {
 			yyerror("No memory left to allocate select structure\n");
fb851d7e
 		}
f141bc93
 		memcpy(sel_ptr, &sel, sizeof(select_t));
 		$$ = sel_ptr;
 	}
 	;
 attr_class_spec:
fd6d4dc9
 	ATTR_FROM { s_attr->type |= AVP_TRACK_FROM; }
 	| ATTR_TO { s_attr->type |= AVP_TRACK_TO; }
e61ba5d2
         | ATTR_FROMURI { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_URI; }
         | ATTR_TOURI { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_URI; }
fd6d4dc9
 	| ATTR_FROMUSER { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_USER; }
f141bc93
 	| ATTR_TOUSER { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_USER; }
 	| ATTR_FROMDOMAIN { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_DOMAIN; }
 	| ATTR_TODOMAIN { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_DOMAIN; }
 	| ATTR_GLOBAL { s_attr->type |= AVP_TRACK_ALL | AVP_CLASS_GLOBAL; }
 	;
 attr_name_spec:
 	ID { s_attr->type |= AVP_NAME_STR; s_attr->name.s.s = $1; s_attr->name.s.len = strlen ($1); }
 	;
 attr_spec:
 	attr_name_spec
 	| attr_class_spec DOT attr_name_spec
 	;
 attr_mark:
 	ATTR_MARK {
 		s_attr = (struct avp_spec*)pkg_malloc(sizeof(struct avp_spec));
b269c881
 		if (!s_attr) { yyerror("No memory left"); YYABORT; }
 		else s_attr->type = 0;
f141bc93
 	}
 	;
 attr_id:
 	attr_mark attr_spec { $$ = s_attr; }
 	;
 attr_id_num_idx:
80ae84b9
 	attr_mark attr_spec LBRACK intno RBRACK {
f141bc93
 		s_attr->type|= (AVP_NAME_STR | ($4<0?AVP_INDEX_BACKWARD:AVP_INDEX_FORWARD));
 		s_attr->index = ($4<0?-$4:$4);
 		$$ = s_attr;
 	}
 	;
 attr_id_no_idx:
 	attr_mark attr_spec LBRACK RBRACK {
 		s_attr->type|= AVP_INDEX_ALL;
 		$$ = s_attr;
 	}
 	;
 attr_id_ass:
 	attr_id
 	| attr_id_no_idx
 	;
80ae84b9
 /*
f141bc93
 attr_id_val:
 	attr_id
 	| attr_id_num_idx
 	;
80ae84b9
 */
f141bc93
 attr_id_any:
 	attr_id
 	| attr_id_no_idx
 	| attr_id_num_idx
145e3fb3
 ;
85d4627f
 attr_id_any_str:
 	attr_id
b269c881
 	| avp_pvar {
 		if ($1->type==LV_AVP){
 			s_attr = pkg_malloc(sizeof(struct avp_spec));
 			if (!s_attr) { yyerror("No memory left"); YYABORT; }
 			else{
 				*s_attr=$1->lv.avps;
 			}
b1336a67
 			$$=s_attr;
b269c881
 		}else
 			$$=0; /* not an avp, a pvar */
 		pkg_free($1);
 	}
85d4627f
 	| STRING {
 		avp_spec_t *avp_spec;
 		str s;
 		int type, idx;
 		avp_spec = pkg_malloc(sizeof(*avp_spec));
 		if (!avp_spec) {
 			yyerror("Not enough memory");
 			YYABORT;
 		}
f7f58ba0
 		s.s = $1;
 		if (s.s[0] == '$')
 			s.s++;
85d4627f
 		s.len = strlen(s.s);
 		if (parse_avp_name(&s, &type, &avp_spec->name, &idx)) {
 			yyerror("error when parsing AVP");
26a886bc
 			pkg_free(avp_spec);
85d4627f
 			YYABORT;
 		}
 		avp_spec->type = type;
 		avp_spec->index = idx;
 		$$ = avp_spec;
 	}
 	;
26a886bc
 
 pvar:	PVAR {
cddb9399
 			s_tmp.s=$1; s_tmp.len=strlen($1);
6fba3230
 			pv_spec=pv_cache_get(&s_tmp);
 			if (!pv_spec) {
 				yyerror("Can't get from cache: %s", $1);
26a886bc
 				YYABORT;
 			}
 			$$=pv_spec;
 		}
 	;
 
 avp_pvar:	AVP_OR_PVAR {
cddb9399
 				lval_tmp=pkg_malloc(sizeof(*lval_tmp));
 				if (!lval_tmp) {
 					yyerror("Not enough memory");
26a886bc
 					YYABORT;
 				}
cddb9399
 				memset(lval_tmp, 0, sizeof(*lval_tmp));
 				s_tmp.s=$1; s_tmp.len=strlen(s_tmp.s);
6fba3230
 				lval_tmp->lv.pvs = pv_cache_get(&s_tmp);
 				if (lval_tmp->lv.pvs==NULL){
cddb9399
 					lval_tmp->lv.avps.type|= AVP_NAME_STR;
 					lval_tmp->lv.avps.name.s.s = s_tmp.s+1;
 					lval_tmp->lv.avps.name.s.len = s_tmp.len-1;
 					lval_tmp->type=LV_AVP;
 				}else{
 					lval_tmp->type=LV_PVAR;
 				}
 				$$ = lval_tmp;
96e0b967
 				DBG("parsed ambiguous avp/pvar \"%.*s\" to %d\n",
cddb9399
 							s_tmp.len, s_tmp.s, lval_tmp->type);
26a886bc
 			}
 	;
 
 
f141bc93
 /*
 assign_op:
 	ADDEQ { $$ = ADD_T; }
 	| EQUAL { $$ = ASSIGN_T; }
 	;
 */
 assign_op:
 	EQUAL { $$ = ASSIGN_T; }
 	;
cddb9399
 
 
 lval: attr_id_ass {
 					lval_tmp=pkg_malloc(sizeof(*lval_tmp));
 					if (!lval_tmp) {
 						yyerror("Not enough memory");
 						YYABORT;
 					}
 					lval_tmp->type=LV_AVP; lval_tmp->lv.avps=*$1;
 					pkg_free($1); /* free the avp spec we just copied */
 					$$=lval_tmp;
 				}
 	| pvar        {
 					if (!pv_is_w($1))
 						yyerror("read only pvar in assignment left side");
 					if ($1->trans!=0)
 						yyerror("pvar with transformations in assignment"
 								" left side");
 					lval_tmp=pkg_malloc(sizeof(*lval_tmp));
 					if (!lval_tmp) {
 						yyerror("Not enough memory");
 						YYABORT;
 					}
6fba3230
 					lval_tmp->type=LV_PVAR; lval_tmp->lv.pvs=$1;
cddb9399
 					$$=lval_tmp;
 				}
 	| avp_pvar    {
 					if (($1)->type==LV_PVAR){
6fba3230
 						if (!pv_is_w($1->lv.pvs))
cddb9399
 							yyerror("read only pvar in assignment left side");
6fba3230
 						if ($1->lv.pvs->trans!=0)
cddb9399
 							yyerror("pvar with transformations in assignment"
 									" left side");
 					}
 					$$=$1;
 				}
 	;
 
8a0c71c9
 rval: intno			{$$=mk_rve_rval(RV_INT, (void*)$1); }
cddb9399
 	| STRING			{	s_tmp.s=$1; s_tmp.len=strlen($1);
8a0c71c9
 							$$=mk_rve_rval(RV_STR, &s_tmp); }
 	| attr_id_any		{$$=mk_rve_rval(RV_AVP, $1); pkg_free($1); }
d5c4dda7
 	| pvar				{$$=mk_rve_rval(RV_PVAR, $1); }
cddb9399
 	| avp_pvar			{
 							switch($1->type){
 								case LV_AVP:
8a0c71c9
 									$$=mk_rve_rval(RV_AVP, &$1->lv.avps);
cddb9399
 									break;
 								case LV_PVAR:
6fba3230
 									$$=mk_rve_rval(RV_PVAR, $1->lv.pvs);
cddb9399
 									break;
 								default:
 									yyerror("BUG: invalid lvalue type ");
 									YYABORT;
 							}
 							pkg_free($1); /* not needed anymore */
 						}
8a0c71c9
 	| select_id			{$$=mk_rve_rval(RV_SEL, $1); pkg_free($1); }
 	| fcmd				{$$=mk_rve_rval(RV_ACTION_ST, $1); }
 	| exp_elem { $$=mk_rve_rval(RV_BEXPR, $1); }
 	| LBRACE actions RBRACE	{$$=mk_rve_rval(RV_ACTION_ST, $2); }
36d4ed7c
 	| LBRACE error RBRACE	{ $$=0; yyerror("bad command block"); }
8a0c71c9
 	| LPAREN assign_action RPAREN	{$$=mk_rve_rval(RV_ACTION_ST, $2); }
36d4ed7c
 	| LPAREN error RPAREN	{ $$=0; yyerror("bad expression"); }
cddb9399
 	;
 
 
80ae84b9
 rve_un_op: NOT	{ $$=RVE_LNOT_OP; }
508ad1c0
 		|  BIN_NOT 	{ $$=RVE_BNOT_OP; }
dee21fff
 		|  MINUS %prec UNARY	{ $$=RVE_UMINUS_OP; }
cddb9399
 		/* TODO: RVE_BOOL_OP, RVE_NOT_OP? */
 	;
 
80ae84b9
 /*
cddb9399
 rve_op:		PLUS		{ $$=RVE_PLUS_OP; }
 		|	MINUS		{ $$=RVE_MINUS_OP; }
 		|	STAR		{ $$=RVE_MUL_OP; }
80ae84b9
 		|	SLASH		{ $$=RVE_DIV_OP; }
333a3335
 		|	MODULO		{ $$=RVE_MOD_OP; }
cddb9399
 	;
80ae84b9
 */
 
 rval_expr: rval						{ $$=$1;
420a756d
 										if ($$==0){
b269c881
 											/*yyerror("out of memory\n");*/
 											YYERROR;
420a756d
 										}
80ae84b9
 									}
835c266e
 		| rve_un_op rval_expr %prec UNARY	{$$=mk_rve1($1, $2); }
e41bc057
 		| INTCAST rval_expr				{$$=mk_rve1(RVE_INT_OP, $2); }
 		| STRCAST rval_expr				{$$=mk_rve1(RVE_STR_OP, $2); }
8a0c71c9
 		| rval_expr PLUS rval_expr		{$$=mk_rve2(RVE_PLUS_OP, $1, $3); }
 		| rval_expr MINUS rval_expr		{$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
 		| rval_expr STAR rval_expr		{$$=mk_rve2(RVE_MUL_OP, $1, $3); }
 		| rval_expr SLASH rval_expr		{$$=mk_rve2(RVE_DIV_OP, $1, $3); }
333a3335
 		| rval_expr MODULO rval_expr	{$$=mk_rve2(RVE_MOD_OP, $1, $3); }
8a0c71c9
 		| rval_expr BIN_OR rval_expr	{$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
 		| rval_expr BIN_AND rval_expr	{$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
508ad1c0
 		| rval_expr BIN_XOR rval_expr	{$$=mk_rve2(RVE_BXOR_OP, $1,  $3);}
 		| rval_expr BIN_LSHIFT rval_expr {$$=mk_rve2(RVE_BLSHIFT_OP, $1,  $3);}
 		| rval_expr BIN_RSHIFT rval_expr {$$=mk_rve2(RVE_BRSHIFT_OP, $1,  $3);}
835c266e
 		| rval_expr rve_cmpop rval_expr %prec GT { $$=mk_rve2( $2, $1, $3);}
3856e9e8
 		| rval_expr rve_equalop rval_expr %prec EQUAL_T {
 			/* comparing with $null => treat as defined or !defined */
 			if($3->op==RVE_RVAL_OP && $3->left.rval.type==RV_PVAR
 					&& $3->left.rval.v.pvs.type==PVT_NULL) {
 				if($2==RVE_DIFF_OP || $2==RVE_IDIFF_OP
 						|| $2==RVE_STRDIFF_OP) {
 					DBG("comparison with $null switched to notdefined operator\n");
 					$$=mk_rve1(RVE_DEFINED_OP, $1);
 				} else {
 					DBG("comparison with $null switched to defined operator\n");
 					$$=mk_rve1(RVE_NOTDEFINED_OP, $1);
 				}
 				/* free rve struct for $null */
 				rve_destroy($3);
 			} else {
 				$$=mk_rve2($2, $1, $3);
 			}
 		}
8a0c71c9
 		| rval_expr LOG_AND rval_expr	{ $$=mk_rve2(RVE_LAND_OP, $1, $3);}
 		| rval_expr LOG_OR rval_expr	{ $$=mk_rve2(RVE_LOR_OP, $1, $3);}
9a31872c
 		| LPAREN rval_expr RPAREN		{ $$=$2;}
d4799027
 		| STRLEN LPAREN rval_expr RPAREN { $$=mk_rve1(RVE_STRLEN_OP, $3);}
 		| STREMPTY LPAREN rval_expr RPAREN {$$=mk_rve1(RVE_STREMPTY_OP, $3);}
 		| DEFINED rval_expr				{ $$=mk_rve1(RVE_DEFINED_OP, $2);}
835c266e
 		| rve_un_op error %prec UNARY 		{ $$=0; yyerror("bad expression"); }
e41bc057
 		| INTCAST error					{ $$=0; yyerror("bad expression"); }
 		| STRCAST error					{ $$=0; yyerror("bad expression"); }
420a756d
 		| rval_expr PLUS error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr MINUS error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr STAR error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr SLASH error			{ $$=0; yyerror("bad expression"); }
333a3335
 		| rval_expr MODULO error			{ $$=0; yyerror("bad expression"); }
420a756d
 		| rval_expr BIN_OR error		{ $$=0; yyerror("bad expression"); }
 		| rval_expr BIN_AND error		{ $$=0; yyerror("bad expression"); }
835c266e
 		| rval_expr rve_cmpop error %prec GT
420a756d
 			{ $$=0; yyerror("bad expression"); }
835c266e
 		| rval_expr rve_equalop error %prec EQUAL_T
420a756d
 			{ $$=0; yyerror("bad expression"); }
 		| rval_expr LOG_AND error		{ $$=0; yyerror("bad expression"); }
 		| rval_expr LOG_OR error		{ $$=0; yyerror("bad expression"); }
36d4ed7c
 		| STRLEN LPAREN error RPAREN	{ $$=0; yyerror("bad expression"); }
 		| STREMPTY LPAREN error RPAREN	{ $$=0; yyerror("bad expression"); }
 		| DEFINED error					{ $$=0; yyerror("bad expression"); }
80ae84b9
 		;
 
 assign_action: lval assign_op  rval_expr	{ $$=mk_action($2, 2, LVAL_ST, $1, 
cddb9399
 														 	  RVE_ST, $3);
eac773a6
 											set_cfg_pos($$);
cddb9399
 										}
 	;
 
 /*
f141bc93
 assign_action:
 	attr_id_ass assign_op STRING  { $$=mk_action($2, 2, AVP_ST, $1, STRING_ST, $3); }
 	| attr_id_ass assign_op NUMBER  { $$=mk_action($2, 2, AVP_ST, $1, NUMBER_ST, (void*)$3); }
 	| attr_id_ass assign_op fcmd    { $$=mk_action($2, 2, AVP_ST, $1, ACTION_ST, $3); }
 	| attr_id_ass assign_op attr_id_any { $$=mk_action($2, 2, AVP_ST, $1, AVP_ST, $3); }
 	| attr_id_ass assign_op select_id { $$=mk_action($2, 2, AVP_ST, (void*)$1, SELECT_ST, (void*)$3); }
 	| attr_id_ass assign_op LPAREN exp RPAREN { $$ = mk_action($2, 2, AVP_ST, $1, EXPR_ST, $4); }
 	;
cddb9399
 */
26a886bc
 
85d4627f
 avpflag_oper:
 	SETAVPFLAG { $$ = 1; }
 	| RESETAVPFLAG { $$ = 0; }
 	| ISAVPFLAGSET { $$ = -1; }
 	;
f141bc93
 cmd:
0267d20a
 	FORWARD LPAREN RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
d31b697f
 	| FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
eac773a6
 	| FORWARD LPAREN STRING RPAREN	{ $$=mk_action(	FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD LPAREN ip RPAREN	{ $$=mk_action(	FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD LPAREN URIHOST COMMA URIPORT RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
 	| FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$); }
f141bc93
 	| FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward argument"); }
eac773a6
 	| FORWARD_UDP LPAREN host RPAREN	{ $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN STRING RPAREN	{ $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN ip RPAREN	{ $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_UDP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$); }
f141bc93
 	| FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp argument"); }
eac773a6
 	| FORWARD_TCP LPAREN host RPAREN	{ $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN STRING RPAREN	{ $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN ip RPAREN	{ $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
 	| FORWARD_TCP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$); }
f141bc93
 	| FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp argument"); }
 	| FORWARD_TLS LPAREN host RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN STRING RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN ip RPAREN	{
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN host COMMA NUMBER RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN STRING COMMA NUMBER RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN ip COMMA NUMBER RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 					}
 	| FORWARD_TLS LPAREN URIHOST COMMA URIPORT RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN URIHOST COMMA NUMBER RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS LPAREN URIHOST RPAREN {
 		#ifdef USE_TLS
eac773a6
 			$$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$);
f141bc93
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
 	}
 	| FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
ed990c31
 	| FORWARD_TLS LPAREN error RPAREN { $$=0; 
 									yyerror("bad forward_tls argument"); }
 	| FORWARD_SCTP LPAREN host RPAREN {
e549d96b
 		#ifdef USE_SCTP
eac773a6
 			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN STRING RPAREN {
e549d96b
 		#ifdef USE_SCTP
eac773a6
 			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN ip RPAREN	{
e549d96b
 		#ifdef USE_SCTP
eac773a6
 			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN host COMMA NUMBER RPAREN {
e549d96b
 		#ifdef USE_SCTP
ed990c31
 			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
eac773a6
 							(void*)$5); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN STRING COMMA NUMBER RPAREN {
e549d96b
 		#ifdef USE_SCTP
ed990c31
 			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
eac773a6
 							(void*)$5); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
e549d96b
 		#ifdef USE_SCTP
ed990c31
 			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 
eac773a6
 							(void*)$5); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 					}
 	| FORWARD_SCTP LPAREN URIHOST COMMA URIPORT RPAREN {
e549d96b
 		#ifdef USE_SCTP
eac773a6
 			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN URIHOST COMMA NUMBER RPAREN {
e549d96b
 		#ifdef USE_SCTP
ed990c31
 			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST,
eac773a6
 							(void*)$5); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("sctp support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP LPAREN URIHOST RPAREN {
e549d96b
 		#ifdef USE_SCTP
eac773a6
 			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$);
e549d96b
 		#else
 			$$=0;
 			yyerror("tls support not compiled in");
 		#endif
ed990c31
 	}
 	| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| FORWARD_SCTP LPAREN error RPAREN { $$=0; 
e549d96b
 									yyerror("bad forward_sctp argument"); }
43181b6b
 	| LOG_TOK LPAREN STRING RPAREN	{$$=mk_action(LOG_T, 2, NUMBER_ST,
eac773a6
 										(void*)(L_DBG+1), STRING_ST, $3);
 									set_cfg_pos($$); }
 	| LOG_TOK LPAREN NUMBER COMMA STRING RPAREN	{$$=mk_action(LOG_T, 2, NUMBER_ST, (void*)$3, STRING_ST, $5); set_cfg_pos($$); }
f141bc93
 	| LOG_TOK error 		{ $$=0; yyerror("missing '(' or ')' ?"); }
 	| LOG_TOK LPAREN error RPAREN	{ $$=0; yyerror("bad log argument"); }
65938e0e
 	| SETFLAG LPAREN NUMBER RPAREN	{
 							if (check_flag($3)==-1)
 								yyerror("bad flag value");
 							$$=mk_action(SETFLAG_T, 1, NUMBER_ST,
 													(void*)$3);
eac773a6
 							set_cfg_pos($$);
65938e0e
 									}
 	| SETFLAG LPAREN flag_name RPAREN	{
 							i_tmp=get_flag_no($3, strlen($3));
 							if (i_tmp<0) yyerror("flag not declared");
 							$$=mk_action(SETFLAG_T, 1, NUMBER_ST,
85d4627f
 										(void*)(long)i_tmp);
eac773a6
 							set_cfg_pos($$);
65938e0e
 									}
f141bc93
 	| SETFLAG error			{ $$=0; yyerror("missing '(' or ')'?"); }
65938e0e
 	| RESETFLAG LPAREN NUMBER RPAREN {
 							if (check_flag($3)==-1)
 								yyerror("bad flag value");
 							$$=mk_action(RESETFLAG_T, 1, NUMBER_ST, (void*)$3);
eac773a6
 							set_cfg_pos($$);
65938e0e
 									}
 	| RESETFLAG LPAREN flag_name RPAREN	{
 							i_tmp=get_flag_no($3, strlen($3));
 							if (i_tmp<0) yyerror("flag not declared");
 							$$=mk_action(RESETFLAG_T, 1, NUMBER_ST,
85d4627f
 										(void*)(long)i_tmp);
eac773a6
 							set_cfg_pos($$);
65938e0e
 									}
f141bc93
 	| RESETFLAG error		{ $$=0; yyerror("missing '(' or ')'?"); }
65938e0e
 	| ISFLAGSET LPAREN NUMBER RPAREN {
 							if (check_flag($3)==-1)
 								yyerror("bad flag value");
 							$$=mk_action(ISFLAGSET_T, 1, NUMBER_ST, (void*)$3);
eac773a6
 							set_cfg_pos($$);
65938e0e
 									}
 	| ISFLAGSET LPAREN flag_name RPAREN	{
 							i_tmp=get_flag_no($3, strlen($3));
 							if (i_tmp<0) yyerror("flag not declared");
 							$$=mk_action(ISFLAGSET_T, 1, NUMBER_ST,
85d4627f
 										(void*)(long)i_tmp);
eac773a6
 							set_cfg_pos($$);
65938e0e
 									}
f141bc93
 	| ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
85d4627f
 	| avpflag_oper LPAREN attr_id_any_str COMMA flag_name RPAREN {
 		i_tmp=get_avpflag_no($5);
 		if (i_tmp==0) yyerror("avpflag not declared");
 		$$=mk_action(AVPFLAG_OPER_T, 3, AVP_ST, $3, NUMBER_ST, (void*)(long)i_tmp, NUMBER_ST, (void*)$1);
eac773a6
 		set_cfg_pos($$);
85d4627f
 	}
b269c881
 	| avpflag_oper LPAREN attr_id_any_str COMMA error RPAREN {
 		$$=0; yyerror("error parsing flag name");
 	}
 	| avpflag_oper LPAREN error COMMA flag_name RPAREN {
 		$$=0; yyerror("error parsing first parameter (avp or string)");
 	}
 	| avpflag_oper LPAREN error RPAREN { $$=0; yyerror("bad parameters"); }
85d4627f
 	| avpflag_oper error { $$=0; yyerror("missing '(' or ')'?"); }
eac773a6
 	| ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T, 2, STRING_ST, $3, STRING_ST, $5);
 			set_cfg_pos($$);
 	}
f141bc93
 	| ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| ERROR LPAREN error RPAREN { $$=0; yyerror("bad error argument"); }
d75db62d
 	| ROUTE LPAREN rval_expr RPAREN	{
 		if ($3) {
 			$$ = mk_action(ROUTE_T, 1, RVE_ST, (void*)$3);
 			set_cfg_pos($$);
 		} else {
 			$$ = 0;
 			YYERROR;
 		}
 	}
 	| ROUTE LPAREN ID RPAREN	{
0a3ab1b2
 		if ($3) {
 			$$ = mk_action(ROUTE_T, 1, STRING_ST, (void*)$3);
 			set_cfg_pos($$);
 		} else {
 			$$ = 0;
 			YYERROR;
 		}
 	}
f141bc93
 	| ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route argument"); }
eac773a6
 	| EXEC LPAREN STRING RPAREN	{ $$=mk_action(EXEC_T, 1, STRING_ST, $3); set_cfg_pos($$); }
 	| SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, 1, STRING_ST, $3); set_cfg_pos($$); }
f141bc93
 	| SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| PREFIX LPAREN STRING RPAREN { $$=mk_action(PREFIX_T, 1, STRING_ST,  $3); set_cfg_pos($$); }
f141bc93
 	| PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| STRIP_TAIL LPAREN NUMBER RPAREN { $$=mk_action(STRIP_TAIL_T, 1, NUMBER_ST, (void*)$3); set_cfg_pos($$); }
f141bc93
 	| STRIP_TAIL error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| STRIP_TAIL LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
eac773a6
 	| STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, 1, NUMBER_ST, (void*) $3); set_cfg_pos($$); }
f141bc93
 	| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
eac773a6
 	| SET_USERPHONE LPAREN RPAREN { $$=mk_action(SET_USERPHONE_T, 0); set_cfg_pos($$); }
536065b8
 	| SET_USERPHONE error { $$=0; yyerror("missing '(' or ')' ?"); }
5b258eb6
 	| REMOVE_BRANCH LPAREN intno RPAREN {
9fa304f1
 			$$=mk_action(REMOVE_BRANCH_T, 1, NUMBER_ST, (void*)$3);
 			set_cfg_pos($$);
 	}
 	| REMOVE_BRANCH LPAREN RPAREN {
 			$$=mk_action(REMOVE_BRANCH_T, 0);
 			set_cfg_pos($$);
 	}
 	| REMOVE_BRANCH error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| REMOVE_BRANCH LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
 	| CLEAR_BRANCHES LPAREN RPAREN { $$=mk_action(CLEAR_BRANCHES_T, 0); set_cfg_pos($$); }
eac773a6
 	| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORT_T, 1, STRING_ST, $3); set_cfg_pos($$); }
f141bc93
 	| SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| SET_HOSTPORTTRANS LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORTTRANS_T, 1, STRING_ST, $3); set_cfg_pos($$); }
6973e34c
 	| SET_HOSTPORTTRANS error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_HOSTPORTTRANS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| SET_PORT LPAREN STRING RPAREN { $$=mk_action(SET_PORT_T, 1, STRING_ST, $3); set_cfg_pos($$); }
f141bc93
 	| SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| SET_USER LPAREN STRING RPAREN { $$=mk_action(SET_USER_T, 1, STRING_ST, $3); set_cfg_pos($$); }
f141bc93
 	| SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| SET_USERPASS LPAREN STRING RPAREN { $$=mk_action(SET_USERPASS_T, 1, STRING_ST, $3); set_cfg_pos($$); }
f141bc93
 	| SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| SET_URI LPAREN STRING RPAREN { $$=mk_action(SET_URI_T, 1, STRING_ST,$3); set_cfg_pos($$); }
f141bc93
 	| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
eac773a6
 	| REVERT_URI LPAREN RPAREN { $$=mk_action(REVERT_URI_T, 0); set_cfg_pos($$); }
 	| REVERT_URI { $$=mk_action(REVERT_URI_T, 0); set_cfg_pos($$); }
 	| FORCE_RPORT LPAREN RPAREN	{ $$=mk_action(FORCE_RPORT_T, 0); set_cfg_pos($$); }
 	| FORCE_RPORT	{$$=mk_action(FORCE_RPORT_T, 0); set_cfg_pos($$); }
 	| ADD_LOCAL_RPORT LPAREN RPAREN	{ $$=mk_action(ADD_LOCAL_RPORT_T, 0); set_cfg_pos($$); }
 	| ADD_LOCAL_RPORT	{$$=mk_action(ADD_LOCAL_RPORT_T, 0); set_cfg_pos($$); }
f141bc93
 	| FORCE_TCP_ALIAS LPAREN NUMBER RPAREN	{
 		#ifdef USE_TCP
 			$$=mk_action(FORCE_TCP_ALIAS_T, 1, NUMBER_ST, (void*)$3);
eac773a6
 			set_cfg_pos($$);
f141bc93
 		#else
 			yyerror("tcp support not compiled in");
 		#endif
 	}
 	| FORCE_TCP_ALIAS LPAREN RPAREN	{
 		#ifdef USE_TCP
 			$$=mk_action(FORCE_TCP_ALIAS_T, 0);
eac773a6
 			set_cfg_pos($$);
f141bc93
 		#else
 			yyerror("tcp support not compiled in");
 		#endif
 	}
 	| FORCE_TCP_ALIAS				{
 		#ifdef USE_TCP
 			$$=mk_action(FORCE_TCP_ALIAS_T, 0);
eac773a6
 			set_cfg_pos($$);
f141bc93
 		#else
 			yyerror("tcp support not compiled in");
 		#endif
 	}
 	| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; yyerror("bad argument, number expected"); }
f62c96d8
 	| UDP_MTU_TRY_PROTO LPAREN proto RPAREN
eac773a6
 		{ $$=mk_action(UDP_MTU_TRY_PROTO_T, 1, NUMBER_ST, $3); set_cfg_pos($$); }
f62c96d8
 	| UDP_MTU_TRY_PROTO LPAREN error RPAREN
 		{ $$=0; yyerror("bad argument, UDP, TCP, TLS or SCTP expected"); }
f141bc93
 	| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
 		$$=0;
 		if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
 			LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
 		} else {
 			str_tmp->s=$3;
06020e85
 			str_tmp->len=$3?strlen($3):0;
f141bc93
 			$$=mk_action(SET_ADV_ADDR_T, 1, STR_ST, str_tmp);
eac773a6
 			set_cfg_pos($$);
f141bc93
 		}
 	}
 	| SET_ADV_ADDRESS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
 	| SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); }
 	| SET_ADV_PORT LPAREN NUMBER RPAREN {
 		$$=0;
 		tmp=int2str($3, &i_tmp);
 		if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
 			LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
 		} else {
 			if ((str_tmp->s=pkg_malloc(i_tmp))==0) {
 				LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
 			} else {
 				memcpy(str_tmp->s, tmp, i_tmp);
 				str_tmp->len=i_tmp;
 				$$=mk_action(SET_ADV_PORT_T, 1, STR_ST, str_tmp);
eac773a6
 				set_cfg_pos($$);
0b4b7601
 			}
 		}
f141bc93
 	}
 	| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
 	| SET_ADV_PORT  error {$$=0; yyerror("missing '(' or ')' ?"); }
eb321e3f
 	| FORCE_SEND_SOCKET LPAREN phostport RPAREN { 
 		$$=mk_action(FORCE_SEND_SOCKET_T, 1, SOCKID_ST, $3);
eac773a6
 		set_cfg_pos($$);
eb321e3f
 	}
 	| FORCE_SEND_SOCKET LPAREN error RPAREN {
 		$$=0; yyerror("bad argument, [proto:]host[:port] expected");
 	}
f141bc93
 	| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
58cbf7f7
 	| SET_FWD_NO_CONNECT LPAREN RPAREN	{
 		$$=mk_action(SET_FWD_NO_CONNECT_T, 0); set_cfg_pos($$);
 	}
 	| SET_FWD_NO_CONNECT	{
 		$$=mk_action(SET_FWD_NO_CONNECT_T, 0); set_cfg_pos($$);
 	}
 	| SET_RPL_NO_CONNECT LPAREN RPAREN	{
 		$$=mk_action(SET_RPL_NO_CONNECT_T, 0); set_cfg_pos($$);
 	}
 	| SET_RPL_NO_CONNECT	{
 		$$=mk_action(SET_RPL_NO_CONNECT_T, 0); set_cfg_pos($$);
 	}
 	| SET_FWD_CLOSE LPAREN RPAREN	{
 		$$=mk_action(SET_FWD_CLOSE_T, 0); set_cfg_pos($$);
 	}
 	| SET_FWD_CLOSE	{
 		$$=mk_action(SET_FWD_CLOSE_T, 0); set_cfg_pos($$);
 	}
 	| SET_RPL_CLOSE LPAREN RPAREN	{
 		$$=mk_action(SET_RPL_CLOSE_T, 0); set_cfg_pos($$);
 	}
 	| SET_RPL_CLOSE	{
 		$$=mk_action(SET_RPL_CLOSE_T, 0); set_cfg_pos($$);
 	}
415f24a4
 	| CFG_SELECT LPAREN STRING COMMA NUMBER RPAREN {
 		$$=mk_action(CFG_SELECT_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
 	}
 	| CFG_SELECT LPAREN STRING COMMA rval_expr RPAREN {
 		$$=mk_action(CFG_SELECT_T, 2, STRING_ST, $3, RVE_ST, $5); set_cfg_pos($$);
 	}
 	| CFG_SELECT error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| CFG_SELECT LPAREN error RPAREN { $$=0; yyerror("bad arguments, string and number expected"); }
 	| CFG_RESET LPAREN STRING RPAREN {
 		$$=mk_action(CFG_RESET_T, 1, STRING_ST, $3); set_cfg_pos($$);
 	}
 	| CFG_RESET error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| CFG_RESET LPAREN error RPAREN { $$=0; yyerror("bad arguments, string expected"); }
cad98b04
 	| ID {mod_func_action = mk_action(MODULE0_T, 2, MODEXP_ST, NULL, NUMBER_ST,
a2da0c58
 			0); } LPAREN func_params RPAREN	{
cad98b04
 		mod_func_action->val[0].u.data =
2873d384
 			find_export_record($1, mod_func_action->val[1].u.number, rt,
 								&u_tmp);
f141bc93
 		if (mod_func_action->val[0].u.data == 0) {
2873d384
 			if (find_export_record($1, mod_func_action->val[1].u.number, 0,
 									&u_tmp) ) {
47a3fdbf
 					LOG(L_ERR, "misused command %s\n", $1);
f141bc93
 					yyerror("Command cannot be used in the block\n");
 			} else {
a313a8d3
 				LOG(L_ERR, "cfg. parser: failed to find command %s (params %ld)\n",
 						$1, mod_func_action->val[1].u.number);
f141bc93
 				yyerror("unknown command, missing loadmodule?\n");
 			}
cad98b04
 			free_mod_func_action(mod_func_action);
f141bc93
 			mod_func_action=0;
a2da0c58
 		}else{
cad98b04
 			if (mod_func_action && mod_f_params_pre_fixup(mod_func_action)<0) {
 				/* error messages are printed inside the function */
 				free_mod_func_action(mod_func_action);
 				mod_func_action = 0;
 				YYERROR;
a2da0c58
 			}
f141bc93
 		}
 		$$ = mod_func_action;
eac773a6
 		set_cfg_pos($$);
f141bc93
 	}
f65e66ce
 	| ID error					{ yyerror("'('')' expected (function call)");}
f141bc93
 	;
 func_params:
 	/* empty */
 	| func_params COMMA func_param { }
 	| func_param {}
 	;
 func_param:
cad98b04
 	rval_expr {
 		if ($1 && mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
a2da0c58
 			mod_func_action->val[mod_func_action->val[1].u.number+2].type =
cad98b04
 				RVE_ST;
 			mod_func_action->val[mod_func_action->val[1].u.number+2].u.data =
a2da0c58
 				$1;
f141bc93
 			mod_func_action->val[1].u.number++;
cad98b04
 		} else if ($1) {
f141bc93
 			yyerror("Too many arguments\n");
cad98b04
 			YYERROR;
f141bc93
 		} else {
cad98b04
 			YYERROR;
f141bc93
 		}
 	}
3c1a8ef8
 	;
6c51c69f
 
 ret_cmd:
 	DROP LPAREN RPAREN		{
8ebb586d
 		$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST,
eac773a6
 						(void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
6c51c69f
 	}
 	| DROP rval_expr	{
8ebb586d
 		$$=mk_action(DROP_T, 2, RVE_ST, $2, NUMBER_ST,
eac773a6
 						(void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
6c51c69f
 	}
 	| DROP				{
8ebb586d
 		$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, 
eac773a6
 						(void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
8ebb586d
 	}
 	| EXIT LPAREN RPAREN		{
9954a52e
 		$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
 						(void*)EXIT_R_F);
eac773a6
 		set_cfg_pos($$);
8ebb586d
 	}
 	| EXIT rval_expr	{
 		$$=mk_action(DROP_T, 2, RVE_ST, $2, NUMBER_ST, (void*)EXIT_R_F);
eac773a6
 		set_cfg_pos($$);
8ebb586d
 	}
 	| EXIT				{
9954a52e
 		$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
 						(void*)EXIT_R_F);
eac773a6
 		set_cfg_pos($$);
6c51c69f
 	}
 	| RETURN			{
 		$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
eac773a6
 						(void*)RETURN_R_F); set_cfg_pos($$);
6c51c69f
 	}
8ebb586d
 	| RETURN  LPAREN RPAREN		{
 		$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
eac773a6
 						(void*)RETURN_R_F); set_cfg_pos($$);
8ebb586d
 	}
6c51c69f
 	| RETURN rval_expr	{
 		$$=mk_action(DROP_T, 2, RVE_ST, $2, NUMBER_ST, (void*)RETURN_R_F);
eac773a6
 		set_cfg_pos($$);
6c51c69f
 	}
 	| BREAK				{
eac773a6
 		$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)BREAK_R_F);
 		set_cfg_pos($$);
6c51c69f
 	}
 	;
 
3c1a8ef8
 %%
 
9a31872c
 static void get_cpos(struct cfg_pos* pos)
 {
 	pos->s_line=startline;
 	pos->e_line=line;
 	pos->s_col=startcolumn;
 	pos->e_col=column-1;
d2056519
 	if(finame==0)
 		finame = (cfg_file!=0)?cfg_file:"default";
 	pos->fname=finame;
c44685cb
 	pos->rname=(routename!=0)?routename:default_routename;
9a31872c
 }
 
 
d14a718f
 static void warn_at(struct cfg_pos* p, char* format, ...)
8737eaf4
 {
d14a718f
 	va_list ap;
 	char s[256];
 	
 	va_start(ap, format);
 	vsnprintf(s, sizeof(s), format, ap);
 	va_end(ap);
 	if (p->e_line!=p->s_line)
d2056519
 		LOG(L_WARN, "warning in config file %s, from line %d, column %d to"
7f2853ad
 					" line %d, column %d: %s\n",
d2056519
 					p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
d14a718f
 	else if (p->s_col!=p->e_col)
d2056519
 		LOG(L_WARN, "warning in config file %s, line %d, column %d-%d: %s\n",
 					p->fname, p->s_line, p->s_col, p->e_col, s);
f65e66ce
 	else
d2056519
 		LOG(L_WARN, "warning in config file %s, line %d, column %d: %s\n",
 				p->fname, p->s_line, p->s_col, s);
dcb59e67
 	cfg_warnings++;
8737eaf4
 }
057f0454
 
d14a718f
 
 
9a31872c
 static void yyerror_at(struct cfg_pos* p, char* format, ...)
3c1a8ef8
 {
8a0c71c9
 	va_list ap;
 	char s[256];
 	
 	va_start(ap, format);
 	vsnprintf(s, sizeof(s), format, ap);
 	va_end(ap);
9a31872c
 	if (p->e_line!=p->s_line)
d2056519
 		LOG(L_CRIT, "parse error in config file %s, from line %d, column %d"
7f2853ad
 					" to line %d, column %d: %s\n",
d2056519
 					p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
9a31872c
 	else if (p->s_col!=p->e_col)
d2056519
 		LOG(L_CRIT,"parse error in config file %s, line %d, column %d-%d: %s\n",
 					p->fname, p->s_line, p->s_col, p->e_col, s);
f65e66ce
 	else
d2056519
 		LOG(L_CRIT, "parse error in config file %s, line %d, column %d: %s\n",
 					p->fname, p->s_line, p->s_col, s);
63fa628f
 	cfg_errors++;
3c1a8ef8
 }
 
e5f4cdaf
 
d14a718f
 
 static void warn(char* format, ...)
 {
 	va_list ap;
 	char s[256];
 	struct cfg_pos pos;
 	
 	get_cpos(&pos);
 	va_start(ap, format);
 	vsnprintf(s, sizeof(s), format, ap);
 	va_end(ap);
 	warn_at(&pos, s);
 }
 
 
 
9a31872c
 static void yyerror(char* format, ...)
 {
 	va_list ap;
 	char s[256];
 	struct cfg_pos pos;
 	
 	get_cpos(&pos);
 	va_start(ap, format);
 	vsnprintf(s, sizeof(s), format, ap);
 	va_end(ap);
 	yyerror_at(&pos, s);
 }
 
 
 
8a0c71c9
 /** mk_rval_expr_v wrapper.
  *  checks mk_rval_expr_v return value and sets the cfg. pos
  *  (line and column numbers)
  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr_v)
  */
 static struct rval_expr* mk_rve_rval(enum rval_type type, void* v)
 {
 	struct rval_expr* ret;
9a31872c
 	struct cfg_pos pos;
8a0c71c9
 
9a31872c
 	get_cpos(&pos);
 	ret=mk_rval_expr_v(type, v, &pos);
8a0c71c9
 	if (ret==0){
 		yyerror("internal error: failed to create rval expr");
 		/* YYABORT; */
 	}
 	return ret;
 }
 
 
 /** mk_rval_expr1 wrapper.
  *  checks mk_rval_expr1 return value (!=0 and type checking)
  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr1)
  */
 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1)
 {
 	struct rval_expr* ret;
 	struct rval_expr* bad_rve;
 	enum rval_type type, bad_t, exp_t;
 	
9a31872c
 	if (rve1==0)
 		return 0;
 	ret=mk_rval_expr1(op, rve1, &rve1->fpos);
8a0c71c9
 	if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
9a31872c
 		yyerror_at(&rve1->fpos, "bad expression: type mismatch"
 					" (%s instead of %s)", rval_type_name(bad_t),
 					rval_type_name(exp_t));
420a756d
 		rve_destroy(ret);
 		ret=0;
8a0c71c9
 	}
 	return ret;
 }
 
 
 /** mk_rval_expr2 wrapper.
  *  checks mk_rval_expr2 return value (!=0 and type checking)
  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr2)
  */
 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
 									struct rval_expr* rve2)
 {
 	struct rval_expr* ret;
 	struct rval_expr* bad_rve;
9a31872c
 	enum rval_type type, bad_t, exp_t;
 	struct cfg_pos pos;
8a0c71c9
 	
9a31872c
 	if ((rve1==0) || (rve2==0))
 		return 0;
36d4ed7c
 	bad_rve=0;
 	bad_t=0;
 	exp_t=0;
33d56025
 	cfg_pos_join(&pos, &rve1->fpos, &rve2->fpos);
9a31872c
 	ret=mk_rval_expr2(op, rve1, rve2, &pos);
8a0c71c9
 	if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
36d4ed7c
 		if (bad_rve)
 			yyerror_at(&pos, "bad expression: type mismatch:"
9a31872c
 						" %s instead of %s at (%d,%d)",
 						rval_type_name(bad_t), rval_type_name(exp_t),
 						bad_rve->fpos.s_line, bad_rve->fpos.s_col);
36d4ed7c
 		else
 			yyerror("BUG: unexpected null \"bad\" expression\n");
420a756d
 		rve_destroy(ret);
 		ret=0;
8a0c71c9
 	}
 	return ret;
 }
 
 
8637f340
 /** check if the expression is an int.
  * if the expression does not evaluate to an int return -1 and
  * log an error.
7f2853ad
  * @return 0 success, no warnings; 1 success but warnings; -1 on error */
8637f340
 static int rval_expr_int_check(struct rval_expr *rve)
 {
 	struct rval_expr* bad_rve;
 	enum rval_type type, bad_t, exp_t;
 	
 	if (rve==0){
 		yyerror("invalid expression");
 		return -1;
 	}else if (!rve_check_type(&type, rve, &bad_rve, &bad_t ,&exp_t)){
 		if (bad_rve)
 			yyerror_at(&rve->fpos, "bad expression: type mismatch:"
 						" %s instead of %s at (%d,%d)",
 						rval_type_name(bad_t), rval_type_name(exp_t),
 						bad_rve->fpos.s_line, bad_rve->fpos.s_col);
 		else
 			yyerror("BUG: unexpected null \"bad\" expression\n");
 		return -1;
 	}else if (type!=RV_INT && type!=RV_NONE){
7f2853ad
 		warn_at(&rve->fpos, "non-int expression (you might want to use"
 				" casts)\n");
 		return 1;
8637f340
 	}
 	return 0;
 }
 
 
 /** warn if the expression is constant.
  * @return 0 on success (no warning), 1 when warning */
 static int warn_ct_rve(struct rval_expr *rve, char* name)
 {
 	if (rve && rve_is_constant(rve)){
 		warn_at(&rve->fpos, "constant value in %s%s",
 				name?name:"expression", name?"(...)":"");
 		return 1;
 	}
 	return 0;
 }
 
 
eb321e3f
 static struct name_lst* mk_name_lst(char* host, int flags)
 {
 	struct name_lst* l;
06020e85
 	if (host==0) return 0;
eb321e3f
 	l=pkg_malloc(sizeof(struct name_lst));
 	if (l==0) {
 		LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
 	} else {
 		l->name=host;
 		l->flags=flags;
 		l->next=0;
 	}
 	return l;
 }
 
 
6cd48835
 static struct socket_id* mk_listen_id(char* host, int proto, int port)
e5f4cdaf
 {
6cd48835
 	struct socket_id* l;
06020e85
 	if (host==0) return 0;
6cd48835
 	l=pkg_malloc(sizeof(struct socket_id));
f141bc93
 	if (l==0) {
e5f4cdaf
 		LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
f141bc93
 	} else {
eb321e3f
 		l->addr_lst=mk_name_lst(host, 0);
 		if (l->addr_lst==0){
 			pkg_free(l);
 			return 0;
 		}
 		l->flags=0;
e5f4cdaf
 		l->port=port;
 		l->proto=proto;
 		l->next=0;
 	}
 	return l;
 }
 
 
eb321e3f
 static void free_name_lst(struct name_lst* lst)
 {
 	struct name_lst* tmp;
 	
 	while(lst){
 		tmp=lst;
 		lst=lst->next;
 		pkg_free(tmp);
 	}
 }
 
 
 static struct socket_id* mk_listen_id2(struct name_lst* addr_l, int proto,
 										int port)
 {
 	struct socket_id* l;
06020e85
 	if (addr_l==0) return 0;
eb321e3f
 	l=pkg_malloc(sizeof(struct socket_id));
 	if (l==0) {
 		LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
 	} else {
 		l->flags=addr_l->flags;
 		l->port=port;
 		l->proto=proto;
 		l->addr_lst=addr_l;
 		l->next=0;
 	}
 	return l;
 }
 
 
 static void free_socket_id(struct socket_id* i)
 {
 	free_name_lst(i->addr_lst);
 	pkg_free(i);
 }
 
 
 static void free_socket_id_lst(struct socket_id* lst)
 {
 	struct socket_id* tmp;
 	
 	while(lst){
 		tmp=lst;
 		lst=lst->next;
 		free_socket_id(tmp);
 	}
 }
 
a29a8b6d
 
8c09d09b
 /** create a temporary case statmenet structure.
  *  *err will be filled in case of error (return == 0):
  *   -1 - non constant expression
  *   -2 - expression error (bad type)
  *   -10 - memory allocation error
  */
 static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re,
 											struct action* a, int* err)
a29a8b6d
 {
 	struct case_stms* s;
8c09d09b
 	struct rval_expr* bad_rve;
 	enum rval_type type, bad_t, exp_t;
 	enum match_str_type t;
 	
 	t=MATCH_UNKNOWN;
 	if (ct){
 		/* if ct!=0 => case, else if ct==0 is a default */
 		if (!rve_is_constant(ct)){
 			yyerror_at(&ct->fpos, "non constant expression in case");
 			*err=-1;
 			return 0;
 		}
 		if (rve_check_type(&type, ct, &bad_rve, &bad_t, &exp_t)!=1){
 			yyerror_at(&ct->fpos, "bad expression: type mismatch:"
 							" %s instead of %s at (%d,%d)",
 							rval_type_name(bad_t), rval_type_name(exp_t),
 							bad_rve->fpos.s_line, bad_rve->fpos.s_col);
 			*err=-2;
 			return 0;
 		}
 		if (is_re)
 			t=MATCH_RE;
 		else if (type==RV_STR)
 			t=MATCH_STR;
 		else
 			t=MATCH_INT;
 	}
 
a29a8b6d
 	s=pkg_malloc(sizeof(*s));
 	if (s==0) {
8c09d09b
 		yyerror("internal error: memory allocation failure");
 		*err=-10;
a29a8b6d
 	} else {
 		memset(s, 0, sizeof(*s));
 		s->ct_rve=ct;
8c09d09b
 		s->type=t;
a29a8b6d
 		s->actions=a;
 		s->next=0;
 		s->append=0;
 	}
 	return s;
 }
 
8c09d09b
 
 /*
  * @return 0 on success, -1 on error.
  */
 static int case_check_type(struct case_stms* stms)
 {
 	struct case_stms* c;
 	struct case_stms* s;
 	
 	for(c=stms; c ; c=c->next){
 		if (!c->ct_rve) continue;
 		for (s=c->next; s; s=s->next){
 			if (!s->ct_rve) continue;
 			if ((s->type!=c->type) &&
 				!(	(c->type==MATCH_STR || c->type==MATCH_RE) &&
 					(s->type==MATCH_STR || s->type==MATCH_RE) ) ){
 					yyerror_at(&s->ct_rve->fpos, "type mismatch in case");
 					return -1;
 			}
 		}
 	}
 	return 0;
 }
 
 
 /*
  * @return 0 on success, -1 on error.
  */
 static int case_check_default(struct case_stms* stms)
 {
 	struct case_stms* c;
 	int default_no;
 	
 	default_no=0;
 	for(c=stms; c ; c=c->next)
 		if (c->ct_rve==0) default_no++;
 	return (default_no<=1)?0:-1;
 }
 
 
 
cad98b04
 /** fixes the parameters and the type of a module function call.
  * It is done here instead of fix action, to have quicker feedback
  * on error cases (e.g. passing a non constant to a function with a 
  * declared fixup) 
  * The rest of the fixup is done inside do_action().
  * @param a - filled module function call (MODULE*_T) action structure
  *            complete with parameters, starting at val[2] and parameter
  *            number at val[1].
  * @return 0 on success, -1 on error (it will also print the error msg.).
  *
  */
 static int mod_f_params_pre_fixup(struct action* a)
 {
dee21fff
 	sr31_cmd_export_t* cmd_exp;
cad98b04
 	action_u_t* params;
 	int param_no;
 	struct rval_expr* rve;
 	struct rvalue* rv;
 	int r;
 	str s;
 	
 	cmd_exp = a->val[0].u.data;
 	param_no = a->val[1].u.number;
 	params = &a->val[2];
 	
dee21fff
 	switch(cmd_exp->param_no) {
cad98b04
 		case 0:
 			a->type = MODULE0_T;
 			break;
 		case 1:
 			a->type = MODULE1_T;
 			break;
 		case 2:
 			a->type = MODULE2_T;
 			break;
 		case 3:
 			a->type = MODULE3_T;
 			break;
 		case 4:
 			a->type = MODULE4_T;
 			break;
 		case 5:
 			a->type = MODULE5_T;
 			break;
 		case 6:
 			a->type = MODULE6_T;
 			break;
 		case VAR_PARAM_NO:
 			a->type = MODULEX_T;
 			break;
 		default:
 			yyerror("function %s: bad definition"
dee21fff
 					" (invalid number of parameters)", cmd_exp->name);
cad98b04
 			return -1;
 	}
 	
dee21fff
 	if ( cmd_exp->fixup) {
 		if (is_fparam_rve_fixup(cmd_exp->fixup))
8f3db98b
 			/* mark known fparam rve safe fixups */
dee21fff
 			cmd_exp->fixup_flags  |= FIXUP_F_FPARAM_RVE;
d002aae9
 		else if (!(cmd_exp->fixup_flags & FIXUP_F_FPARAM_RVE) &&
 				 cmd_exp->free_fixup == 0) {
 			/* v0 or v1 functions that have fixups and no coresp. fixup_free
 			   functions, need constant, string params.*/
8f3db98b
 			for (r=0; r < param_no; r++) {
 				rve=params[r].u.data;
 				if (!rve_is_constant(rve)) {
 					yyerror_at(&rve->fpos, "function %s: parameter %d is not"
dee21fff
 								" constant\n", cmd_exp->name, r+1);
8f3db98b
 					return -1;
 				}
 				if ((rv = rval_expr_eval(0, 0, rve)) == 0 ||
 						rval_get_str(0, 0, &s, rv, 0) < 0 ) {
 					/* out of mem or bug ? */
 					rval_destroy(rv);
 					yyerror_at(&rve->fpos, "function %s: bad parameter %d"
dee21fff
 									" expression\n", cmd_exp->name, r+1);
8f3db98b
 					return -1;
 				}
cad98b04
 				rval_destroy(rv);
8f3db98b
 				rve_destroy(rve);
 				params[r].type = STRING_ST; /* asciiz */
 				params[r].u.string = s.s;
 				params[r].u.str.len = s.len; /* not used right now */
cad98b04
 			}
 		}
8f3db98b
 	}/* else
cad98b04
 		if no fixups are present, the RVEs can be transformed
 		into strings at runtime, allowing seamless var. use
 		even with old functions.
 		Further optimizations -> in fix_actions()
 		*/
 	return 0;
 }
 
 
 
 /** frees a filled module function call action structure.
  * @param a - filled module function call action structure
  *            complete with parameters, starting at val[2] and parameter
  *            number at val[1].
  */
 static void free_mod_func_action(struct action* a)
 {
 	action_u_t* params;
 	int param_no;
 	int r;
 	
 	param_no = a->val[1].u.number;
 	params = &a->val[2];
 	
 	for (r=0; r < param_no; r++)
 		if (params[r].u.data)
 			rve_destroy(params[r].u.data);
 	pkg_free(a);
 }
 
 
 
a15c363f
 /*
3c1a8ef8
 int main(int argc, char ** argv)
 {
 	if (yyparse()!=0)
 		fprintf(stderr, "parsing error\n");
 }
a15c363f
 */