fe8cbf27564829f75a46e427d6a1181c00a98214
[sip-router] / cfg.y
1 /*
2  * $Id$
3  *
4  *  cfg grammar
5  *
6  * Copyright (C) 2001-2003 FhG Fokus
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29  /*
30  * History:
31  * ---------
32  * 2003-01-29  src_port added (jiri)
33  * 2003-01-23  mhomed added (jiri)
34  * 2003-03-19  replaced all mallocs/frees with pkg_malloc/pkg_free (andrei)
35  * 2003-03-19  Added support for route type in find_export (janakj)
36  * 2003-03-20  Regex support in modparam (janakj)
37  * 2003-04-01  added dst_port, proto , af (andrei)
38  * 2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
39  * 2003-04-12  added force_rport, chroot and wdir (andrei)
40  * 2003-04-15  added tcp_children, disable_tcp (andrei)
41  * 2003-04-22  strip_tail added (jiri)
42  * 2003-07-03  tls* (disable, certificate, private_key, ca_list, verify,
43  *              require_certificate added (andrei)
44  * 2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
45  * 2003-10-02  added {,set_}advertised_{address,port} (andrei)
46  * 2003-10-10  added <,>,<=,>=, != operators support
47  *             added msg:len (andrei)
48  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
49  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
50  * 2003-10-24  converted to the new socket_info lists (andrei)
51  * 2003-10-28  added tcp_accept_aliases (andrei)
52  * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
53  * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
54  * 2004-04-29  added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
55  * 2004-05-03  applied multicast support patch (MCAST_LOOPBACK) from janakj
56  *             added MCAST_TTL (andrei)
57  * 2004-07-05  src_ip & dst_ip will detect ip addresses between quotes
58  *              (andrei)
59  * 2004-10-19  added FROM_URI, TO_URI (andrei)
60  * 2004-11-30  added force_send_socket (andrei)
61  * 2005-07-08  added TCP_CON_LIFETIME, TCP_POLL_METHOD, TCP_MAX_CONNECTIONS
62  *              (andrei)
63  * 2005-07-11 added DNS_RETR_TIME, DNS_RETR_NO, DNS_SERVERS_NO, DNS_USE_SEARCH,
64  *             DNS_TRY_IPV6 (andrei)
65  * 2005-07-12  default onreply route added (andrei)
66  * 2005-11-16  fixed if (cond) cmd; (andrei)
67  * 2005-12-11  added onsend_route support, fcmd (filtered cmd),
68  *             snd_{ip,port,proto,af}, to_{ip,proto} (andrei)
69  * 2005-12-19  select framework (mma)
70  * 2006-01-06  AVP index support (mma)
71  * 2005-01-07  optional semicolon in statement, PARAM_STR&PARAM_STRING
72  * 2006-02-02  named flags support (andrei)
73  * 2006-02-06  named routes support (andrei)
74  * 2006-05-30  avp flags (tma)
75  * 2006-09-11  added dns cache (use, flags, ttls, mem ,gc) & dst blacklist
76  *              options (andrei)
77  * 2006-10-13  added STUN_ALLOW_STUN, STUN_ALLOW_FP, STUN_REFRESH_INTERVAL
78  *              (vlada)
79  * 2007-02-09  separated command needed for tls-in-core and for tls in general
80  *              (andrei)
81  * 2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
82  *              RT_POLICY, RT_TIMER1_PRIO, RT_TIMER1_POLICY, RT_TIMER2_PRIO,
83  *              RT_TIMER2_POLICY (andrei)
84  * 2007-06-16  added DDNS_SRV_LB, DNS_TRY_NAPTR (andrei)
85  * 2007-09-10  introduced phone2tel option which allows NOT to consider
86  *             user=phone URIs as TEL URIs (jiri)
87  * 2007-10-10  added DNS_SEARCH_FMATCH (mma)
88  * 2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
89  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
90  * 2008-01-24  added cfg_var definition (Miklos)
91  * 2008-11-18  support for variable parameter module functions (andrei)
92  * 2007-12-03  support for generalised lvalues and rvalues:
93  *               lval=rval_expr, where lval=avp|pvar  (andrei)
94  * 2007-12-06  expression are now evaluated in terms of rvalues;
95  *             NUMBER is now always positive; cleanup (andrei)
96  * 2009-01-26  case/switch() support (andrei)
97  * 2009-03-10  added SET_USERPHONE action (Miklos)
98  * 2009-05-04  switched if to rval_expr (andrei)
99 */
100
101 %{
102
103 #include <stdlib.h>
104 #include <stdio.h>
105 #include <stdarg.h>
106 #include <sys/types.h>
107 #include <sys/socket.h>
108 #include <netinet/in.h>
109 #include <arpa/inet.h>
110 #include <string.h>
111 #include <errno.h>
112 #include "route_struct.h"
113 #include "globals.h"
114 #include "route.h"
115 #include "switch.h"
116 #include "dprint.h"
117 #include "sr_module.h"
118 #include "modparam.h"
119 #include "ip_addr.h"
120 #include "resolve.h"
121 #include "socket_info.h"
122 #include "name_alias.h"
123 #include "ut.h"
124 #include "dset.h"
125 #include "select.h"
126 #include "flags.h"
127 #include "tcp_init.h"
128 #include "tcp_options.h"
129 #include "sctp_options.h"
130 #include "pvar.h"
131 #include "lvalue.h"
132 #include "rvalue.h"
133 #include "sr_compat.h"
134 #include "msg_translator.h"
135
136 #include "config.h"
137 #include "cfg_core.h"
138 #include "cfg/cfg.h"
139 #ifdef CORE_TLS
140 #include "tls/tls_config.h"
141 #endif
142 #include "timer_ticks.h"
143
144 #ifdef DEBUG_DMALLOC
145 #include <dmalloc.h>
146 #endif
147
148 /* hack to avoid alloca usage in the generated C file (needed for compiler
149  with no built in alloca, like icc*/
150 #undef _ALLOCA_H
151
152 #define onsend_check(s) \
153         do{\
154                 if (rt!=ONSEND_ROUTE) yyerror( s " allowed only in onsend_routes");\
155         }while(0)
156
157
158 #ifdef USE_DNS_CACHE
159         #define IF_DNS_CACHE(x) x
160 #else
161         #define IF_DNS_CACHE(x) warn("dns cache support not compiled in")
162 #endif
163
164 #ifdef USE_DNS_FAILOVER
165         #define IF_DNS_FAILOVER(x) x
166 #else
167         #define IF_DNS_FAILOVER(x) warn("dns failover support not compiled in")
168 #endif
169
170 #ifdef USE_NAPTR
171         #define IF_NAPTR(x) x
172 #else
173         #define IF_NAPTR(x) warn("dns naptr support not compiled in")
174 #endif
175
176 #ifdef USE_DST_BLACKLIST
177         #define IF_DST_BLACKLIST(x) x
178 #else
179         #define IF_DST_BLACKLIST(x) warn("dst blacklist support not compiled in")
180 #endif
181
182 #ifdef USE_STUN
183         #define IF_STUN(x) x
184 #else 
185         #define IF_STUN(x) warn("stun support not compiled in")
186 #endif
187
188 #ifdef USE_SCTP
189         #define IF_SCTP(x) x
190 #else
191         #define IF_SCTP(x) warn("sctp support not compiled in")
192 #endif
193
194
195 extern int yylex();
196 /* safer then using yytext which can be array or pointer */
197 extern char* yy_number_str;
198
199 static void yyerror(char* s, ...);
200 static void yyerror_at(struct cfg_pos* pos, char* s, ...);
201 static char* tmp;
202 static int i_tmp;
203 static unsigned u_tmp;
204 static struct socket_id* lst_tmp;
205 static struct name_lst*  nl_tmp;
206 static int rt;  /* Type of route block for find_export */
207 static str* str_tmp;
208 static str s_tmp;
209 static struct ip_addr* ip_tmp;
210 static struct avp_spec* s_attr;
211 static select_t sel;
212 static select_t* sel_ptr;
213 static pv_spec_t* pv_spec;
214 static struct action *mod_func_action;
215 static struct lvalue* lval_tmp;
216 static struct rvalue* rval_tmp;
217
218 static void warn(char* s, ...);
219 static void warn_at(struct cfg_pos* pos, char* s, ...);
220 static void get_cpos(struct cfg_pos* pos);
221 static struct rval_expr* mk_rve_rval(enum rval_type, void* v);
222 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1);
223 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
224                                                                         struct rval_expr* rve2);
225 static int rval_expr_int_check(struct rval_expr *rve);
226 static int warn_ct_rve(struct rval_expr *rve, char* name);
227 static struct socket_id* mk_listen_id(char*, int, int);
228 static struct name_lst* mk_name_lst(char* name, int flags);
229 static struct socket_id* mk_listen_id2(struct name_lst*, int, int);
230 static void free_name_lst(struct name_lst* lst);
231 static void free_socket_id_lst(struct socket_id* i);
232
233 static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re, 
234                                                                         struct action* a, int* err);
235 static int case_check_type(struct case_stms* stms);
236 static int case_check_default(struct case_stms* stms);
237
238
239 extern int line;
240 extern int column;
241 extern int startcolumn;
242 extern int startline;
243 extern char *finame;
244
245 #define set_cfg_pos(x) \
246         do{\
247                 if(x) {\
248                 (x)->cline = line;\
249                 (x)->cfile = (finame!=0)?finame:((cfg_file!=0)?cfg_file:"default");\
250                 }\
251         }while(0)
252
253
254 %}
255
256 %union {
257         long intval;
258         unsigned long uval;
259         char* strval;
260         struct expr* expr;
261         struct action* action;
262         struct case_stms* case_stms;
263         struct net* ipnet;
264         struct ip_addr* ipaddr;
265         struct socket_id* sockid;
266         struct name_lst* name_l;
267         struct avp_spec* attr;
268         struct _pv_spec* pvar;
269         struct lvalue* lval;
270         struct rvalue* rval;
271         struct rval_expr* rv_expr;
272         select_t* select;
273 }
274
275 /* terminals */
276
277
278 /* keywords */
279 %token FORWARD
280 %token FORWARD_TCP
281 %token FORWARD_TLS
282 %token FORWARD_SCTP
283 %token FORWARD_UDP
284 %token SEND
285 %token SEND_TCP
286 %token EXIT
287 %token DROP
288 %token RETURN
289 %token BREAK
290 %token LOG_TOK
291 %token ERROR
292 %token ROUTE
293 %token ROUTE_FAILURE
294 %token ROUTE_ONREPLY
295 %token ROUTE_BRANCH
296 %token ROUTE_SEND
297 %token ROUTE_EVENT
298 %token EXEC
299 %token SET_HOST
300 %token SET_HOSTPORT
301 %token SET_HOSTPORTTRANS
302 %token PREFIX
303 %token STRIP
304 %token STRIP_TAIL
305 %token SET_USERPHONE
306 %token APPEND_BRANCH
307 %token SET_USER
308 %token SET_USERPASS
309 %token SET_PORT
310 %token SET_URI
311 %token REVERT_URI
312 %token FORCE_RPORT
313 %token ADD_LOCAL_RPORT
314 %token FORCE_TCP_ALIAS
315 %token UDP_MTU
316 %token UDP_MTU_TRY_PROTO
317 %token IF
318 %token ELSE
319 %token SET_ADV_ADDRESS
320 %token SET_ADV_PORT
321 %token FORCE_SEND_SOCKET
322 %token SET_FWD_NO_CONNECT
323 %token SET_RPL_NO_CONNECT
324 %token SET_FWD_CLOSE
325 %token SET_RPL_CLOSE
326 %token SWITCH
327 %token CASE
328 %token DEFAULT
329 %token WHILE
330 %token URIHOST
331 %token URIPORT
332 %token MAX_LEN
333 %token SETFLAG
334 %token RESETFLAG
335 %token ISFLAGSET
336 %token SETAVPFLAG
337 %token RESETAVPFLAG
338 %token ISAVPFLAGSET
339 %token METHOD
340 %token URI
341 %token FROM_URI
342 %token TO_URI
343 %token SRCIP
344 %token SRCPORT
345 %token DSTIP
346 %token DSTPORT
347 %token TOIP
348 %token TOPORT
349 %token SNDIP
350 %token SNDPORT
351 %token SNDPROTO
352 %token SNDAF
353 %token PROTO
354 %token AF
355 %token MYSELF
356 %token MSGLEN
357 %token RETCODE
358 %token UDP
359 %token TCP
360 %token TLS
361 %token SCTP
362
363 /* config vars. */
364 %token DEBUG_V
365 %token FORK
366 %token LOGSTDERROR
367 %token LOGFACILITY
368 %token LOGNAME
369 %token LISTEN
370 %token ALIAS
371 %token SR_AUTO_ALIASES
372 %token DNS
373 %token REV_DNS
374 %token DNS_TRY_IPV6
375 %token DNS_TRY_NAPTR
376 %token DNS_SRV_LB
377 %token DNS_UDP_PREF
378 %token DNS_TCP_PREF
379 %token DNS_TLS_PREF
380 %token DNS_SCTP_PREF
381 %token DNS_RETR_TIME
382 %token DNS_RETR_NO
383 %token DNS_SERVERS_NO
384 %token DNS_USE_SEARCH
385 %token DNS_SEARCH_FMATCH
386 %token DNS_CACHE_INIT
387 %token DNS_USE_CACHE
388 %token DNS_USE_FAILOVER
389 %token DNS_CACHE_FLAGS
390 %token DNS_CACHE_NEG_TTL
391 %token DNS_CACHE_MIN_TTL
392 %token DNS_CACHE_MAX_TTL
393 %token DNS_CACHE_MEM
394 %token DNS_CACHE_GC_INT
395 %token DNS_CACHE_DEL_NONEXP
396 /*blacklist*/
397 %token DST_BLST_INIT
398 %token USE_DST_BLST
399 %token DST_BLST_MEM
400 %token DST_BLST_TTL
401 %token DST_BLST_GC_INT
402
403 %token PORT
404 %token STAT
405 %token CHILDREN
406 %token CHECK_VIA
407 %token PHONE2TEL
408 %token SYN_BRANCH
409 %token MEMLOG
410 %token MEMDBG
411 %token SIP_WARNING
412 %token SERVER_SIGNATURE
413 %token SERVER_HEADER
414 %token USER_AGENT_HEADER
415 %token REPLY_TO_VIA
416 %token LOADMODULE
417 %token LOADPATH
418 %token MODPARAM
419 %token MAXBUFFER
420 %token USER
421 %token GROUP
422 %token CHROOT
423 %token WDIR
424 %token MHOMED
425 %token DISABLE_TCP
426 %token TCP_ACCEPT_ALIASES
427 %token TCP_CHILDREN
428 %token TCP_CONNECT_TIMEOUT
429 %token TCP_SEND_TIMEOUT
430 %token TCP_CON_LIFETIME
431 %token TCP_POLL_METHOD
432 %token TCP_MAX_CONNECTIONS
433 %token TCP_NO_CONNECT
434 %token TCP_SOURCE_IPV4
435 %token TCP_SOURCE_IPV6
436 %token TCP_OPT_FD_CACHE
437 %token TCP_OPT_BUF_WRITE
438 %token TCP_OPT_CONN_WQ_MAX
439 %token TCP_OPT_WQ_MAX
440 %token TCP_OPT_RD_BUF
441 %token TCP_OPT_WQ_BLK
442 %token TCP_OPT_DEFER_ACCEPT
443 %token TCP_OPT_DELAYED_ACK
444 %token TCP_OPT_SYNCNT
445 %token TCP_OPT_LINGER2
446 %token TCP_OPT_KEEPALIVE
447 %token TCP_OPT_KEEPIDLE
448 %token TCP_OPT_KEEPINTVL
449 %token TCP_OPT_KEEPCNT
450 %token TCP_OPT_CRLF_PING
451 %token DISABLE_TLS
452 %token ENABLE_TLS
453 %token TLSLOG
454 %token TLS_PORT_NO
455 %token TLS_METHOD
456 %token TLS_HANDSHAKE_TIMEOUT
457 %token TLS_SEND_TIMEOUT
458 %token SSLv23
459 %token SSLv2
460 %token SSLv3
461 %token TLSv1
462 %token TLS_VERIFY
463 %token TLS_REQUIRE_CERTIFICATE
464 %token TLS_CERTIFICATE
465 %token TLS_PRIVATE_KEY
466 %token TLS_CA_LIST
467 %token DISABLE_SCTP
468 %token ENABLE_SCTP
469 %token SCTP_CHILDREN
470 %token SCTP_SOCKET_RCVBUF
471 %token SCTP_SOCKET_SNDBUF
472 %token SCTP_AUTOCLOSE
473 %token SCTP_SEND_TTL
474 %token SCTP_SEND_RETRIES
475 %token SCTP_ASSOC_TRACKING
476 %token SCTP_ASSOC_REUSE
477 %token SCTP_MAX_ASSOCS
478 %token SCTP_SRTO_INITIAL
479 %token SCTP_SRTO_MAX
480 %token SCTP_SRTO_MIN
481 %token SCTP_ASOCMAXRXT
482 %token SCTP_INIT_MAX_ATTEMPTS
483 %token SCTP_INIT_MAX_TIMEO
484 %token SCTP_HBINTERVAL
485 %token SCTP_PATHMAXRXT
486 %token SCTP_SACK_DELAY
487 %token SCTP_SACK_FREQ
488 %token SCTP_MAX_BURST
489 %token ADVERTISED_ADDRESS
490 %token ADVERTISED_PORT
491 %token DISABLE_CORE
492 %token OPEN_FD_LIMIT
493 %token SHM_FORCE_ALLOC
494 %token MLOCK_PAGES
495 %token REAL_TIME
496 %token RT_PRIO
497 %token RT_POLICY
498 %token RT_TIMER1_PRIO
499 %token RT_TIMER1_POLICY
500 %token RT_TIMER2_PRIO
501 %token RT_TIMER2_POLICY
502 %token MCAST_LOOPBACK
503 %token MCAST_TTL
504 %token TOS
505 %token PMTU_DISCOVERY
506 %token KILL_TIMEOUT
507 %token MAX_WLOOPS
508 %token CFG_DESCRIPTION
509 %token SERVER_ID
510
511 %token FLAGS_DECL
512 %token AVPFLAGS_DECL
513
514 %token ATTR_MARK
515 %token SELECT_MARK
516 %token ATTR_FROM
517 %token ATTR_TO
518 %token ATTR_FROMURI
519 %token ATTR_TOURI
520 %token ATTR_FROMUSER
521 %token ATTR_TOUSER
522 %token ATTR_FROMDOMAIN
523 %token ATTR_TODOMAIN
524 %token ATTR_GLOBAL
525 %token ADDEQ
526
527
528 %token STUN_REFRESH_INTERVAL
529 %token STUN_ALLOW_STUN
530 %token STUN_ALLOW_FP
531
532
533 /* operators, C like precedence */
534 %right EQUAL
535 %left LOG_OR
536 %left LOG_AND
537 %left BIN_OR
538 %left BIN_AND
539 %left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
540 %left GT LT GTE LTE
541 %left PLUS MINUS
542 %left STAR SLASH MODULO
543 %right NOT
544 %right DEFINED
545 %right INTCAST STRCAST
546 %left DOT
547
548 /* no precedence, they use () */
549 %token STRLEN
550 %token STREMPTY
551
552 /* values */
553 %token <intval> NUMBER
554 %token <strval> ID
555 %token <strval> NUM_ID
556 %token <strval> STRING
557 %token <strval> IPV6ADDR
558 %token <strval> PVAR
559 /* not clear yet if this is an avp or pvar */
560 %token <strval> AVP_OR_PVAR
561 %token <strval> EVENT_RT_NAME
562
563 /* other */
564 %token COMMA
565 %token SEMICOLON
566 %token RPAREN
567 %token LPAREN
568 %token LBRACE
569 %token RBRACE
570 %token LBRACK
571 %token RBRACK
572 %token CR
573 %token COLON
574
575
576 /*non-terminals */
577 /*%type <expr> exp */
578 %type <expr> exp_elem
579 %type <intval> intno eint_op eint_op_onsend
580 %type <intval> eip_op eip_op_onsend
581 %type <action> action actions cmd fcmd if_cmd stm /*exp_stm*/ assign_action
582 %type <action> switch_cmd while_cmd ret_cmd
583 %type <case_stms> single_case case_stms
584 %type <ipaddr> ipv4 ipv6 ipv6addr ip
585 %type <ipnet> ipnet
586 %type <strval> host host_or_if host_if_id
587 %type <strval> listen_id
588 %type <name_l> listen_id_lst
589 %type <name_l> listen_id2
590 %type <sockid>  id_lst
591 %type <sockid>  phostport
592 %type <sockid>  listen_phostport
593 %type <intval> proto port
594 %type <intval> equalop strop cmpop rve_cmpop rve_equalop
595 %type <intval> uri_type
596 %type <attr> attr_id
597 %type <attr> attr_id_num_idx
598 %type <attr> attr_id_no_idx
599 %type <attr> attr_id_ass
600 /*%type <attr> attr_id_val*/
601 %type <attr> attr_id_any
602 %type <attr> attr_id_any_str
603 %type <pvar> pvar
604 %type <lval> lval
605 %type <rv_expr> rval rval_expr ct_rval
606 %type <lval> avp_pvar
607 /* %type <intval> class_id */
608 %type <intval> assign_op
609 %type <select> select_id
610 %type <strval>  flag_name;
611 %type <strval>  route_name;
612 %type <intval> avpflag_oper
613 %type <intval> rve_un_op
614 %type <strval> cfg_var_id
615 /* %type <intval> rve_op */
616
617 /*%type <route_el> rules;
618   %type <route_el> rule;
619 */
620
621 %%
622
623
624 cfg:
625         statements
626         ;
627 statements:
628         statements statement {}
629         | statement {}
630         | statements error { yyerror(""); YYABORT;}
631         ;
632 statement:
633         assign_stm
634         | flags_decl
635         | avpflags_decl
636         | module_stm
637         | {rt=REQUEST_ROUTE;} route_stm
638         | {rt=FAILURE_ROUTE;} failure_route_stm
639         | {rt=ONREPLY_ROUTE;} onreply_route_stm
640         | {rt=BRANCH_ROUTE;} branch_route_stm
641         | {rt=ONSEND_ROUTE;}   send_route_stm
642         | {rt=EVENT_ROUTE;}   event_route_stm
643         | SEMICOLON     /* null statement */
644         | CR    /* null statement*/
645         ;
646 listen_id:
647         ip {
648                 if ($1){
649                         tmp=ip_addr2a($1);
650                         if (tmp==0) {
651                                 LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
652                                                 "address.\n");
653                                 $$=0;
654                         } else {
655                                 $$=pkg_malloc(strlen(tmp)+1);
656                                 if ($$==0) {
657                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
658                                                         "memory.\n");
659                                 } else {
660                                         strncpy($$, tmp, strlen(tmp)+1);
661                                 }
662                         }
663                 }
664         }
665         | STRING {
666                 $$=pkg_malloc(strlen($1)+1);
667                 if ($$==0) {
668                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
669                                                 "memory.\n");
670                 } else {
671                                 strncpy($$, $1, strlen($1)+1);
672                 }
673         }
674         | host_or_if {
675                 if ($1){
676                         $$=pkg_malloc(strlen($1)+1);
677                         if ($$==0) {
678                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
679                                                         "memory.\n");
680                         } else {
681                                         strncpy($$, $1, strlen($1)+1);
682                         }
683                 }
684         }
685         ;
686
687
688 listen_id_lst:
689         listen_id       { $$=mk_name_lst($1, SI_IS_MHOMED); }
690         | listen_id COMMA listen_id_lst { $$=mk_name_lst($1, SI_IS_MHOMED); 
691                                                                                 if ($$) $$->next=$3;
692                                                                         }
693         ;
694
695 listen_id2:
696         LPAREN listen_id_lst RPAREN { $$=$2; }
697         | listen_id     { $$=mk_name_lst($1, 0); }
698         ;
699
700 proto:
701         UDP     { $$=PROTO_UDP; }
702         | TCP   { $$=PROTO_TCP; }
703         | TLS   { $$=PROTO_TLS; }
704         | SCTP  { $$=PROTO_SCTP; }
705         | STAR  { $$=0; }
706         ;
707 port:
708         NUMBER  { $$=$1; }
709         | STAR  { $$=0; }
710 ;
711 phostport:
712         listen_id               { $$=mk_listen_id($1, 0, 0); }
713         | listen_id COLON port  { $$=mk_listen_id($1, 0, $3); }
714         | proto COLON listen_id { $$=mk_listen_id($3, $1, 0); }
715         | proto COLON listen_id COLON port      { $$=mk_listen_id($3, $1, $5);}
716         | listen_id COLON error { $$=0; yyerror(" port number expected"); }
717         ;
718
719 listen_phostport:
720         listen_id2              { $$=mk_listen_id2($1, 0, 0); }
721         | listen_id2 COLON port { $$=mk_listen_id2($1, 0, $3); }
722         | proto COLON listen_id2        { $$=mk_listen_id2($3, $1, 0); }
723         | proto COLON listen_id2 COLON port     { $$=mk_listen_id2($3, $1, $5);}
724         | listen_id2 COLON error { $$=0; yyerror(" port number expected"); }
725         ;
726
727 id_lst:
728         listen_phostport                {  $$=$1 ; }
729         | listen_phostport id_lst       { $$=$1;  if ($$) $$->next=$2; }
730         ;
731
732 intno: NUMBER
733         |  MINUS %prec NOT NUMBER { $$=-$2; }
734         ;
735
736 flags_decl:             FLAGS_DECL      flag_list
737                         |       FLAGS_DECL error { yyerror("flag list expected\n"); }
738 ;
739 flag_list:              flag_spec
740                         |       flag_spec COMMA flag_list
741 ;
742
743 flag_spec:              flag_name       { if (register_flag($1,-1)<0)
744                                                                 yyerror("register flag failed");
745                                                 }
746                         |       flag_name COLON NUMBER {
747                                                 if (register_flag($1, $3)<0)
748                                                                 yyerror("register flag failed");
749                                                                                 }
750 ;
751
752 flag_name:              STRING  { $$=$1; }
753                         |       ID              { $$=$1; }
754 ;
755
756 avpflags_decl:
757         AVPFLAGS_DECL avpflag_list
758         | AVPFLAGS_DECL error { yyerror("avpflag list expected\n"); }
759         ;
760 avpflag_list:
761         avpflag_spec
762         | avpflag_spec COMMA avpflag_list
763         ;
764 avpflag_spec:
765         flag_name {
766                 if (register_avpflag($1)==0)
767                         yyerror("cannot declare avpflag");
768         }
769         ;
770 assign_stm:
771         DEBUG_V EQUAL intno { default_core_cfg.debug=$3; }
772         | DEBUG_V EQUAL error  { yyerror("number  expected"); }
773         | FORK  EQUAL NUMBER { dont_fork= ! $3; }
774         | FORK  EQUAL error  { yyerror("boolean value expected"); }
775         | LOGSTDERROR EQUAL NUMBER { if (!config_check) log_stderr=$3; }
776         | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
777         | LOGFACILITY EQUAL ID {
778                 if ( (i_tmp=str2facility($3))==-1)
779                         yyerror("bad facility (see syslog(3) man page)");
780                 if (!config_check)
781                         default_core_cfg.log_facility=i_tmp;
782         }
783         | LOGFACILITY EQUAL error { yyerror("ID expected"); }
784         | LOGNAME EQUAL STRING { log_name=$3; }
785         | LOGNAME EQUAL error { yyerror("string value expected"); }
786         | DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
787         | DNS EQUAL error { yyerror("boolean value expected"); }
788         | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
789         | REV_DNS EQUAL error { yyerror("boolean value expected"); }
790         | DNS_TRY_IPV6 EQUAL NUMBER   { default_core_cfg.dns_try_ipv6=$3; }
791         | DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
792         | DNS_TRY_NAPTR EQUAL NUMBER   { IF_NAPTR(default_core_cfg.dns_try_naptr=$3); }
793         | DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
794         | DNS_SRV_LB EQUAL NUMBER   { IF_DNS_FAILOVER(default_core_cfg.dns_srv_lb=$3); }
795         | DNS_SRV_LB error { yyerror("boolean value expected"); }
796         | DNS_UDP_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_udp_pref=$3);}
797         | DNS_UDP_PREF error { yyerror("number expected"); }
798         | DNS_TCP_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tcp_pref=$3);}
799         | DNS_TCP_PREF error { yyerror("number expected"); }
800         | DNS_TLS_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tls_pref=$3);}
801         | DNS_TLS_PREF error { yyerror("number expected"); }
802         | DNS_SCTP_PREF EQUAL intno { 
803                                                                 IF_NAPTR(default_core_cfg.dns_sctp_pref=$3); }
804         | DNS_SCTP_PREF error { yyerror("number expected"); }
805         | DNS_RETR_TIME EQUAL NUMBER   { default_core_cfg.dns_retr_time=$3; }
806         | DNS_RETR_TIME error { yyerror("number expected"); }
807         | DNS_RETR_NO EQUAL NUMBER   { default_core_cfg.dns_retr_no=$3; }
808         | DNS_RETR_NO error { yyerror("number expected"); }
809         | DNS_SERVERS_NO EQUAL NUMBER   { default_core_cfg.dns_servers_no=$3; }
810         | DNS_SERVERS_NO error { yyerror("number expected"); }
811         | DNS_USE_SEARCH EQUAL NUMBER   { default_core_cfg.dns_search_list=$3; }
812         | DNS_USE_SEARCH error { yyerror("boolean value expected"); }
813         | DNS_SEARCH_FMATCH EQUAL NUMBER   { default_core_cfg.dns_search_fmatch=$3; }
814         | DNS_SEARCH_FMATCH error { yyerror("boolean value expected"); }
815         | DNS_CACHE_INIT EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_init=$3); }
816         | DNS_CACHE_INIT error { yyerror("boolean value expected"); }
817         | DNS_USE_CACHE EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.use_dns_cache=$3); }
818         | DNS_USE_CACHE error { yyerror("boolean value expected"); }
819         | DNS_USE_FAILOVER EQUAL NUMBER   { IF_DNS_FAILOVER(default_core_cfg.use_dns_failover=$3);}
820         | DNS_USE_FAILOVER error { yyerror("boolean value expected"); }
821         | DNS_CACHE_FLAGS EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_flags=$3); }
822         | DNS_CACHE_FLAGS error { yyerror("boolean value expected"); }
823         | DNS_CACHE_NEG_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_neg_cache_ttl=$3); }
824         | DNS_CACHE_NEG_TTL error { yyerror("boolean value expected"); }
825         | DNS_CACHE_MAX_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_max_ttl=$3); }
826         | DNS_CACHE_MAX_TTL error { yyerror("boolean value expected"); }
827         | DNS_CACHE_MIN_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_min_ttl=$3); }
828         | DNS_CACHE_MIN_TTL error { yyerror("boolean value expected"); }
829         | DNS_CACHE_MEM EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_max_mem=$3); }
830         | DNS_CACHE_MEM error { yyerror("boolean value expected"); }
831         | DNS_CACHE_GC_INT EQUAL NUMBER   { IF_DNS_CACHE(dns_timer_interval=$3); }
832         | DNS_CACHE_GC_INT error { yyerror("boolean value expected"); }
833         | DNS_CACHE_DEL_NONEXP EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_del_nonexp=$3); }
834         | DNS_CACHE_DEL_NONEXP error { yyerror("boolean value expected"); }
835         | DST_BLST_INIT EQUAL NUMBER   { IF_DST_BLACKLIST(dst_blacklist_init=$3); }
836         | DST_BLST_INIT error { yyerror("boolean value expected"); }
837         | USE_DST_BLST EQUAL NUMBER   { IF_DST_BLACKLIST(default_core_cfg.use_dst_blacklist=$3); }
838         | USE_DST_BLST error { yyerror("boolean value expected"); }
839         | DST_BLST_MEM EQUAL NUMBER   { IF_DST_BLACKLIST(default_core_cfg.blst_max_mem=$3); }
840         | DST_BLST_MEM error { yyerror("boolean value expected"); }
841         | DST_BLST_TTL EQUAL NUMBER   { IF_DST_BLACKLIST(default_core_cfg.blst_timeout=$3); }
842         | DST_BLST_TTL error { yyerror("boolean value expected"); }
843         | DST_BLST_GC_INT EQUAL NUMBER { IF_DST_BLACKLIST(blst_timer_interval=$3);}
844         | DST_BLST_GC_INT error { yyerror("boolean value expected"); }
845         | PORT EQUAL NUMBER   { port_no=$3; }
846         | STAT EQUAL STRING {
847                 #ifdef STATS
848                                 stat_file=$3;
849                 #endif
850         }
851         | MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
852         | MAXBUFFER EQUAL error { yyerror("number expected"); }
853         | PORT EQUAL error    { yyerror("number expected"); }
854         | CHILDREN EQUAL NUMBER { children_no=$3; }
855         | CHILDREN EQUAL error { yyerror("number expected"); }
856         | CHECK_VIA EQUAL NUMBER { check_via=$3; }
857         | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
858         | PHONE2TEL EQUAL NUMBER { phone2tel=$3; }
859         | PHONE2TEL EQUAL error { yyerror("boolean value expected"); }
860         | SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
861         | SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
862         | MEMLOG EQUAL intno { memlog=$3; }
863         | MEMLOG EQUAL error { yyerror("int value expected"); }
864         | MEMDBG EQUAL intno { memdbg=$3; }
865         | MEMDBG EQUAL error { yyerror("int value expected"); }
866         | SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
867         | SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
868         | USER EQUAL STRING     { user=$3; }
869         | USER EQUAL ID         { user=$3; }
870         | USER EQUAL error      { yyerror("string value expected"); }
871         | GROUP EQUAL STRING     { group=$3; }
872         | GROUP EQUAL ID         { group=$3; }
873         | GROUP EQUAL error      { yyerror("string value expected"); }
874         | CHROOT EQUAL STRING     { chroot_dir=$3; }
875         | CHROOT EQUAL ID         { chroot_dir=$3; }
876         | CHROOT EQUAL error      { yyerror("string value expected"); }
877         | WDIR EQUAL STRING     { working_dir=$3; }
878         | WDIR EQUAL ID         { working_dir=$3; }
879         | WDIR EQUAL error      { yyerror("string value expected"); }
880         | MHOMED EQUAL NUMBER { mhomed=$3; }
881         | MHOMED EQUAL error { yyerror("boolean value expected"); }
882         | DISABLE_TCP EQUAL NUMBER {
883                 #ifdef USE_TCP
884                         tcp_disable=$3;
885                 #else
886                         warn("tcp support not compiled in");
887                 #endif
888         }
889         | DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
890         | TCP_ACCEPT_ALIASES EQUAL NUMBER {
891                 #ifdef USE_TCP
892                         tcp_default_cfg.accept_aliases=$3;
893                 #else
894                         warn("tcp support not compiled in");
895                 #endif
896         }
897         | TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
898         | TCP_CHILDREN EQUAL NUMBER {
899                 #ifdef USE_TCP
900                         tcp_children_no=$3;
901                 #else
902                         warn("tcp support not compiled in");
903                 #endif
904         }
905         | TCP_CHILDREN EQUAL error { yyerror("number expected"); }
906         | TCP_CONNECT_TIMEOUT EQUAL intno {
907                 #ifdef USE_TCP
908                         tcp_default_cfg.connect_timeout_s=$3;
909                 #else
910                         warn("tcp support not compiled in");
911                 #endif
912         }
913         | TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
914         | TCP_SEND_TIMEOUT EQUAL intno {
915                 #ifdef USE_TCP
916                         tcp_default_cfg.send_timeout=S_TO_TICKS($3);
917                 #else
918                         warn("tcp support not compiled in");
919                 #endif
920         }
921         | TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
922         | TCP_CON_LIFETIME EQUAL intno {
923                 #ifdef USE_TCP
924                         if ($3<0)
925                                 tcp_default_cfg.con_lifetime=-1;
926                         else
927                                 tcp_default_cfg.con_lifetime=S_TO_TICKS($3);
928                 #else
929                         warn("tcp support not compiled in");
930                 #endif
931         }
932         | TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
933         | TCP_POLL_METHOD EQUAL ID {
934                 #ifdef USE_TCP
935                         tcp_poll_method=get_poll_type($3);
936                         if (tcp_poll_method==POLL_NONE) {
937                                 LOG(L_CRIT, "bad poll method name:"
938                                                 " %s\n, try one of %s.\n",
939                                                 $3, poll_support);
940                                 yyerror("bad tcp_poll_method "
941                                                 "value");
942                         }
943                 #else
944                         warn("tcp support not compiled in");
945                 #endif
946         }
947         | TCP_POLL_METHOD EQUAL STRING {
948                 #ifdef USE_TCP
949                         tcp_poll_method=get_poll_type($3);
950                         if (tcp_poll_method==POLL_NONE) {
951                                 LOG(L_CRIT, "bad poll method name:"
952                                                 " %s\n, try one of %s.\n",
953                                                 $3, poll_support);
954                                 yyerror("bad tcp_poll_method "
955                                                 "value");
956                         }
957                 #else
958                         warn("tcp support not compiled in");
959                 #endif
960         }
961         | TCP_POLL_METHOD EQUAL error { yyerror("poll method name expected"); }
962         | TCP_MAX_CONNECTIONS EQUAL NUMBER {
963                 #ifdef USE_TCP
964                         tcp_max_connections=$3;
965                 #else
966                         warn("tcp support not compiled in");
967                 #endif
968         }
969         | TCP_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
970         | TCP_NO_CONNECT EQUAL NUMBER {
971                 #ifdef USE_TCP
972                         tcp_default_cfg.no_connect=$3;
973                 #else
974                         warn("tcp support not compiled in");
975                 #endif
976         }
977         | TCP_NO_CONNECT EQUAL error { yyerror("boolean value expected"); }
978         | TCP_SOURCE_IPV4 EQUAL ipv4 {
979                 #ifdef USE_TCP
980                         if (tcp_set_src_addr($3)<0)
981                                 warn("tcp_source_ipv4 failed");
982                 #else
983                         warn("tcp support not compiled in");
984                 #endif
985                 pkg_free($3);
986         }
987         | TCP_SOURCE_IPV4 EQUAL error { yyerror("IPv4 address expected"); }
988         | TCP_SOURCE_IPV6 EQUAL ipv6 {
989                 #ifdef USE_TCP
990                         #ifdef USE_IPV6
991                                 if (tcp_set_src_addr($3)<0)
992                                         warn("tcp_source_ipv6 failed");
993                         #else
994                                 warn("IPv6 support not compiled in");
995                         #endif
996                 #else
997                         warn("tcp support not compiled in");
998                 #endif
999                 pkg_free($3);
1000         }
1001         | TCP_SOURCE_IPV6 EQUAL error { yyerror("IPv6 address expected"); }
1002         | TCP_OPT_FD_CACHE EQUAL NUMBER {
1003                 #ifdef USE_TCP
1004                         tcp_default_cfg.fd_cache=$3;
1005                 #else
1006                         warn("tcp support not compiled in");
1007                 #endif
1008         }
1009         | TCP_OPT_FD_CACHE EQUAL error { yyerror("boolean value expected"); }
1010         | TCP_OPT_BUF_WRITE EQUAL NUMBER {
1011                 #ifdef USE_TCP
1012                         tcp_default_cfg.async=$3;
1013                 #else
1014                         warn("tcp support not compiled in");
1015                 #endif
1016         }
1017         | TCP_OPT_BUF_WRITE EQUAL error { yyerror("boolean value expected"); }
1018         | TCP_OPT_CONN_WQ_MAX EQUAL NUMBER {
1019                 #ifdef USE_TCP
1020                         tcp_default_cfg.tcpconn_wq_max=$3;
1021                 #else
1022                         warn("tcp support not compiled in");
1023                 #endif
1024         }
1025         | TCP_OPT_CONN_WQ_MAX error { yyerror("boolean value expected"); }
1026         | TCP_OPT_WQ_MAX EQUAL NUMBER {
1027                 #ifdef USE_TCP
1028                         tcp_default_cfg.tcp_wq_max=$3;
1029                 #else
1030                         warn("tcp support not compiled in");
1031                 #endif
1032         }
1033         | TCP_OPT_WQ_MAX error { yyerror("number expected"); }
1034         | TCP_OPT_RD_BUF EQUAL NUMBER {
1035                 #ifdef USE_TCP
1036                         tcp_default_cfg.rd_buf_size=$3;
1037                 #else
1038                         warn("tcp support not compiled in");
1039                 #endif
1040         }
1041         | TCP_OPT_RD_BUF error { yyerror("number expected"); }
1042         | TCP_OPT_WQ_BLK EQUAL NUMBER {
1043                 #ifdef USE_TCP
1044                         tcp_default_cfg.wq_blk_size=$3;
1045                 #else
1046                         warn("tcp support not compiled in");
1047                 #endif
1048         }
1049         | TCP_OPT_WQ_BLK error { yyerror("number expected"); }
1050         | TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
1051                 #ifdef USE_TCP
1052                         tcp_default_cfg.defer_accept=$3;
1053                 #else
1054                         warn("tcp support not compiled in");
1055                 #endif
1056         }
1057         | TCP_OPT_DEFER_ACCEPT EQUAL error { yyerror("boolean value expected"); }
1058         | TCP_OPT_DELAYED_ACK EQUAL NUMBER {
1059                 #ifdef USE_TCP
1060                         tcp_default_cfg.delayed_ack=$3;
1061                 #else
1062                         warn("tcp support not compiled in");
1063                 #endif
1064         }
1065         | TCP_OPT_DELAYED_ACK EQUAL error { yyerror("boolean value expected"); }
1066         | TCP_OPT_SYNCNT EQUAL NUMBER {
1067                 #ifdef USE_TCP
1068                         tcp_default_cfg.syncnt=$3;
1069                 #else
1070                         warn("tcp support not compiled in");
1071                 #endif
1072         }
1073         | TCP_OPT_SYNCNT EQUAL error { yyerror("number expected"); }
1074         | TCP_OPT_LINGER2 EQUAL NUMBER {
1075                 #ifdef USE_TCP
1076                         tcp_default_cfg.linger2=$3;
1077                 #else
1078                         warn("tcp support not compiled in");
1079                 #endif
1080         }
1081         | TCP_OPT_LINGER2 EQUAL error { yyerror("number expected"); }
1082         | TCP_OPT_KEEPALIVE EQUAL NUMBER {
1083                 #ifdef USE_TCP
1084                         tcp_default_cfg.keepalive=$3;
1085                 #else
1086                         warn("tcp support not compiled in");
1087                 #endif
1088         }
1089         | TCP_OPT_KEEPALIVE EQUAL error { yyerror("boolean value expected");}
1090         | TCP_OPT_KEEPIDLE EQUAL NUMBER {
1091                 #ifdef USE_TCP
1092                         tcp_default_cfg.keepidle=$3;
1093                 #else
1094                         warn("tcp support not compiled in");
1095                 #endif
1096         }
1097         | TCP_OPT_KEEPIDLE EQUAL error { yyerror("number expected"); }
1098         | TCP_OPT_KEEPINTVL EQUAL NUMBER {
1099                 #ifdef USE_TCP
1100                         tcp_default_cfg.keepintvl=$3;
1101                 #else
1102                         warn("tcp support not compiled in");
1103                 #endif
1104         }
1105         | TCP_OPT_KEEPINTVL EQUAL error { yyerror("number expected"); }
1106         | TCP_OPT_KEEPCNT EQUAL NUMBER {
1107                 #ifdef USE_TCP
1108                         tcp_default_cfg.keepcnt=$3;
1109                 #else
1110                         warn("tcp support not compiled in");
1111                 #endif
1112         }
1113         | TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
1114         | TCP_OPT_CRLF_PING EQUAL NUMBER {
1115                 #ifdef USE_TCP
1116                         tcp_default_cfg.crlf_ping=$3;
1117                 #else
1118                         warn("tcp support not compiled in");
1119                 #endif
1120         }
1121         | TCP_OPT_CRLF_PING EQUAL error { yyerror("boolean value expected"); }
1122         | DISABLE_TLS EQUAL NUMBER {
1123                 #ifdef USE_TLS
1124                         tls_disable=$3;
1125                 #else
1126                         warn("tls support not compiled in");
1127                 #endif
1128         }
1129         | DISABLE_TLS EQUAL error { yyerror("boolean value expected"); }
1130         | ENABLE_TLS EQUAL NUMBER {
1131                 #ifdef USE_TLS
1132                         tls_disable=!($3);
1133                 #else
1134                         warn("tls support not compiled in");
1135                 #endif
1136         }
1137         | ENABLE_TLS EQUAL error { yyerror("boolean value expected"); }
1138         | TLSLOG EQUAL NUMBER {
1139                 #ifdef CORE_TLS
1140                         tls_log=$3;
1141                 #else
1142                         warn("tls-in-core support not compiled in");
1143                 #endif
1144         }
1145         | TLSLOG EQUAL error { yyerror("int value expected"); }
1146         | TLS_PORT_NO EQUAL NUMBER {
1147                 #ifdef USE_TLS
1148                         tls_port_no=$3;
1149                 #else
1150                         warn("tls support not compiled in");
1151                 #endif
1152         }
1153         | TLS_PORT_NO EQUAL error { yyerror("number expected"); }
1154         | TLS_METHOD EQUAL SSLv23 {
1155                 #ifdef CORE_TLS
1156                         tls_method=TLS_USE_SSLv23;
1157                 #else
1158                         warn("tls-in-core support not compiled in");
1159                 #endif
1160         }
1161         | TLS_METHOD EQUAL SSLv2 {
1162                 #ifdef CORE_TLS
1163                         tls_method=TLS_USE_SSLv2;
1164                 #else
1165                         warn("tls-in-core support not compiled in");
1166                 #endif
1167         }
1168         | TLS_METHOD EQUAL SSLv3 {
1169                 #ifdef CORE_TLS
1170                         tls_method=TLS_USE_SSLv3;
1171                 #else
1172                         warn("tls-in-core support not compiled in");
1173                 #endif
1174         }
1175         | TLS_METHOD EQUAL TLSv1 {
1176                 #ifdef CORE_TLS
1177                         tls_method=TLS_USE_TLSv1;
1178                 #else
1179                         warn("tls-in-core support not compiled in");
1180                 #endif
1181         }
1182         | TLS_METHOD EQUAL error {
1183                 #ifdef CORE_TLS
1184                         yyerror("SSLv23, SSLv2, SSLv3 or TLSv1 expected");
1185                 #else
1186                         warn("tls-in-core support not compiled in");
1187                 #endif
1188         }
1189         | TLS_VERIFY EQUAL NUMBER {
1190                 #ifdef CORE_TLS
1191                         tls_verify_cert=$3;
1192                 #else
1193                         warn("tls-in-core support not compiled in");
1194                 #endif
1195         }
1196         | TLS_VERIFY EQUAL error { yyerror("boolean value expected"); }
1197         | TLS_REQUIRE_CERTIFICATE EQUAL NUMBER {
1198                 #ifdef CORE_TLS
1199                         tls_require_cert=$3;
1200                 #else
1201                         warn( "tls-in-core support not compiled in");
1202                 #endif
1203         }
1204         | TLS_REQUIRE_CERTIFICATE EQUAL error { yyerror("boolean value expected"); }
1205         | TLS_CERTIFICATE EQUAL STRING {
1206                 #ifdef CORE_TLS
1207                         tls_cert_file=$3;
1208                 #else
1209                         warn("tls-in-core support not compiled in");
1210                 #endif
1211         }
1212         | TLS_CERTIFICATE EQUAL error { yyerror("string value expected"); }
1213         | TLS_PRIVATE_KEY EQUAL STRING {
1214                 #ifdef CORE_TLS
1215                         tls_pkey_file=$3;
1216                 #else
1217                         warn("tls-in-core support not compiled in");
1218                 #endif
1219         }
1220         | TLS_PRIVATE_KEY EQUAL error { yyerror("string value expected"); }
1221         | TLS_CA_LIST EQUAL STRING {
1222                 #ifdef CORE_TLS
1223                         tls_ca_file=$3;
1224                 #else
1225                         warn("tls-in-core support not compiled in");
1226                 #endif
1227         }
1228         | TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
1229         | TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
1230                 #ifdef CORE_TLS
1231                         tls_handshake_timeout=$3;
1232                 #else
1233                         warn("tls-in-core support not compiled in");
1234                 #endif
1235         }
1236         | TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
1237         | TLS_SEND_TIMEOUT EQUAL NUMBER {
1238                 #ifdef CORE_TLS
1239                         tls_send_timeout=$3;
1240                 #else
1241                         warn("tls-in-core support not compiled in");
1242                 #endif
1243         }
1244         | TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
1245         | DISABLE_SCTP EQUAL NUMBER {
1246                 #ifdef USE_SCTP
1247                         sctp_disable=$3;
1248                 #else
1249                         warn("sctp support not compiled in");
1250                 #endif
1251         }
1252         | DISABLE_SCTP EQUAL error { yyerror("boolean value expected"); }
1253         | ENABLE_SCTP EQUAL NUMBER {
1254                 #ifdef USE_SCTP
1255                         sctp_disable=($3<=1)?!$3:$3;
1256                 #else
1257                         warn("sctp support not compiled in");
1258                 #endif
1259         }
1260         | ENABLE_SCTP EQUAL error { yyerror("boolean or number expected"); }
1261         | SCTP_CHILDREN EQUAL NUMBER {
1262                 #ifdef USE_SCTP
1263                         sctp_children_no=$3;
1264                 #else
1265                         warn("sctp support not compiled in");
1266                 #endif
1267         }
1268         | SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
1269         | SCTP_SOCKET_RCVBUF EQUAL NUMBER {
1270                 #ifdef USE_SCTP
1271                         sctp_default_cfg.so_rcvbuf=$3;
1272                 #else
1273                         warn("sctp support not compiled in");
1274                 #endif
1275         }
1276         | SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
1277         | SCTP_SOCKET_SNDBUF EQUAL NUMBER {
1278                 #ifdef USE_SCTP
1279                         sctp_default_cfg.so_sndbuf=$3;
1280                 #else
1281                         warn("sctp support not compiled in");
1282                 #endif
1283         }
1284         | SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
1285         | SCTP_AUTOCLOSE EQUAL NUMBER {
1286                 #ifdef USE_SCTP
1287                         sctp_default_cfg.autoclose=$3;
1288                 #else
1289                         warn("sctp support not compiled in");
1290                 #endif
1291         }
1292         | SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
1293         | SCTP_SEND_TTL EQUAL NUMBER {
1294                 #ifdef USE_SCTP
1295                         sctp_default_cfg.send_ttl=$3;
1296                 #else
1297                         warn("sctp support not compiled in");
1298                 #endif
1299         }
1300         | SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
1301         | SCTP_SEND_RETRIES EQUAL NUMBER {
1302                 #ifdef USE_SCTP
1303                         sctp_default_cfg.send_retries=$3;
1304                 #else
1305                         warn("sctp support not compiled in");
1306                 #endif
1307         }
1308         | SCTP_SEND_RETRIES EQUAL error { yyerror("number expected"); }
1309         | SCTP_ASSOC_TRACKING EQUAL NUMBER {
1310                 #ifdef USE_SCTP
1311                         #ifdef SCTP_CONN_REUSE
1312                                 sctp_default_cfg.assoc_tracking=$3;
1313                         #else
1314                                 if ($3)
1315                                         warn("sctp association tracking/reuse (SCTP_CONN_REUSE) "
1316                                                         "support not compiled in");
1317                         #endif /* SCTP_CONN_REUSE */
1318                 #else
1319                         warn("sctp support not compiled in");
1320                 #endif /* USE_SCTP */
1321         }
1322         | SCTP_ASSOC_TRACKING EQUAL error { yyerror("number expected"); }
1323         | SCTP_ASSOC_REUSE EQUAL NUMBER {
1324                 #ifdef USE_SCTP
1325                         #ifdef SCTP_CONN_REUSE
1326                                 sctp_default_cfg.assoc_reuse=$3;
1327                         #else
1328                                 if ($3)
1329                                         warn("sctp association reuse (SCTP_CONN_REUSE) support"
1330                                                         " not compiled in");
1331                         #endif /* SCTP_CONN_REUSE */
1332                 #else
1333                         warn("sctp support not compiled in");
1334                 #endif /* USE_SCTP */
1335         }
1336         | SCTP_ASSOC_REUSE EQUAL error { yyerror("number expected"); }
1337         | SCTP_MAX_ASSOCS EQUAL intno {
1338                         IF_SCTP(sctp_default_cfg.max_assocs=$3);
1339         }
1340         | SCTP_MAX_ASSOCS EQUAL error { yyerror("number expected"); }
1341         | SCTP_SRTO_INITIAL EQUAL NUMBER {
1342                         IF_SCTP(sctp_default_cfg.srto_initial=$3);
1343         }
1344         | SCTP_SRTO_INITIAL EQUAL error { yyerror("number expected"); }
1345         | SCTP_SRTO_MAX EQUAL NUMBER {
1346                         IF_SCTP(sctp_default_cfg.srto_max=$3);
1347         }
1348         | SCTP_SRTO_MAX EQUAL error { yyerror("number expected"); }
1349         | SCTP_SRTO_MIN EQUAL NUMBER {
1350                         IF_SCTP(sctp_default_cfg.srto_min=$3);
1351         }
1352         | SCTP_SRTO_MIN EQUAL error { yyerror("number expected"); }
1353         | SCTP_ASOCMAXRXT EQUAL NUMBER {
1354                         IF_SCTP(sctp_default_cfg.asocmaxrxt=$3);
1355         }
1356         | SCTP_ASOCMAXRXT EQUAL error { yyerror("number expected"); }
1357         | SCTP_INIT_MAX_ATTEMPTS EQUAL NUMBER {
1358                         IF_SCTP(sctp_default_cfg.init_max_attempts=$3);
1359         }
1360         | SCTP_INIT_MAX_ATTEMPTS EQUAL error { yyerror("number expected"); }
1361         | SCTP_INIT_MAX_TIMEO EQUAL NUMBER {
1362                         IF_SCTP(sctp_default_cfg.init_max_timeo=$3);
1363         }
1364         | SCTP_INIT_MAX_TIMEO EQUAL error { yyerror("number expected"); }
1365         | SCTP_HBINTERVAL EQUAL intno {
1366                         IF_SCTP(sctp_default_cfg.hbinterval=$3);
1367         }
1368         | SCTP_HBINTERVAL EQUAL error { yyerror("number expected"); }
1369         | SCTP_PATHMAXRXT EQUAL NUMBER {
1370                         IF_SCTP(sctp_default_cfg.pathmaxrxt=$3);
1371         }
1372         | SCTP_PATHMAXRXT EQUAL error { yyerror("number expected"); }
1373         | SCTP_SACK_DELAY EQUAL NUMBER {
1374                         IF_SCTP(sctp_default_cfg.sack_delay=$3);
1375         }
1376         | SCTP_SACK_DELAY EQUAL error { yyerror("number expected"); }
1377         | SCTP_SACK_FREQ EQUAL NUMBER {
1378                         IF_SCTP(sctp_default_cfg.sack_freq=$3);
1379         }
1380         | SCTP_SACK_FREQ EQUAL error { yyerror("number expected"); }
1381         | SCTP_MAX_BURST EQUAL NUMBER {
1382                         IF_SCTP(sctp_default_cfg.max_burst=$3);
1383         }
1384         | SCTP_MAX_BURST EQUAL error { yyerror("number expected"); }
1385         | SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
1386         | SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
1387         | SERVER_HEADER EQUAL STRING { server_hdr.s=$3;
1388                         server_hdr.len=strlen(server_hdr.s);
1389         }
1390         | SERVER_HEADER EQUAL error { yyerror("string value expected"); }
1391         | USER_AGENT_HEADER EQUAL STRING { user_agent_hdr.s=$3;
1392                         user_agent_hdr.len=strlen(user_agent_hdr.s);
1393         }
1394         | USER_AGENT_HEADER EQUAL error { yyerror("string value expected"); }
1395         | REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
1396         | REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
1397         | LISTEN EQUAL id_lst {
1398                 for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1399                         if (add_listen_iface(   lst_tmp->addr_lst->name,
1400                                                                         lst_tmp->addr_lst->next,
1401                                                                         lst_tmp->port, lst_tmp->proto,
1402                                                                         lst_tmp->flags)!=0) {
1403                                 LOG(L_CRIT,  "ERROR: cfg. parser: failed to add listen"
1404                                                                 " address\n");
1405                                 break;
1406                         }
1407                 }
1408                 free_socket_id_lst($3);
1409         }
1410         | LISTEN EQUAL  error { yyerror("ip address, interface name or"
1411                                                                         " hostname expected"); }
1412         | ALIAS EQUAL  id_lst {
1413                 for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
1414                         add_alias(      lst_tmp->addr_lst->name,
1415                                                 strlen(lst_tmp->addr_lst->name),
1416                                                 lst_tmp->port, lst_tmp->proto);
1417                         for (nl_tmp=lst_tmp->addr_lst->next; nl_tmp; nl_tmp=nl_tmp->next)
1418                                 add_alias(nl_tmp->name, strlen(nl_tmp->name),
1419                                                         lst_tmp->port, lst_tmp->proto);
1420                 }
1421                 free_socket_id_lst($3);
1422         }
1423         | ALIAS  EQUAL error  { yyerror(" hostname expected"); }
1424         | SR_AUTO_ALIASES EQUAL NUMBER { sr_auto_aliases=$3; }
1425         | SR_AUTO_ALIASES EQUAL error  { yyerror("boolean value expected"); }
1426         | ADVERTISED_ADDRESS EQUAL listen_id {
1427                 if ($3){
1428                         default_global_address.s=$3;
1429                         default_global_address.len=strlen($3);
1430                 }
1431         }
1432         | ADVERTISED_ADDRESS EQUAL error {yyerror("ip address or hostname expected"); }
1433         | ADVERTISED_PORT EQUAL NUMBER {
1434                 tmp=int2str($3, &i_tmp);
1435                 if ((default_global_port.s=pkg_malloc(i_tmp))==0) {
1436                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1437                         default_global_port.len=0;
1438                 } else {
1439                         default_global_port.len=i_tmp;
1440                         memcpy(default_global_port.s, tmp, default_global_port.len);
1441                 };
1442         }
1443         |ADVERTISED_PORT EQUAL error {yyerror("ip address or hostname expected"); }
1444         | DISABLE_CORE EQUAL NUMBER { disable_core_dump=$3; }
1445         | DISABLE_CORE EQUAL error { yyerror("boolean value expected"); }
1446         | OPEN_FD_LIMIT EQUAL NUMBER { open_files_limit=$3; }
1447         | OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); }
1448         | SHM_FORCE_ALLOC EQUAL NUMBER { shm_force_alloc=$3; }
1449         | SHM_FORCE_ALLOC EQUAL error { yyerror("boolean value expected"); }
1450         | MLOCK_PAGES EQUAL NUMBER { mlock_pages=$3; }
1451         | MLOCK_PAGES EQUAL error { yyerror("boolean value expected"); }
1452         | REAL_TIME EQUAL NUMBER { real_time=$3; }
1453         | REAL_TIME EQUAL error { yyerror("boolean value expected"); }
1454         | RT_PRIO EQUAL NUMBER { rt_prio=$3; }
1455         | RT_PRIO EQUAL error { yyerror("boolean value expected"); }
1456         | RT_POLICY EQUAL NUMBER { rt_policy=$3; }
1457         | RT_POLICY EQUAL error { yyerror("boolean value expected"); }
1458         | RT_TIMER1_PRIO EQUAL NUMBER { rt_timer1_prio=$3; }
1459         | RT_TIMER1_PRIO EQUAL error { yyerror("boolean value expected"); }
1460         | RT_TIMER1_POLICY EQUAL NUMBER { rt_timer1_policy=$3; }
1461         | RT_TIMER1_POLICY EQUAL error { yyerror("boolean value expected"); }
1462         | RT_TIMER2_PRIO EQUAL NUMBER { rt_timer2_prio=$3; }
1463         | RT_TIMER2_PRIO EQUAL error { yyerror("boolean value expected"); }
1464         | RT_TIMER2_POLICY EQUAL NUMBER { rt_timer2_policy=$3; }
1465         | RT_TIMER2_POLICY EQUAL error { yyerror("boolean value expected"); }
1466         | MCAST_LOOPBACK EQUAL NUMBER {
1467                 #ifdef USE_MCAST
1468                         mcast_loopback=$3;
1469                 #else
1470                         warn("no multicast support compiled in");
1471                 #endif
1472         }
1473         | MCAST_LOOPBACK EQUAL error { yyerror("boolean value expected"); }
1474         | MCAST_TTL EQUAL NUMBER {
1475                 #ifdef USE_MCAST
1476                         mcast_ttl=$3;
1477                 #else
1478                         warn("no multicast support compiled in");
1479                 #endif
1480         }
1481         | MCAST_TTL EQUAL error { yyerror("number expected"); }
1482         | TOS EQUAL NUMBER { tos=$3; }
1483         | TOS EQUAL error { yyerror("number expected"); }
1484         | PMTU_DISCOVERY EQUAL NUMBER { pmtu_discovery=$3; }
1485         | PMTU_DISCOVERY error { yyerror("number expected"); }
1486         | KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
1487         | KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
1488         | MAX_WLOOPS EQUAL NUMBER { default_core_cfg.max_while_loops=$3; }
1489         | MAX_WLOOPS EQUAL error { yyerror("number expected"); }
1490         | STUN_REFRESH_INTERVAL EQUAL NUMBER { IF_STUN(stun_refresh_interval=$3); }
1491         | STUN_REFRESH_INTERVAL EQUAL error{ yyerror("number expected"); }
1492         | STUN_ALLOW_STUN EQUAL NUMBER { IF_STUN(stun_allow_stun=$3); }
1493         | STUN_ALLOW_STUN EQUAL error{ yyerror("number expected"); }
1494         | STUN_ALLOW_FP EQUAL NUMBER { IF_STUN(stun_allow_fp=$3) ; }
1495         | STUN_ALLOW_FP EQUAL error{ yyerror("number expected"); }
1496     | SERVER_ID EQUAL NUMBER { server_id=$3; }
1497         | UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
1498         | UDP_MTU EQUAL error { yyerror("number expected"); }
1499         | FORCE_RPORT EQUAL NUMBER 
1500                 { default_core_cfg.force_rport=$3; fix_global_req_flags(0, 0); }
1501         | FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
1502         | UDP_MTU_TRY_PROTO EQUAL proto
1503                 { default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0, 0); }
1504         | UDP_MTU_TRY_PROTO EQUAL error
1505                 { yyerror("TCP, TLS, SCTP or UDP expected"); }
1506         | cfg_var
1507         | error EQUAL { yyerror("unknown config variable"); }
1508         ;
1509         
1510 cfg_var_id: ID 
1511         | DEFAULT { $$="default" ; } /*needed to allow default as cfg var. name*/
1512         ;
1513         
1514 cfg_var:
1515         cfg_var_id DOT cfg_var_id EQUAL NUMBER {
1516                 if (cfg_declare_int($1, $3, $5, 0, 0, NULL)) {
1517                         yyerror("variable cannot be declared");
1518                 }
1519         }
1520         | cfg_var_id DOT cfg_var_id EQUAL STRING {
1521                 if (cfg_declare_str($1, $3, $5, NULL)) {
1522                         yyerror("variable cannot be declared");
1523                 }
1524         }
1525         | cfg_var_id DOT cfg_var_id EQUAL NUMBER CFG_DESCRIPTION STRING {
1526                 if (cfg_declare_int($1, $3, $5, 0, 0, $7)) {
1527                         yyerror("variable cannot be declared");
1528                 }
1529         }
1530         | cfg_var_id DOT cfg_var_id EQUAL STRING CFG_DESCRIPTION STRING {
1531                 if (cfg_declare_str($1, $3, $5, $7)) {
1532                         yyerror("variable cannot be declared");
1533                 }
1534         }
1535         | cfg_var_id DOT cfg_var_id EQUAL error { 
1536                 yyerror("number or string expected"); 
1537         }
1538         ;
1539
1540 module_stm:
1541         LOADMODULE STRING {
1542                 DBG("loading module %s\n", $2);
1543                         if (load_module($2)!=0) {
1544                                 yyerror("failed to load module");
1545                         }
1546         }
1547         | LOADMODULE error      { yyerror("string expected"); }
1548         | LOADPATH STRING {
1549                 DBG("loading modules under %s\n", $2);
1550                 printf("loading modules under %s\n", $2);
1551                 mods_dir = $2;
1552         }
1553         | LOADPATH error        { yyerror("string expected"); }
1554         | LOADPATH EQUAL STRING {
1555                 DBG("loading modules under %s\n", $3);
1556                 printf("loading modules under %s\n", $3);
1557                 mods_dir = $3;
1558         }
1559         | LOADPATH EQUAL error  { yyerror("string expected"); }
1560         | MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
1561                 if (set_mod_param_regex($3, $5, PARAM_STRING, $7) != 0) {
1562                          yyerror("Can't set module parameter");
1563                 }
1564         }
1565         | MODPARAM LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
1566                 if (set_mod_param_regex($3, $5, PARAM_INT, (void*)$7) != 0) {
1567                          yyerror("Can't set module parameter");
1568                 }
1569         }
1570         | MODPARAM error { yyerror("Invalid arguments"); }
1571         ;
1572 ip:
1573         ipv4  { $$=$1; }
1574         | ipv6  { $$=$1; }
1575         ;
1576 ipv4:
1577         NUMBER DOT NUMBER DOT NUMBER DOT NUMBER {
1578                 $$=pkg_malloc(sizeof(struct ip_addr));
1579                 if ($$==0) {
1580                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1581                 } else {
1582                         memset($$, 0, sizeof(struct ip_addr));
1583                         $$->af=AF_INET;
1584                         $$->len=4;
1585                         if (($1>255) || ($1<0) ||
1586                                 ($3>255) || ($3<0) ||
1587                                 ($5>255) || ($5<0) ||
1588                                 ($7>255) || ($7<0)) {
1589                                 yyerror("invalid ipv4 address");
1590                                 $$->u.addr32[0]=0;
1591                                 /* $$=0; */
1592                         } else {
1593                                 $$->u.addr[0]=$1;
1594                                 $$->u.addr[1]=$3;
1595                                 $$->u.addr[2]=$5;
1596                                 $$->u.addr[3]=$7;
1597                                 /*
1598                                 $$=htonl( ($1<<24)|
1599                                 ($3<<16)| ($5<<8)|$7 );
1600                                 */
1601                         }
1602                 }
1603         }
1604         ;
1605 ipv6addr:
1606         IPV6ADDR {
1607                 $$=pkg_malloc(sizeof(struct ip_addr));
1608                 if ($$==0) {
1609                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1610                 } else {
1611                 #ifdef USE_IPV6
1612                         memset($$, 0, sizeof(struct ip_addr));
1613                         $$->af=AF_INET6;
1614                         $$->len=16;
1615                         if (inet_pton(AF_INET6, $1, $$->u.addr)<=0) {
1616                                 yyerror("bad ipv6 address");
1617                         }
1618                 #else
1619                         yyerror("ipv6 address & no ipv6 support compiled in");
1620                         YYABORT;
1621                 #endif
1622                 }
1623         }
1624         ;
1625 ipv6:
1626         ipv6addr { $$=$1; }
1627         | LBRACK ipv6addr RBRACK {$$=$2; }
1628 ;
1629
1630
1631 route_name:             NUMBER  {
1632                                         tmp=int2str($1, &i_tmp);
1633                                         if (($$=pkg_malloc(i_tmp+1))==0) {
1634                                                 yyerror("out of  memory");
1635                                                 YYABORT;
1636                                         } else {
1637                                                 memcpy($$, tmp, i_tmp);
1638                                                 $$[i_tmp]=0;
1639                                         }
1640                                                 }
1641                         |       ID              { $$=$1; }
1642                         |       STRING  { $$=$1; }
1643 ;
1644
1645 route_stm:
1646         ROUTE LBRACE actions RBRACE { push($3, &main_rt.rlist[DEFAULT_RT]); }
1647         | ROUTE LBRACK route_name RBRACK LBRACE actions RBRACE {
1648                 i_tmp=route_get(&main_rt, $3);
1649                 if (i_tmp==-1){
1650                         yyerror("internal error");
1651                         YYABORT;
1652                 }
1653                 if (main_rt.rlist[i_tmp]){
1654                         yyerror("duplicate route");
1655                         YYABORT;
1656                 }
1657                 push($6, &main_rt.rlist[i_tmp]);
1658         }
1659         | ROUTE error { yyerror("invalid  route  statement"); }
1660         ;
1661 failure_route_stm:
1662         ROUTE_FAILURE LBRACE actions RBRACE {
1663                                                                         push($3, &failure_rt.rlist[DEFAULT_RT]);
1664                                                                                 }
1665         | ROUTE_FAILURE LBRACK route_name RBRACK LBRACE actions RBRACE {
1666                 i_tmp=route_get(&failure_rt, $3);
1667                 if (i_tmp==-1){
1668                         yyerror("internal error");
1669                         YYABORT;
1670                 }
1671                 if (failure_rt.rlist[i_tmp]){
1672                         yyerror("duplicate route");
1673                         YYABORT;
1674                 }
1675                 push($6, &failure_rt.rlist[i_tmp]);
1676         }
1677         | ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
1678         ;
1679 onreply_route_stm:
1680         ROUTE_ONREPLY LBRACE actions RBRACE {
1681                                                                         push($3, &onreply_rt.rlist[DEFAULT_RT]);
1682                                                                                 }
1683         | ROUTE_ONREPLY LBRACK route_name RBRACK LBRACE actions RBRACE {
1684                 i_tmp=route_get(&onreply_rt, $3);
1685                 if (i_tmp==-1){
1686                         yyerror("internal error");
1687                         YYABORT;
1688                 }
1689                 if (onreply_rt.rlist[i_tmp]){
1690                         yyerror("duplicate route");
1691                         YYABORT;
1692                 }
1693                 push($6, &onreply_rt.rlist[i_tmp]);
1694         }
1695         | ROUTE_ONREPLY error { yyerror("invalid onreply_route statement"); }
1696         ;
1697 branch_route_stm:
1698         ROUTE_BRANCH LBRACE actions RBRACE {
1699                                                                         push($3, &branch_rt.rlist[DEFAULT_RT]);
1700                                                                                 }
1701         | ROUTE_BRANCH LBRACK route_name RBRACK LBRACE actions RBRACE {
1702                 i_tmp=route_get(&branch_rt, $3);
1703                 if (i_tmp==-1){
1704                         yyerror("internal error");
1705                         YYABORT;
1706                 }
1707                 if (branch_rt.rlist[i_tmp]){
1708                         yyerror("duplicate route");
1709                         YYABORT;
1710                 }
1711                 push($6, &branch_rt.rlist[i_tmp]);
1712         }
1713         | ROUTE_BRANCH error { yyerror("invalid branch_route statement"); }
1714         ;
1715 send_route_stm: ROUTE_SEND LBRACE actions RBRACE {
1716                                                                         push($3, &onsend_rt.rlist[DEFAULT_RT]);
1717                                                                                                 }
1718         | ROUTE_SEND LBRACK route_name RBRACK LBRACE actions RBRACE {
1719                 i_tmp=route_get(&onsend_rt, $3);
1720                 if (i_tmp==-1){
1721                         yyerror("internal error");
1722                         YYABORT;
1723                 }
1724                 if (onsend_rt.rlist[i_tmp]){
1725                         yyerror("duplicate route");
1726                         YYABORT;
1727                 }
1728                 push($6, &onsend_rt.rlist[i_tmp]);
1729         }
1730         | ROUTE_SEND error { yyerror("invalid onsend_route statement"); }
1731         ;
1732 event_route_stm: ROUTE_EVENT LBRACK EVENT_RT_NAME RBRACK LBRACE actions RBRACE {
1733                 i_tmp=route_get(&event_rt, $3);
1734                 if (i_tmp==-1){
1735                         yyerror("internal error");
1736                         YYABORT;
1737                 }
1738                 if (event_rt.rlist[i_tmp]){
1739                         yyerror("duplicate route");
1740                         YYABORT;
1741                 }
1742                 push($6, &event_rt.rlist[i_tmp]);
1743         }
1744
1745         | ROUTE_EVENT error { yyerror("invalid event_route statement"); }
1746         ;
1747
1748 /*exp:  rval_expr
1749                 {
1750                         if ($1==0){
1751                                 yyerror("invalid expression");
1752                                 $$=0;
1753                         }else if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
1754                                 yyerror("invalid expression");
1755                                 $$=0;
1756                         }else if (i_tmp!=RV_INT && i_tmp!=RV_NONE){
1757                                 yyerror("invalid expression type, int expected\n");
1758                                 $$=0;
1759                         }else
1760                                 $$=mk_elem(NO_OP, RVEXP_O, $1, 0, 0);
1761                 }
1762         ;
1763 */
1764
1765 /* exp elem operators */
1766 equalop:
1767         EQUAL_T {$$=EQUAL_OP; }
1768         | DIFF  {$$=DIFF_OP; }
1769         | STREQ {$$=EQUAL_OP; }  /* for expr. elems equiv. to EQUAL_T*/
1770         | STRDIFF {$$=DIFF_OP; } /* for expr. elems. equiv. to DIFF */
1771         ;
1772 cmpop:
1773           GT    {$$=GT_OP; }
1774         | LT    {$$=LT_OP; }
1775         | GTE   {$$=GTE_OP; }
1776         | LTE   {$$=LTE_OP; }
1777         ;
1778 strop:
1779         equalop {$$=$1; }
1780         | MATCH {$$=MATCH_OP; }
1781         ;
1782
1783
1784 /* rve expr. operators */
1785 rve_equalop:
1786         EQUAL_T {$$=RVE_EQ_OP; }
1787         | DIFF  {$$=RVE_DIFF_OP; }
1788         | INTEQ {$$=RVE_IEQ_OP; }
1789         | INTDIFF {$$=RVE_IDIFF_OP; }
1790         | STREQ {$$=RVE_STREQ_OP; }
1791         | STRDIFF {$$=RVE_STRDIFF_OP; }
1792         | MATCH {$$=RVE_MATCH_OP; }
1793         ;
1794 rve_cmpop:
1795           GT    {$$=RVE_GT_OP; }
1796         | LT    {$$=RVE_LT_OP; }
1797         | GTE   {$$=RVE_GTE_OP; }
1798         | LTE   {$$=RVE_LTE_OP; }
1799         ;
1800
1801
1802
1803 /* boolean expression uri operands */
1804 uri_type:
1805         URI             {$$=URI_O;}
1806         | FROM_URI      {$$=FROM_URI_O;}
1807         | TO_URI        {$$=TO_URI_O;}
1808         ;
1809
1810
1811 /* boolean expression integer operands, available only in the
1812   onsend route */
1813 eint_op_onsend:
1814                         SNDPORT         { $$=SNDPORT_O; }
1815                 |       TOPORT          { $$=TOPORT_O; }
1816                 |       SNDAF           { $$=SNDAF_O; }
1817                 ;
1818
1819 /* boolean expression integer operands */
1820 eint_op:        SRCPORT         { $$=SRCPORT_O; }
1821                 |       DSTPORT         { $$=DSTPORT_O; }
1822                 |       AF                      { $$=AF_O; }
1823                 |       MSGLEN          { $$=MSGLEN_O; }
1824                 |       RETCODE         { $$=RETCODE_O; }
1825                 | eint_op_onsend
1826         ;
1827
1828 /* boolean expression ip/ipnet operands */
1829 eip_op_onsend:
1830                         SNDIP           { onsend_check("snd_ip"); $$=SNDIP_O; }
1831                 |       TOIP            { onsend_check("to_ip");  $$=TOIP_O; }
1832                 ;
1833
1834 eip_op:         SRCIP           { $$=SRCIP_O; }
1835                 |       DSTIP           { $$=DSTIP_O; }
1836                 | eip_op_onsend
1837                 ;
1838
1839
1840
1841 exp_elem:
1842         METHOD strop %prec EQUAL_T rval_expr
1843                 {$$= mk_elem($2, METHOD_O, 0, RVE_ST, $3);}
1844         | METHOD strop %prec EQUAL_T ID
1845                 {$$ = mk_elem($2, METHOD_O, 0, STRING_ST,$3); }
1846         | METHOD strop error { $$=0; yyerror("string expected"); }
1847         | METHOD error  
1848                 { $$=0; yyerror("invalid operator,== , !=, or =~ expected"); }
1849         | uri_type strop %prec EQUAL_T rval_expr
1850                 {$$ = mk_elem($2, $1, 0, RVE_ST, $3); }
1851         | uri_type strop %prec EQUAL_T MYSELF
1852                 {$$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
1853         | uri_type strop %prec EQUAL_T error
1854                 { $$=0; yyerror("string or MYSELF expected"); }
1855         | uri_type error
1856                 { $$=0; yyerror("invalid operator, == , != or =~ expected"); }
1857         | eint_op cmpop %prec GT rval_expr { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
1858         | eint_op equalop %prec EQUAL_T rval_expr 
1859                 { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
1860         | eint_op cmpop error   { $$=0; yyerror("number expected"); }
1861         | eint_op equalop error { $$=0; yyerror("number expected"); }
1862         | eint_op error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
1863         | PROTO equalop %prec EQUAL_T proto
1864                 { $$=mk_elem($2, PROTO_O, 0, NUMBER_ST, (void*)$3 ); }
1865         | PROTO equalop %prec EQUAL_T rval_expr
1866                 { $$=mk_elem($2, PROTO_O, 0, RVE_ST, $3 ); }
1867         | PROTO equalop error
1868                 { $$=0; yyerror("protocol expected (udp, tcp, tls or sctp)"); }
1869         | SNDPROTO equalop %prec EQUAL_T proto
1870                 { $$=mk_elem($2, SNDPROTO_O, 0, NUMBER_ST, (void*)$3 ); }
1871         | SNDPROTO equalop %prec EQUAL_T rval_expr
1872                 { $$=mk_elem($2, SNDPROTO_O, 0, RVE_ST, $3 ); }
1873         | SNDPROTO equalop error
1874                 { $$=0; yyerror("protocol expected (udp, tcp, tls or sctp)"); }
1875         | eip_op strop %prec EQUAL_T ipnet { $$=mk_elem($2, $1, 0, NET_ST, $3); }
1876         | eip_op strop %prec EQUAL_T rval_expr {
1877                         s_tmp.s=0;
1878                         $$=0;
1879                         if (rve_is_constant($3)){
1880                                 i_tmp=rve_guess_type($3);
1881                                 if (i_tmp==RV_INT)
1882                                         yyerror("string expected");
1883                                 else if (i_tmp==RV_STR){
1884                                         if (((rval_tmp=rval_expr_eval(0, 0, $3))==0) ||
1885                                                                 (rval_get_str(0, 0, &s_tmp, rval_tmp, 0)<0)){
1886                                                 rval_destroy(rval_tmp);
1887                                                 yyerror("bad rvalue expression");
1888                                         }else{
1889                                                 rval_destroy(rval_tmp);
1890                                         }
1891                                 }else{
1892                                         yyerror("BUG: unexpected dynamic type");
1893                                 }
1894                         }else{
1895                                         warn("non constant rvalue in ip comparison");
1896                         }
1897                         if (s_tmp.s){
1898                                 ip_tmp=str2ip(&s_tmp);
1899                         #ifdef USE_IPV6
1900                                 if (ip_tmp==0)
1901                                         ip_tmp=str2ip6(&s_tmp);
1902                         #endif
1903                                 pkg_free(s_tmp.s);
1904                                 if (ip_tmp) {
1905                                         $$=mk_elem($2, $1, 0, NET_ST, 
1906                                                                 mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
1907                                 } else {
1908                                         $$=mk_elem($2, $1, 0, RVE_ST, $3);
1909                                 }
1910                         }else{
1911                                 $$=mk_elem($2, $1, 0, RVE_ST, $3);
1912                         }
1913                 }
1914         | eip_op strop %prec EQUAL_T host
1915                 { $$=mk_elem($2, $1, 0, STRING_ST, $3); }
1916         | eip_op strop %prec EQUAL_T MYSELF
1917                 { $$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
1918         | eip_op strop %prec EQUAL_T error
1919                 { $$=0; yyerror( "ip address or hostname expected" ); }
1920         | eip_op error
1921                 { $$=0; yyerror("invalid operator, ==, != or =~ expected");}
1922         
1923         | MYSELF equalop %prec EQUAL_T uri_type
1924                 { $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
1925         | MYSELF equalop %prec EQUAL_T eip_op
1926                 { $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
1927         | MYSELF equalop %prec EQUAL_T error
1928                 { $$=0; yyerror(" URI, SRCIP or DSTIP expected"); }
1929         | MYSELF error  { $$=0; yyerror ("invalid operator, == or != expected"); }
1930         ;
1931 /*
1932 exp_elem2:
1933         rval_expr cmpop %prec GT rval_expr
1934                 { $$=mk_elem( $2, RVE_ST, $1, RVE_ST, $3);}
1935         |
1936         rval_expr equalop %prec EQUAL_T rval_expr
1937                 { $$=mk_elem( $2, RVE_ST, $1, RVE_ST, $3);}
1938         | rval_expr LOG_AND rval_expr
1939                 { $$=mk_exp_rve(LOGAND_OP, $1, $3);}
1940         | rval_expr LOG_OR rval_expr
1941                 { $$=mk_exp_rve(LOGOR_OP, $1, $3);}
1942 ;
1943 */
1944
1945 ipnet:
1946         ip SLASH ip     { $$=mk_net($1, $3); }
1947         | ip SLASH NUMBER {
1948                 if (($3<0) || ($3>$1->len*8)) {
1949                         yyerror("invalid bit number in netmask");
1950                         $$=0;
1951                 } else {
1952                         $$=mk_net_bitlen($1, $3);
1953                 /*
1954                         $$=mk_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
1955                 */
1956                 }
1957         }
1958         | ip    { $$=mk_net_bitlen($1, $1->len*8); }
1959         | ip SLASH error { $$=0; yyerror("netmask (eg:255.0.0.0 or 8) expected"); }
1960         ;
1961
1962 host:
1963         ID { $$=$1; }
1964         | host DOT ID {
1965                 if ($1){
1966                         $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1967                         if ($$==0) {
1968                                 LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
1969                                                         " failure while parsing host\n");
1970                         } else {
1971                                 memcpy($$, $1, strlen($1));
1972                                 $$[strlen($1)]='.';
1973                                 memcpy($$+strlen($1)+1, $3, strlen($3));
1974                                 $$[strlen($1)+1+strlen($3)]=0;
1975                         }
1976                         pkg_free($1);
1977                 }
1978                 if ($3) pkg_free($3);
1979         }
1980         | host MINUS ID {
1981                 if ($1){
1982                         $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1983                         if ($$==0) {
1984                                 LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
1985                                                         " failure while parsing host\n");
1986                         } else {
1987                                 memcpy($$, $1, strlen($1));
1988                                 $$[strlen($1)]='-';
1989                                 memcpy($$+strlen($1)+1, $3, strlen($3));
1990                                 $$[strlen($1)+1+strlen($3)]=0;
1991                         }
1992                         pkg_free($1);
1993                 }
1994                 if ($3) pkg_free($3);
1995         }
1996         | host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
1997         | host MINUS error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
1998         ;
1999
2000 host_if_id: ID
2001                 | NUM_ID
2002                 | NUMBER {
2003                         /* get string version */
2004                         $$=pkg_malloc(strlen(yy_number_str)+1);
2005                         if ($$)
2006                                 strcpy($$, yy_number_str);
2007                 }
2008                 ;
2009
2010 host_or_if:
2011         host_if_id { $$=$1; }
2012         | host_or_if DOT host_if_id {
2013                 if ($1){
2014                         $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
2015                         if ($$==0) {
2016                                 LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
2017                                                         " failure while parsing host/interface name\n");
2018                         } else {
2019                                 memcpy($$, $1, strlen($1));
2020                                 $$[strlen($1)]='.';
2021                                 memcpy($$+strlen($1)+1, $3, strlen($3));
2022                                 $$[strlen($1)+1+strlen($3)]=0;
2023                         }
2024                         pkg_free($1);
2025                 }
2026                 if ($3) pkg_free($3);
2027         }
2028         | host_or_if MINUS host_if_id {
2029                 if ($1){
2030                         $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
2031                         if ($$==0) {
2032                                 LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
2033                                                         " failure while parsing host/interface name\n");
2034                         } else {
2035                                 memcpy($$, $1, strlen($1));
2036                                 $$[strlen($1)]='-';
2037                                 memcpy($$+strlen($1)+1, $3, strlen($3));
2038                                 $$[strlen($1)+1+strlen($3)]=0;
2039                         }
2040                         pkg_free($1);
2041                 }
2042                 if ($3) pkg_free($3);
2043         }
2044         | host_or_if DOT error { $$=0; pkg_free($1);
2045                                                                 yyerror("invalid host or interface name"); }
2046         | host_or_if MINUS error { $$=0; pkg_free($1);
2047                                                                 yyerror("invalid host or interface name"); }
2048         ;
2049
2050
2051 /* filtered cmd */
2052 fcmd:
2053         cmd {
2054                 /* check if allowed */
2055                 if ($1 && rt==ONSEND_ROUTE) {
2056                         switch($1->type) {
2057                                 case DROP_T:
2058                                 case SEND_T:
2059                                 case SEND_TCP_T:
2060                                 case LOG_T:
2061                                 case SETFLAG_T:
2062                                 case RESETFLAG_T:
2063                                 case ISFLAGSET_T:
2064                                 case IF_T:
2065                                 case MODULE_T:
2066                                 case SET_FWD_NO_CONNECT_T:
2067                                 case SET_RPL_NO_CONNECT_T:
2068                                 case SET_FWD_CLOSE_T:
2069                                 case SET_RPL_CLOSE_T:
2070                                         $$=$1;
2071                                         break;
2072                                 default:
2073                                         $$=0;
2074                                         yyerror("command not allowed in onsend_route\n");
2075                         }
2076                 } else {
2077                         $$=$1;
2078                 }
2079         }
2080         ;
2081 /*
2082 exp_stm:
2083         fcmd    { $$=$1; }
2084         | if_cmd        { $$=$1; }
2085         | assign_action { $$ = $1; }
2086         | LBRACE actions RBRACE { $$=$2; }
2087         ;
2088 */
2089 stm:
2090         action  { $$=$1; }
2091         | LBRACE actions RBRACE { $$=$2; }
2092         ;
2093 actions:
2094         actions action  {$$=append_action($1, $2); }
2095         | action        {$$=$1;}
2096         | actions error { $$=0; yyerror("bad command"); }
2097         ;
2098 action:
2099         fcmd SEMICOLON {$$=$1;}
2100         | if_cmd {$$=$1;}
2101         | switch_cmd {$$=$1;}
2102         | while_cmd { $$=$1; }
2103         | ret_cmd SEMICOLON { $$=$1; }
2104         | assign_action SEMICOLON {$$=$1;}
2105         | SEMICOLON /* null action */ {$$=0;}
2106         | fcmd error { $$=0; yyerror("bad command: missing ';'?"); }
2107         ;
2108 if_cmd:
2109         IF rval_expr stm        {
2110                 if ($2 && rval_expr_int_check($2)>=0){
2111                         warn_ct_rve($2, "if");
2112                         $$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, NOSUBTYPE, 0);
2113                         set_cfg_pos($$);
2114                 }else
2115                         YYERROR;
2116         }
2117         | IF rval_expr stm ELSE stm     { 
2118                 if ($2 && rval_expr_int_check($2)>=0){
2119                         warn_ct_rve($2, "if");
2120                         $$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, ACTIONS_ST, $5);
2121                         set_cfg_pos($$);
2122                 }else
2123                         YYERROR;
2124         }
2125         ;
2126
2127 ct_rval: rval_expr {
2128                         $$=0;
2129                         if (!rve_is_constant($1)){
2130                                 yyerror("constant expected");
2131                         /*
2132                         } else if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
2133                                 yyerror("invalid expression (bad type)");
2134                         }else if (i_tmp!=RV_INT){
2135                                 yyerror("invalid expression type, int expected\n");
2136                         */
2137                         }else
2138                                 $$=$1;
2139                 }
2140 ;
2141 single_case:
2142         CASE ct_rval COLON actions {
2143                 $$=0;
2144                 if ($2==0) yyerror ("bad case label");
2145                 else if ((($$=mk_case_stm($2, 0, $4, &i_tmp))==0) && (i_tmp==-10)){
2146                                 YYABORT;
2147                 }
2148         }
2149 | CASE SLASH ct_rval COLON actions {
2150                 $$=0;
2151                 if ($3==0) yyerror ("bad case label");
2152                 else if ((($$=mk_case_stm($3, 1, $5, &i_tmp))==0) && (i_tmp==-10)){
2153                                 YYABORT;
2154                 }
2155         }
2156         | CASE ct_rval COLON {
2157                 $$=0;
2158                 if ($2==0) yyerror ("bad case label");
2159                 else if ((($$=mk_case_stm($2, 0, 0, &i_tmp))==0) && (i_tmp==-10)){
2160                                 YYABORT;
2161                 }
2162         }
2163         | CASE SLASH ct_rval COLON {
2164                 $$=0;
2165                 if ($3==0) yyerror ("bad case label");
2166                 else if ((($$=mk_case_stm($3, 1, 0, &i_tmp))==0) && (i_tmp==-10)){
2167                                 YYABORT;
2168                 }
2169         }
2170         | DEFAULT COLON actions {
2171                 if ((($$=mk_case_stm(0, 0, $3, &i_tmp))==0) && (i_tmp=-10)){
2172                                 YYABORT;
2173                 }
2174         }
2175         | DEFAULT COLON {
2176                 if ((($$=mk_case_stm(0, 0, 0, &i_tmp))==0) && (i_tmp==-10)){
2177                                 YYABORT;
2178                 }
2179         }
2180         | CASE error { $$=0; yyerror("bad case label"); }
2181         | CASE ct_rval COLON error { $$=0; yyerror ("bad case body"); }
2182 ;
2183 case_stms:
2184         case_stms single_case {
2185                 $$=$1;
2186                 if ($2==0) yyerror ("bad case");
2187                 if ($$){
2188                         *($$->append)=$2;
2189                         if (*($$->append)!=0)
2190                                 $$->append=&((*($$->append))->next);
2191                 }
2192         }
2193         | single_case {
2194                 $$=$1;
2195                 if ($1==0) yyerror ("bad case");
2196                 else $$->append=&($$->next);
2197         }
2198 ;
2199 switch_cmd:
2200           SWITCH rval_expr LBRACE case_stms RBRACE { 
2201                 $$=0;
2202                 if ($2==0){
2203                         yyerror("bad expression in switch(...)");
2204                         YYERROR;
2205                 }else if ($4==0){
2206                         yyerror ("bad switch body");
2207                         YYERROR;
2208                 }else if (case_check_default($4)!=0){
2209                         yyerror_at(&$2->fpos, "bad switch(): too many "
2210                                                         "\"default:\" labels\n");
2211                         YYERROR;
2212                 }else if (case_check_type($4)!=0){
2213                         yyerror_at(&$2->fpos, "bad switch(): mixed integer and"
2214                                                         " string/RE cases not allowed\n");
2215                         YYERROR;
2216                 }else{
2217                         $$=mk_action(SWITCH_T, 2, RVE_ST, $2, CASE_ST, $4);
2218                         if ($$==0) {
2219                                 yyerror("internal error");
2220                                 YYABORT;
2221                         }
2222                         set_cfg_pos($$);
2223                 }
2224         }
2225         | SWITCH rval_expr LBRACE RBRACE {
2226                 $$=0;
2227                 warn("empty switch()");
2228                 if ($2==0){
2229                         yyerror("bad expression in switch(...)");
2230                         YYERROR;
2231                 }else{
2232                         /* it might have sideffects, so leave it for the optimizer */
2233                         $$=mk_action(SWITCH_T, 2, RVE_ST, $2, CASE_ST, 0);
2234                         if ($$==0) {
2235                                 yyerror("internal error");
2236                                 YYABORT;
2237                         }
2238                         set_cfg_pos($$);
2239                 }
2240         }
2241         | SWITCH error { $$=0; yyerror ("bad expression in switch(...)"); }
2242         | SWITCH rval_expr LBRACE error RBRACE 
2243                 {$$=0; yyerror ("bad switch body"); }
2244 ;
2245
2246 while_cmd:
2247         WHILE rval_expr stm {
2248                 if ($2 && rval_expr_int_check($2)>=0){
2249                         warn_ct_rve($2, "while");
2250                         $$=mk_action( WHILE_T, 2, RVE_ST, $2, ACTIONS_ST, $3);
2251                         set_cfg_pos($$);
2252                 }else{
2253                         yyerror_at(&$2->fpos, "bad while(...) expression");
2254                         YYERROR;
2255                 }
2256         }
2257 ;
2258
2259 /* class_id:
2260         LBRACK ATTR_USER RBRACK { $$ = AVP_CLASS_USER; }
2261         | LBRACK ATTR_DOMAIN RBRACK { $$ = AVP_CLASS_DOMAIN; }
2262         | LBRACK ATTR_GLOBAL RBRACK { $$ = AVP_CLASS_GLOBAL; }
2263         ;
2264 */
2265 select_param:
2266         ID {
2267                 if (sel.n >= MAX_SELECT_PARAMS-1) {
2268                         yyerror("Select identifier too long\n");
2269                 }
2270                 sel.params[sel.n].type = SEL_PARAM_STR;
2271                 sel.params[sel.n].v.s.s = $1;
2272                 sel.params[sel.n].v.s.len = strlen($1);
2273                 sel.n++;
2274         }
2275         | ID LBRACK intno RBRACK {
2276                 if (sel.n >= MAX_SELECT_PARAMS-2) {
2277                         yyerror("Select identifier too long\n");
2278                 }
2279                 sel.params[sel.n].type = SEL_PARAM_STR;
2280                 sel.params[sel.n].v.s.s = $1;
2281                 sel.params[sel.n].v.s.len = strlen($1);
2282                 sel.n++;
2283                 sel.params[sel.n].type = SEL_PARAM_INT;
2284                 sel.params[sel.n].v.i = $3;
2285                 sel.n++;
2286         }
2287         | ID LBRACK STRING RBRACK {
2288                 if (sel.n >= MAX_SELECT_PARAMS-2) {
2289                         yyerror("Select identifier too long\n");
2290                 }
2291                 sel.params[sel.n].type = SEL_PARAM_STR;
2292                 sel.params[sel.n].v.s.s = $1;
2293                 sel.params[sel.n].v.s.len = strlen($1);
2294                 sel.n++;
2295                 sel.params[sel.n].type = SEL_PARAM_STR;
2296                 sel.params[sel.n].v.s.s = $3;
2297                 sel.params[sel.n].v.s.len = strlen($3);
2298                 sel.n++;
2299         }
2300         ;
2301 select_params:
2302         select_params DOT select_param
2303         | select_param
2304         ;
2305 select_id:
2306         SELECT_MARK { sel.n = 0; sel.f[0] = 0; } select_params {
2307                 sel_ptr = (select_t*)pkg_malloc(sizeof(select_t));
2308                 if (!sel_ptr) {
2309                         yyerror("No memory left to allocate select structure\n");
2310                 }
2311                 memcpy(sel_ptr, &sel, sizeof(select_t));
2312                 $$ = sel_ptr;
2313         }
2314         ;
2315 attr_class_spec:
2316         ATTR_FROM { s_attr->type |= AVP_TRACK_FROM; }
2317         | ATTR_TO { s_attr->type |= AVP_TRACK_TO; }
2318         | ATTR_FROMURI { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_URI; }
2319         | ATTR_TOURI { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_URI; }
2320         | ATTR_FROMUSER { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_USER; }
2321         | ATTR_TOUSER { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_USER; }
2322         | ATTR_FROMDOMAIN { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_DOMAIN; }
2323         | ATTR_TODOMAIN { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_DOMAIN; }
2324         | ATTR_GLOBAL { s_attr->type |= AVP_TRACK_ALL | AVP_CLASS_GLOBAL; }
2325         ;
2326 attr_name_spec:
2327         ID { s_attr->type |= AVP_NAME_STR; s_attr->name.s.s = $1; s_attr->name.s.len = strlen ($1); }
2328         ;
2329 attr_spec:
2330         attr_name_spec
2331         | attr_class_spec DOT attr_name_spec
2332         ;
2333 attr_mark:
2334         ATTR_MARK {
2335                 s_attr = (struct avp_spec*)pkg_malloc(sizeof(struct avp_spec));
2336                 if (!s_attr) { yyerror("No memory left"); YYABORT; }
2337                 else s_attr->type = 0;
2338         }
2339         ;
2340 attr_id:
2341         attr_mark attr_spec { $$ = s_attr; }
2342         ;
2343 attr_id_num_idx:
2344         attr_mark attr_spec LBRACK intno RBRACK {
2345                 s_attr->type|= (AVP_NAME_STR | ($4<0?AVP_INDEX_BACKWARD:AVP_INDEX_FORWARD));
2346                 s_attr->index = ($4<0?-$4:$4);
2347                 $$ = s_attr;
2348         }
2349         ;
2350 attr_id_no_idx:
2351         attr_mark attr_spec LBRACK RBRACK {
2352                 s_attr->type|= AVP_INDEX_ALL;
2353                 $$ = s_attr;
2354         }
2355         ;
2356 attr_id_ass:
2357         attr_id
2358         | attr_id_no_idx
2359         ;
2360 /*
2361 attr_id_val:
2362         attr_id
2363         | attr_id_num_idx
2364         ;
2365 */
2366 attr_id_any:
2367         attr_id
2368         | attr_id_no_idx
2369         | attr_id_num_idx
2370 ;
2371 attr_id_any_str:
2372         attr_id
2373         | avp_pvar {
2374                 if ($1->type==LV_AVP){
2375                         s_attr = pkg_malloc(sizeof(struct avp_spec));
2376                         if (!s_attr) { yyerror("No memory left"); YYABORT; }
2377                         else{
2378                                 *s_attr=$1->lv.avps;
2379                         }
2380                         $$=s_attr;
2381                 }else
2382                         $$=0; /* not an avp, a pvar */
2383                 pkg_free($1);
2384         }
2385         | STRING {
2386                 avp_spec_t *avp_spec;
2387                 str s;
2388                 int type, idx;
2389                 avp_spec = pkg_malloc(sizeof(*avp_spec));
2390                 if (!avp_spec) {
2391                         yyerror("Not enough memory");
2392                         YYABORT;
2393                 }
2394                 s.s = $1;
2395                 if (s.s[0] == '$')
2396                         s.s++;
2397                 s.len = strlen(s.s);
2398                 if (parse_avp_name(&s, &type, &avp_spec->name, &idx)) {
2399                         yyerror("error when parsing AVP");
2400                         pkg_free(avp_spec);
2401                         YYABORT;
2402                 }
2403                 avp_spec->type = type;
2404                 avp_spec->index = idx;
2405                 $$ = avp_spec;
2406         }
2407         ;
2408
2409 pvar:   PVAR {
2410                         pv_spec=pkg_malloc(sizeof(*pv_spec));
2411                         if (!pv_spec) {
2412                                 yyerror("Not enough memory");
2413                                 YYABORT;
2414                         }
2415                         memset(pv_spec, 0, sizeof(*pv_spec));
2416                         s_tmp.s=$1; s_tmp.len=strlen($1);
2417                         if (pv_parse_spec(&s_tmp, pv_spec)==0){
2418                                 yyerror("unknown script pseudo variable");
2419                                 pkg_free(pv_spec);
2420                                 pv_spec=0;
2421                                 YYABORT;
2422                         }
2423                         $$=pv_spec;
2424                 }
2425         ;
2426
2427 avp_pvar:       AVP_OR_PVAR {
2428                                 lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2429                                 if (!lval_tmp) {
2430                                         yyerror("Not enough memory");
2431                                         YYABORT;
2432                                 }
2433                                 memset(lval_tmp, 0, sizeof(*lval_tmp));
2434                                 s_tmp.s=$1; s_tmp.len=strlen(s_tmp.s);
2435                                 if (pv_parse_spec2(&s_tmp, &lval_tmp->lv.pvs, 1)==0){
2436                                         /* not a pvar, try avps */
2437                                         lval_tmp->lv.avps.type|= AVP_NAME_STR;
2438                                         lval_tmp->lv.avps.name.s.s = s_tmp.s+1;
2439                                         lval_tmp->lv.avps.name.s.len = s_tmp.len-1;
2440                                         lval_tmp->type=LV_AVP;
2441                                 }else{
2442                                         lval_tmp->type=LV_PVAR;
2443                                 }
2444                                 $$ = lval_tmp;
2445                                 DBG("parsed ambigous avp/pvar \"%.*s\" to %d\n",
2446                                                         s_tmp.len, s_tmp.s, lval_tmp->type);
2447                         }
2448         ;
2449
2450
2451 /*
2452 assign_op:
2453         ADDEQ { $$ = ADD_T; }
2454         | EQUAL { $$ = ASSIGN_T; }
2455         ;
2456 */
2457 assign_op:
2458         EQUAL { $$ = ASSIGN_T; }
2459         ;
2460
2461
2462 lval: attr_id_ass {
2463                                         lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2464                                         if (!lval_tmp) {
2465                                                 yyerror("Not enough memory");
2466                                                 YYABORT;
2467                                         }
2468                                         lval_tmp->type=LV_AVP; lval_tmp->lv.avps=*$1;
2469                                         pkg_free($1); /* free the avp spec we just copied */
2470                                         $$=lval_tmp;
2471                                 }
2472         | pvar        {
2473                                         if (!pv_is_w($1))
2474                                                 yyerror("read only pvar in assignment left side");
2475                                         if ($1->trans!=0)
2476                                                 yyerror("pvar with transformations in assignment"
2477                                                                 " left side");
2478                                         lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2479                                         if (!lval_tmp) {
2480                                                 yyerror("Not enough memory");
2481                                                 YYABORT;
2482                                         }
2483                                         lval_tmp->type=LV_PVAR; lval_tmp->lv.pvs=*($1);
2484                                         pkg_free($1); /* free the pvar spec we just copied */
2485                                         $$=lval_tmp;
2486                                 }
2487         | avp_pvar    {
2488                                         if (($1)->type==LV_PVAR){
2489                                                 if (!pv_is_w(&($1)->lv.pvs))
2490                                                         yyerror("read only pvar in assignment left side");
2491                                                 if ($1->lv.pvs.trans!=0)
2492                                                         yyerror("pvar with transformations in assignment"
2493                                                                         " left side");
2494                                         }
2495                                         $$=$1;
2496                                 }
2497         ;
2498
2499 rval: intno                     {$$=mk_rve_rval(RV_INT, (void*)$1); }
2500         | STRING                        {       s_tmp.s=$1; s_tmp.len=strlen($1);
2501                                                         $$=mk_rve_rval(RV_STR, &s_tmp); }
2502         | attr_id_any           {$$=mk_rve_rval(RV_AVP, $1); pkg_free($1); }
2503         | pvar                          {$$=mk_rve_rval(RV_PVAR, $1); pkg_free($1); }
2504         | avp_pvar                      {
2505                                                         switch($1->type){
2506                                                                 case LV_AVP:
2507                                                                         $$=mk_rve_rval(RV_AVP, &$1->lv.avps);
2508                                                                         break;
2509                                                                 case LV_PVAR:
2510                                                                         $$=mk_rve_rval(RV_PVAR, &$1->lv.pvs);
2511                                                                         break;
2512                                                                 default:
2513                                                                         yyerror("BUG: invalid lvalue type ");
2514                                                                         YYABORT;
2515                                                         }
2516                                                         pkg_free($1); /* not needed anymore */
2517                                                 }
2518         | select_id                     {$$=mk_rve_rval(RV_SEL, $1); pkg_free($1); }
2519         | fcmd                          {$$=mk_rve_rval(RV_ACTION_ST, $1); }
2520         | exp_elem { $$=mk_rve_rval(RV_BEXPR, $1); }
2521         | LBRACE actions RBRACE {$$=mk_rve_rval(RV_ACTION_ST, $2); }
2522         | LBRACE error RBRACE   { $$=0; yyerror("bad command block"); }
2523         | LPAREN assign_action RPAREN   {$$=mk_rve_rval(RV_ACTION_ST, $2); }
2524         | LPAREN error RPAREN   { $$=0; yyerror("bad expression"); }
2525         ;
2526
2527
2528 rve_un_op: NOT  { $$=RVE_LNOT_OP; }
2529                 |  MINUS %prec NOT      { $$=RVE_UMINUS_OP; } 
2530                 /* TODO: RVE_BOOL_OP, RVE_NOT_OP? */
2531         ;
2532
2533 /*
2534 rve_op:         PLUS            { $$=RVE_PLUS_OP; }
2535                 |       MINUS           { $$=RVE_MINUS_OP; }
2536                 |       STAR            { $$=RVE_MUL_OP; }
2537                 |       SLASH           { $$=RVE_DIV_OP; }
2538                 |       MODULO          { $$=RVE_MOD_OP; }
2539         ;
2540 */
2541
2542 rval_expr: rval                                         { $$=$1;
2543                                                                                 if ($$==0){
2544                                                                                         /*yyerror("out of memory\n");*/
2545                                                                                         YYERROR;
2546                                                                                 }
2547                                                                         }
2548                 | rve_un_op %prec NOT rval_expr {$$=mk_rve1($1, $2); }
2549                 | INTCAST rval_expr                             {$$=mk_rve1(RVE_INT_OP, $2); }
2550                 | STRCAST rval_expr                             {$$=mk_rve1(RVE_STR_OP, $2); }
2551                 | rval_expr PLUS rval_expr              {$$=mk_rve2(RVE_PLUS_OP, $1, $3); }
2552                 | rval_expr MINUS rval_expr             {$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
2553                 | rval_expr STAR rval_expr              {$$=mk_rve2(RVE_MUL_OP, $1, $3); }
2554                 | rval_expr SLASH rval_expr             {$$=mk_rve2(RVE_DIV_OP, $1, $3); }
2555                 | rval_expr MODULO rval_expr    {$$=mk_rve2(RVE_MOD_OP, $1, $3); }
2556                 | rval_expr BIN_OR rval_expr    {$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
2557                 | rval_expr BIN_AND rval_expr   {$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
2558                 | rval_expr rve_cmpop %prec GT rval_expr { $$=mk_rve2( $2, $1, $3);}
2559                 | rval_expr rve_equalop %prec EQUAL_T rval_expr
2560                         { $$=mk_rve2( $2, $1, $3);}
2561                 | rval_expr LOG_AND rval_expr   { $$=mk_rve2(RVE_LAND_OP, $1, $3);}
2562                 | rval_expr LOG_OR rval_expr    { $$=mk_rve2(RVE_LOR_OP, $1, $3);}
2563                 | LPAREN rval_expr RPAREN               { $$=$2;}
2564                 | STRLEN LPAREN rval_expr RPAREN { $$=mk_rve1(RVE_STRLEN_OP, $3);}
2565                 | STREMPTY LPAREN rval_expr RPAREN {$$=mk_rve1(RVE_STREMPTY_OP, $3);}
2566                 | DEFINED rval_expr                             { $$=mk_rve1(RVE_DEFINED_OP, $2);}
2567                 | rve_un_op %prec NOT error             { $$=0; yyerror("bad expression"); }
2568                 | INTCAST error                                 { $$=0; yyerror("bad expression"); }
2569                 | STRCAST error                                 { $$=0; yyerror("bad expression"); }
2570                 | rval_expr PLUS error                  { $$=0; yyerror("bad expression"); }
2571                 | rval_expr MINUS error                 { $$=0; yyerror("bad expression"); }
2572                 | rval_expr STAR error                  { $$=0; yyerror("bad expression"); }
2573                 | rval_expr SLASH error                 { $$=0; yyerror("bad expression"); }
2574                 | rval_expr MODULO error                        { $$=0; yyerror("bad expression"); }
2575                 | rval_expr BIN_OR error                { $$=0; yyerror("bad expression"); }
2576                 | rval_expr BIN_AND error               { $$=0; yyerror("bad expression"); }
2577                 | rval_expr rve_cmpop %prec GT error
2578                         { $$=0; yyerror("bad expression"); }
2579                 | rval_expr rve_equalop %prec EQUAL_T error
2580                         { $$=0; yyerror("bad expression"); }
2581                 | rval_expr LOG_AND error               { $$=0; yyerror("bad expression"); }
2582                 | rval_expr LOG_OR error                { $$=0; yyerror("bad expression"); }
2583                 | STRLEN LPAREN error RPAREN    { $$=0; yyerror("bad expression"); }
2584                 | STREMPTY LPAREN error RPAREN  { $$=0; yyerror("bad expression"); }
2585                 | DEFINED error                                 { $$=0; yyerror("bad expression"); }
2586                 ;
2587
2588 assign_action: lval assign_op  rval_expr        { $$=mk_action($2, 2, LVAL_ST, $1, 
2589                                                                                                                           RVE_ST, $3);
2590                                                                                         set_cfg_pos($$);
2591                                                                                 }
2592         ;
2593
2594 /*
2595 assign_action:
2596         attr_id_ass assign_op STRING  { $$=mk_action($2, 2, AVP_ST, $1, STRING_ST, $3); }
2597         | attr_id_ass assign_op NUMBER  { $$=mk_action($2, 2, AVP_ST, $1, NUMBER_ST, (void*)$3); }
2598         | attr_id_ass assign_op fcmd    { $$=mk_action($2, 2, AVP_ST, $1, ACTION_ST, $3); }
2599         | attr_id_ass assign_op attr_id_any { $$=mk_action($2, 2, AVP_ST, $1, AVP_ST, $3); }
2600         | attr_id_ass assign_op select_id { $$=mk_action($2, 2, AVP_ST, (void*)$1, SELECT_ST, (void*)$3); }
2601         | attr_id_ass assign_op LPAREN exp RPAREN { $$ = mk_action($2, 2, AVP_ST, $1, EXPR_ST, $4); }
2602         ;
2603 */
2604
2605 avpflag_oper:
2606         SETAVPFLAG { $$ = 1; }
2607         | RESETAVPFLAG { $$ = 0; }
2608         | ISAVPFLAGSET { $$ = -1; }
2609         ;
2610 cmd:
2611         FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2612         | FORWARD LPAREN STRING RPAREN  { $$=mk_action( FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2613         | FORWARD LPAREN ip RPAREN      { $$=mk_action( FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
2614         | FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2615         | FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2616         | FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2617         | FORWARD LPAREN URIHOST COMMA URIPORT RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
2618         | FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2619         | FORWARD LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$); }
2620         | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
2621         | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward argument"); }
2622         | FORWARD_UDP LPAREN host RPAREN        { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2623         | FORWARD_UDP LPAREN STRING RPAREN      { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2624         | FORWARD_UDP LPAREN ip RPAREN  { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
2625         | FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2626         | FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2627         | FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2628         | FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
2629         | FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2630         | FORWARD_UDP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$); }
2631         | FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
2632         | FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp argument"); }
2633         | FORWARD_TCP LPAREN host RPAREN        { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2634         | FORWARD_TCP LPAREN STRING RPAREN      { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2635         | FORWARD_TCP LPAREN ip RPAREN  { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
2636         | FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2637         | FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2638         | FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2639         | FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
2640         | FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2641         | FORWARD_TCP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$); }
2642         | FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
2643         | FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp argument"); }
2644         | FORWARD_TLS LPAREN host RPAREN {
2645                 #ifdef USE_TLS
2646                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
2647                 #else
2648                         $$=0;
2649                         yyerror("tls support not compiled in");
2650                 #endif
2651         }
2652         | FORWARD_TLS LPAREN STRING RPAREN {
2653                 #ifdef USE_TLS
2654                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
2655                 #else
2656                         $$=0;
2657                         yyerror("tls support not compiled in");
2658                 #endif
2659         }
2660         | FORWARD_TLS LPAREN ip RPAREN  {
2661                 #ifdef USE_TLS
2662                         $$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$);
2663                 #else
2664                         $$=0;
2665                         yyerror("tls support not compiled in");
2666                 #endif
2667         }
2668         | FORWARD_TLS LPAREN host COMMA NUMBER RPAREN {
2669                 #ifdef USE_TLS
2670                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
2671                 #else
2672                         $$=0;
2673                         yyerror("tls support not compiled in");
2674                 #endif
2675         }
2676         | FORWARD_TLS LPAREN STRING COMMA NUMBER RPAREN {
2677                 #ifdef USE_TLS
2678                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
2679                 #else
2680                         $$=0;
2681                         yyerror("tls support not compiled in");
2682                 #endif
2683         }
2684         | FORWARD_TLS LPAREN ip COMMA NUMBER RPAREN {
2685                 #ifdef USE_TLS
2686                         $$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
2687                 #else
2688                         $$=0;
2689                         yyerror("tls support not compiled in");
2690                 #endif
2691                                         }
2692         | FORWARD_TLS LPAREN URIHOST COMMA URIPORT RPAREN {
2693                 #ifdef USE_TLS
2694                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$);
2695                 #else
2696                         $$=0;
2697                         yyerror("tls support not compiled in");
2698                 #endif
2699         }
2700         | FORWARD_TLS LPAREN URIHOST COMMA NUMBER RPAREN {
2701                 #ifdef USE_TLS
2702                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); set_cfg_pos($$);
2703                 #else
2704                         $$=0;
2705                         yyerror("tls support not compiled in");
2706                 #endif
2707         }
2708         | FORWARD_TLS LPAREN URIHOST RPAREN {
2709                 #ifdef USE_TLS
2710                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$);
2711                 #else
2712                         $$=0;
2713                         yyerror("tls support not compiled in");
2714                 #endif
2715         }
2716         | FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
2717         | FORWARD_TLS LPAREN error RPAREN { $$=0; 
2718                                                                         yyerror("bad forward_tls argument"); }
2719         | FORWARD_SCTP LPAREN host RPAREN {
2720                 #ifdef USE_SCTP
2721                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
2722                 #else
2723                         $$=0;
2724                         yyerror("sctp support not compiled in");
2725                 #endif
2726         }
2727         | FORWARD_SCTP LPAREN STRING RPAREN {
2728                 #ifdef USE_SCTP
2729                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$);
2730                 #else
2731                         $$=0;
2732                         yyerror("sctp support not compiled in");
2733                 #endif
2734         }
2735         | FORWARD_SCTP LPAREN ip RPAREN {
2736                 #ifdef USE_SCTP
2737                         $$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$);
2738                 #else
2739                         $$=0;
2740                         yyerror("sctp support not compiled in");
2741                 #endif
2742         }
2743         | FORWARD_SCTP LPAREN host COMMA NUMBER RPAREN {
2744                 #ifdef USE_SCTP
2745                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2746                                                         (void*)$5); set_cfg_pos($$);
2747                 #else
2748                         $$=0;
2749                         yyerror("sctp support not compiled in");
2750                 #endif
2751         }
2752         | FORWARD_SCTP LPAREN STRING COMMA NUMBER RPAREN {
2753                 #ifdef USE_SCTP
2754                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2755                                                         (void*)$5); set_cfg_pos($$);
2756                 #else
2757                         $$=0;
2758                         yyerror("sctp support not compiled in");
2759                 #endif
2760         }
2761         | FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
2762                 #ifdef USE_SCTP
2763                         $$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 
2764                                                         (void*)$5); set_cfg_pos($$);
2765                 #else
2766                         $$=0;
2767                         yyerror("sctp support not compiled in");
2768                 #endif
2769                                         }
2770         | FORWARD_SCTP LPAREN URIHOST COMMA URIPORT RPAREN {
2771                 #ifdef USE_SCTP
2772                         $$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$);
2773                 #else
2774                         $$=0;
2775                         yyerror("sctp support not compiled in");
2776                 #endif
2777         }
2778         | FORWARD_SCTP LPAREN URIHOST COMMA NUMBER RPAREN {
2779                 #ifdef USE_SCTP
2780                         $$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST,
2781                                                         (void*)$5); set_cfg_pos($$);
2782                 #else
2783                         $$=0;
2784                         yyerror("sctp support not compiled in");
2785                 #endif
2786         }
2787         | FORWARD_SCTP LPAREN URIHOST RPAREN {
2788                 #ifdef USE_SCTP
2789                         $$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); set_cfg_pos($$);
2790                 #else
2791                         $$=0;
2792                         yyerror("tls support not compiled in");
2793                 #endif
2794         }
2795         | FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
2796         | FORWARD_SCTP LPAREN error RPAREN { $$=0; 
2797                                                                         yyerror("bad forward_tls argument"); }
2798         | SEND LPAREN host RPAREN       { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2799         | SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2800         | SEND LPAREN ip RPAREN         { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
2801         | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2802         | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2803         | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2804         | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
2805         | SEND LPAREN error RPAREN { $$=0; yyerror("bad send argument"); }
2806         | SEND_TCP LPAREN host RPAREN   { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2807         | SEND_TCP LPAREN STRING RPAREN { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
2808         | SEND_TCP LPAREN ip RPAREN     { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
2809         | SEND_TCP LPAREN host COMMA NUMBER RPAREN      { $$=mk_action( SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);}
2810         | SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2811         | SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
2812         | SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
2813         | SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp argument"); }
2814         | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(LOG_T, 2, NUMBER_ST,
2815                                                                                 (void*)(L_DBG+1), STRING_ST, $3);
2816                                                                         set_cfg_pos($$); }
2817         | LOG_TOK LPAREN NUMBER COMMA STRING RPAREN     {$$=mk_action(LOG_T, 2, NUMBER_ST, (void*)$3, STRING_ST, $5); set_cfg_pos($$); }
2818         | LOG_TOK error                 { $$=0; yyerror("missing '(' or ')' ?"); }
2819         | LOG_TOK LPAREN error RPAREN   { $$=0; yyerror("bad log argument"); }
2820         | SETFLAG LPAREN NUMBER RPAREN  {
2821                                                         if (check_flag($3)==-1)
2822                                                                 yyerror("bad flag value");
2823                                                         $$=mk_action(SETFLAG_T, 1, NUMBER_ST,
2824                                                                                                         (void*)$3);
2825                                                         set_cfg_pos($$);
2826                                                                         }
2827         | SETFLAG LPAREN flag_name RPAREN       {
2828                                                         i_tmp=get_flag_no($3, strlen($3));
2829                                                         if (i_tmp<0) yyerror("flag not declared");
2830                                                         $$=mk_action(SETFLAG_T, 1, NUMBER_ST,
2831                                                                                 (void*)(long)i_tmp);
2832                                                         set_cfg_pos($$);
2833                                                                         }
2834         | SETFLAG error                 { $$=0; yyerror("missing '(' or ')'?"); }
2835         | RESETFLAG LPAREN NUMBER RPAREN {
2836                                                         if (check_flag($3)==-1)
2837                                                                 yyerror("bad flag value");
2838                                                         $$=mk_action(RESETFLAG_T, 1, NUMBER_ST, (void*)$3);
2839                                                         set_cfg_pos($$);
2840                                                                         }
2841         | RESETFLAG LPAREN flag_name RPAREN     {
2842                                                         i_tmp=get_flag_no($3, strlen($3));
2843                                                         if (i_tmp<0) yyerror("flag not declared");
2844                                                         $$=mk_action(RESETFLAG_T, 1, NUMBER_ST,
2845                                                                                 (void*)(long)i_tmp);
2846                                                         set_cfg_pos($$);
2847                                                                         }
2848         | RESETFLAG error               { $$=0; yyerror("missing '(' or ')'?"); }
2849         | ISFLAGSET LPAREN NUMBER RPAREN {
2850                                                         if (check_flag($3)==-1)
2851                                                                 yyerror("bad flag value");
2852                                                         $$=mk_action(ISFLAGSET_T, 1, NUMBER_ST, (void*)$3);
2853                                                         set_cfg_pos($$);
2854                                                                         }
2855         | ISFLAGSET LPAREN flag_name RPAREN     {
2856                                                         i_tmp=get_flag_no($3, strlen($3));
2857                                                         if (i_tmp<0) yyerror("flag not declared");
2858                                                         $$=mk_action(ISFLAGSET_T, 1, NUMBER_ST,
2859                                                                                 (void*)(long)i_tmp);
2860                                                         set_cfg_pos($$);
2861                                                                         }
2862         | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
2863         | avpflag_oper LPAREN attr_id_any_str COMMA flag_name RPAREN {
2864                 i_tmp=get_avpflag_no($5);
2865                 if (i_tmp==0) yyerror("avpflag not declared");
2866                 $$=mk_action(AVPFLAG_OPER_T, 3, AVP_ST, $3, NUMBER_ST, (void*)(long)i_tmp, NUMBER_ST, (void*)$1);
2867                 set_cfg_pos($$);
2868         }
2869         | avpflag_oper LPAREN attr_id_any_str COMMA error RPAREN {
2870                 $$=0; yyerror("error parsing flag name");
2871         }
2872         | avpflag_oper LPAREN error COMMA flag_name RPAREN {
2873                 $$=0; yyerror("error parsing first parameter (avp or string)");
2874         }
2875         | avpflag_oper LPAREN error RPAREN { $$=0; yyerror("bad parameters"); }
2876         | avpflag_oper error { $$=0; yyerror("missing '(' or ')'?"); }
2877         | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T, 2, STRING_ST, $3, STRING_ST, $5);
2878                         set_cfg_pos($$);
2879         }
2880         | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
2881         | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error argument"); }
2882         | ROUTE LPAREN route_name RPAREN        {
2883                                                 i_tmp=route_get(&main_rt, $3);
2884                                                 if (i_tmp==-1){
2885                                                         yyerror("internal error");
2886                                                         YYABORT;
2887                                                 }
2888                                                 $$=mk_action(ROUTE_T, 1, NUMBER_ST,(void*)(long)i_tmp);
2889                                                 set_cfg_pos($$);
2890                                                                                 }
2891         | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
2892         | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route argument"); }
2893         | EXEC LPAREN STRING RPAREN     { $$=mk_action(EXEC_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2894         | SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2895         | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
2896         | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2897         | PREFIX LPAREN STRING RPAREN { $$=mk_action(PREFIX_T, 1, STRING_ST,  $3); set_cfg_pos($$); }
2898         | PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); }
2899         | PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2900         | STRIP_TAIL LPAREN NUMBER RPAREN { $$=mk_action(STRIP_TAIL_T, 1, NUMBER_ST, (void*)$3); set_cfg_pos($$); }
2901         | STRIP_TAIL error { $$=0; yyerror("missing '(' or ')' ?"); }
2902         | STRIP_TAIL LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
2903         | STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, 1, NUMBER_ST, (void*) $3); set_cfg_pos($$); }
2904         | STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
2905         | STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
2906         | SET_USERPHONE LPAREN RPAREN { $$=mk_action(SET_USERPHONE_T, 0); set_cfg_pos($$); }
2907         | SET_USERPHONE error { $$=0; yyerror("missing '(' or ')' ?"); }
2908         | APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN {
2909                 qvalue_t q;
2910                 if (str2q(&q, $5, strlen($5)) < 0) {
2911                         yyerror("bad argument, q value expected");
2912                 }
2913                 $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, $3, NUMBER_ST, (void *)(long)q);
2914                 set_cfg_pos($$);
2915         }
2916         | APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, $3, NUMBER_ST, (void *)Q_UNSPECIFIED); set_cfg_pos($$); }
2917         | APPEND_BRANCH LPAREN RPAREN { $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, 0, NUMBER_ST, (void *)Q_UNSPECIFIED); set_cfg_pos($$); }
2918         | APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, 1, STRING_ST, 0); set_cfg_pos($$); }
2919         | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORT_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2920         | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2921         | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2922         | SET_HOSTPORTTRANS LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORTTRANS_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2923         | SET_HOSTPORTTRANS error { $$=0; yyerror("missing '(' or ')' ?"); }
2924         | SET_HOSTPORTTRANS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2925         | SET_PORT LPAREN STRING RPAREN { $$=mk_action(SET_PORT_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2926         | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2927         | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2928         | SET_USER LPAREN STRING RPAREN { $$=mk_action(SET_USER_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2929         | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
2930         | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2931         | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action(SET_USERPASS_T, 1, STRING_ST, $3); set_cfg_pos($$); }
2932         | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
2933         | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2934         | SET_URI LPAREN STRING RPAREN { $$=mk_action(SET_URI_T, 1, STRING_ST,$3); set_cfg_pos($$); }
2935         | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
2936         | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2937         | REVERT_URI LPAREN RPAREN { $$=mk_action(REVERT_URI_T, 0); set_cfg_pos($$); }
2938         | REVERT_URI { $$=mk_action(REVERT_URI_T, 0); set_cfg_pos($$); }
2939         | FORCE_RPORT LPAREN RPAREN     { $$=mk_action(FORCE_RPORT_T, 0); set_cfg_pos($$); }
2940         | FORCE_RPORT   {$$=mk_action(FORCE_RPORT_T, 0); set_cfg_pos($$); }
2941         | ADD_LOCAL_RPORT LPAREN RPAREN { $$=mk_action(ADD_LOCAL_RPORT_T, 0); set_cfg_pos($$); }
2942         | ADD_LOCAL_RPORT       {$$=mk_action(ADD_LOCAL_RPORT_T, 0); set_cfg_pos($$); }
2943         | FORCE_TCP_ALIAS LPAREN NUMBER RPAREN  {
2944                 #ifdef USE_TCP
2945                         $$=mk_action(FORCE_TCP_ALIAS_T, 1, NUMBER_ST, (void*)$3);
2946                         set_cfg_pos($$);
2947                 #else
2948                         yyerror("tcp support not compiled in");
2949                 #endif
2950         }
2951         | FORCE_TCP_ALIAS LPAREN RPAREN {
2952                 #ifdef USE_TCP
2953                         $$=mk_action(FORCE_TCP_ALIAS_T, 0);
2954                         set_cfg_pos($$);
2955                 #else
2956                         yyerror("tcp support not compiled in");
2957                 #endif
2958         }
2959         | FORCE_TCP_ALIAS                               {
2960                 #ifdef USE_TCP
2961                         $$=mk_action(FORCE_TCP_ALIAS_T, 0);
2962                         set_cfg_pos($$);
2963                 #else
2964                         yyerror("tcp support not compiled in");
2965                 #endif
2966         }
2967         | FORCE_TCP_ALIAS LPAREN error RPAREN   {$$=0; yyerror("bad argument, number expected"); }
2968         | UDP_MTU_TRY_PROTO LPAREN proto RPAREN
2969                 { $$=mk_action(UDP_MTU_TRY_PROTO_T, 1, NUMBER_ST, $3); set_cfg_pos($$); }
2970         | UDP_MTU_TRY_PROTO LPAREN error RPAREN
2971                 { $$=0; yyerror("bad argument, UDP, TCP, TLS or SCTP expected"); }
2972         | SET_ADV_ADDRESS LPAREN listen_id RPAREN {
2973                 $$=0;
2974                 if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
2975                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2976                 } else {
2977                         str_tmp->s=$3;
2978                         str_tmp->len=$3?strlen($3):0;
2979                         $$=mk_action(SET_ADV_ADDR_T, 1, STR_ST, str_tmp);
2980                         set_cfg_pos($$);
2981                 }
2982         }
2983         | SET_ADV_ADDRESS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2984         | SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); }
2985         | SET_ADV_PORT LPAREN NUMBER RPAREN {
2986                 $$=0;
2987                 tmp=int2str($3, &i_tmp);
2988                 if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
2989                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2990                 } else {
2991                         if ((str_tmp->s=pkg_malloc(i_tmp))==0) {
2992                                 LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2993                         } else {
2994                                 memcpy(str_tmp->s, tmp, i_tmp);
2995                                 str_tmp->len=i_tmp;
2996                                 $$=mk_action(SET_ADV_PORT_T, 1, STR_ST, str_tmp);
2997                                 set_cfg_pos($$);
2998                         }
2999                 }
3000         }
3001         | SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
3002         | SET_ADV_PORT  error {$$=0; yyerror("missing '(' or ')' ?"); }
3003         | FORCE_SEND_SOCKET LPAREN phostport RPAREN { 
3004                 $$=mk_action(FORCE_SEND_SOCKET_T, 1, SOCKID_ST, $3);
3005                 set_cfg_pos($$);
3006         }
3007         | FORCE_SEND_SOCKET LPAREN error RPAREN {
3008                 $$=0; yyerror("bad argument, [proto:]host[:port] expected");
3009         }
3010         | FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
3011         | SET_FWD_NO_CONNECT LPAREN RPAREN      {
3012                 $$=mk_action(SET_FWD_NO_CONNECT_T, 0); set_cfg_pos($$);
3013         }
3014         | SET_FWD_NO_CONNECT    {
3015                 $$=mk_action(SET_FWD_NO_CONNECT_T, 0); set_cfg_pos($$);
3016         }
3017         | SET_RPL_NO_CONNECT LPAREN RPAREN      {
3018                 $$=mk_action(SET_RPL_NO_CONNECT_T, 0); set_cfg_pos($$);
3019         }
3020         | SET_RPL_NO_CONNECT    {
3021                 $$=mk_action(SET_RPL_NO_CONNECT_T, 0); set_cfg_pos($$);
3022         }
3023         | SET_FWD_CLOSE LPAREN RPAREN   {
3024                 $$=mk_action(SET_FWD_CLOSE_T, 0); set_cfg_pos($$);
3025         }
3026         | SET_FWD_CLOSE {
3027                 $$=mk_action(SET_FWD_CLOSE_T, 0); set_cfg_pos($$);
3028         }
3029         | SET_RPL_CLOSE LPAREN RPAREN   {
3030                 $$=mk_action(SET_RPL_CLOSE_T, 0); set_cfg_pos($$);
3031         }
3032         | SET_RPL_CLOSE {
3033                 $$=mk_action(SET_RPL_CLOSE_T, 0); set_cfg_pos($$);
3034         }
3035         | ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST,
3036                         0); } LPAREN func_params RPAREN {
3037                 mod_func_action->val[0].u.data = 
3038                         find_export_record($1, mod_func_action->val[1].u.number, rt,
3039                                                                 &u_tmp);
3040                 if (mod_func_action->val[0].u.data == 0) {
3041                         if (find_export_record($1, mod_func_action->val[1].u.number, 0,
3042                                                                         &u_tmp) ) {
3043                                         yyerror("Command cannot be used in the block\n");
3044                         } else {
3045                                 yyerror("unknown command, missing loadmodule?\n");
3046                         }
3047                         pkg_free(mod_func_action);
3048                         mod_func_action=0;
3049                 }else{
3050                         switch( ((union cmd_export_u*)
3051                                                 mod_func_action->val[0].u.data)->c.param_no){
3052                                 case 0:
3053                                 case 1:
3054                                 case 2:
3055                                         /* MODULE_T used for 0-2 params */
3056                                         break;
3057                                 case 3:
3058                                         mod_func_action->type=MODULE3_T;
3059                                         break;
3060                                 case 4:
3061                                         mod_func_action->type=MODULE4_T;
3062                                         break;
3063                                 case 5:
3064                                         mod_func_action->type=MODULE5_T;
3065                                         break;
3066                                 case 6:
3067                                         mod_func_action->type=MODULE6_T;
3068                                         break;
3069                                 case VAR_PARAM_NO:
3070                                         mod_func_action->type=MODULEX_T;
3071                                         break;
3072                                 default:
3073                                         yyerror("too many parameters for function\n");
3074                                         break;
3075                         }
3076                 }
3077                 $$ = mod_func_action;
3078                 set_cfg_pos($$);
3079         }
3080         | ID error                                      { yyerror("'('')' expected (function call)");}
3081         ;
3082 func_params:
3083         /* empty */
3084         | func_params COMMA func_param { }
3085         | func_param {}
3086         | func_params error { yyerror("call params error\n"); }
3087         ;
3088 func_param:
3089         intno {
3090                 if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
3091                         mod_func_action->val[mod_func_action->val[1].u.number+2].type =
3092                                 NUMBER_ST;
3093                         mod_func_action->val[mod_func_action->val[1].u.number+2].u.number =
3094                                 $1;
3095                         mod_func_action->val[1].u.number++;
3096                 } else {
3097                         yyerror("Too many arguments\n");
3098                 }
3099         }
3100         | STRING {
3101                 if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
3102                         mod_func_action->val[mod_func_action->val[1].u.number+2].type = STRING_ST;
3103                         mod_func_action->val[mod_func_action->val[1].u.number+2].u.string = $1;
3104                         mod_func_action->val[1].u.number++;
3105                 } else {
3106                         yyerror("Too many arguments\n");
3107                 }
3108         }
3109         ;
3110
3111 ret_cmd:
3112         DROP LPAREN RPAREN              {
3113                 $$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST,
3114                                                 (void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
3115         }
3116         | DROP rval_expr        {
3117                 $$=mk_action(DROP_T, 2, RVE_ST, $2, NUMBER_ST,
3118                                                 (void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
3119         }
3120         | DROP                          {
3121                 $$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, 
3122                                                 (void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
3123         }
3124         | EXIT LPAREN RPAREN            {
3125                 $$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F);
3126                 set_cfg_pos($$);
3127         }
3128         | EXIT rval_expr        {
3129                 $$=mk_action(DROP_T, 2, RVE_ST, $2, NUMBER_ST, (void*)EXIT_R_F);
3130                 set_cfg_pos($$);
3131         }
3132         | EXIT                          {
3133                 $$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F);
3134                 set_cfg_pos($$);
3135         }
3136         | RETURN                        {
3137                 $$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
3138                                                 (void*)RETURN_R_F); set_cfg_pos($$);
3139         }
3140         | RETURN  LPAREN RPAREN         {
3141                 $$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
3142                                                 (void*)RETURN_R_F); set_cfg_pos($$);
3143         }
3144         | RETURN rval_expr      {
3145                 $$=mk_action(DROP_T, 2, RVE_ST, $2, NUMBER_ST, (void*)RETURN_R_F);
3146                 set_cfg_pos($$);
3147         }
3148         | BREAK                         {
3149                 $$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)BREAK_R_F);
3150                 set_cfg_pos($$);
3151         }
3152         ;
3153
3154 %%
3155
3156 static void get_cpos(struct cfg_pos* pos)
3157 {
3158         pos->s_line=startline;
3159         pos->e_line=line;
3160         pos->s_col=startcolumn;
3161         pos->e_col=column-1;
3162         if(finame==0)
3163                 finame = (cfg_file!=0)?cfg_file:"default";
3164         pos->fname=finame;
3165 }
3166
3167
3168 static void warn_at(struct cfg_pos* p, char* format, ...)
3169 {
3170         va_list ap;
3171         char s[256];
3172         
3173         va_start(ap, format);
3174         vsnprintf(s, sizeof(s), format, ap);
3175         va_end(ap);
3176         if (p->e_line!=p->s_line)
3177                 LOG(L_WARN, "warning in config file %s, from line %d, column %d to"
3178                                         " line %d, column %d: %s\n",
3179                                         p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
3180         else if (p->s_col!=p->e_col)
3181                 LOG(L_WARN, "warning in config file %s, line %d, column %d-%d: %s\n",
3182                                         p->fname, p->s_line, p->s_col, p->e_col, s);
3183         else
3184                 LOG(L_WARN, "warning in config file %s, line %d, column %d: %s\n",
3185                                 p->fname, p->s_line, p->s_col, s);
3186         cfg_warnings++;
3187 }
3188
3189
3190
3191 static void yyerror_at(struct cfg_pos* p, char* format, ...)
3192 {
3193         va_list ap;
3194         char s[256];
3195         
3196         va_start(ap, format);
3197         vsnprintf(s, sizeof(s), format, ap);
3198         va_end(ap);
3199         if (p->e_line!=p->s_line)
3200                 LOG(L_CRIT, "parse error in config file %s, from line %d, column %d"
3201                                         " to line %d, column %d: %s\n",
3202                                         p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
3203         else if (p->s_col!=p->e_col)
3204                 LOG(L_CRIT,"parse error in config file %s, line %d, column %d-%d: %s\n",
3205                                         p->fname, p->s_line, p->s_col, p->e_col, s);
3206         else
3207                 LOG(L_CRIT, "parse error in config file %s, line %d, column %d: %s\n",
3208                                         p->fname, p->s_line, p->s_col, s);
3209         cfg_errors++;
3210 }
3211
3212
3213
3214 static void warn(char* format, ...)
3215 {
3216         va_list ap;
3217         char s[256];
3218         struct cfg_pos pos;
3219         
3220         get_cpos(&pos);
3221         va_start(ap, format);
3222         vsnprintf(s, sizeof(s), format, ap);
3223         va_end(ap);
3224         warn_at(&pos, s);
3225 }
3226
3227
3228
3229 static void yyerror(char* format, ...)
3230 {
3231         va_list ap;
3232         char s[256];
3233         struct cfg_pos pos;
3234         
3235         get_cpos(&pos);
3236         va_start(ap, format);
3237         vsnprintf(s, sizeof(s), format, ap);
3238         va_end(ap);
3239         yyerror_at(&pos, s);
3240 }
3241
3242
3243
3244 /** mk_rval_expr_v wrapper.
3245  *  checks mk_rval_expr_v return value and sets the cfg. pos
3246  *  (line and column numbers)
3247  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr_v)
3248  */
3249 static struct rval_expr* mk_rve_rval(enum rval_type type, void* v)
3250 {
3251         struct rval_expr* ret;
3252         struct cfg_pos pos;
3253
3254         get_cpos(&pos);
3255         ret=mk_rval_expr_v(type, v, &pos);
3256         if (ret==0){
3257                 yyerror("internal error: failed to create rval expr");
3258                 /* YYABORT; */
3259         }
3260         return ret;
3261 }
3262
3263
3264 /** mk_rval_expr1 wrapper.
3265  *  checks mk_rval_expr1 return value (!=0 and type checking)
3266  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr1)
3267  */
3268 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1)
3269 {
3270         struct rval_expr* ret;
3271         struct rval_expr* bad_rve;
3272         enum rval_type type, bad_t, exp_t;
3273         
3274         if (rve1==0)
3275                 return 0;
3276         ret=mk_rval_expr1(op, rve1, &rve1->fpos);
3277         if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
3278                 yyerror_at(&rve1->fpos, "bad expression: type mismatch"
3279                                         " (%s instead of %s)", rval_type_name(bad_t),
3280                                         rval_type_name(exp_t));
3281                 rve_destroy(ret);
3282                 ret=0;
3283         }
3284         return ret;
3285 }
3286
3287
3288 /** mk_rval_expr2 wrapper.
3289  *  checks mk_rval_expr2 return value (!=0 and type checking)
3290  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr2)
3291  */
3292 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
3293                                                                         struct rval_expr* rve2)
3294 {
3295         struct rval_expr* ret;
3296         struct rval_expr* bad_rve;
3297         enum rval_type type, bad_t, exp_t;
3298         struct cfg_pos pos;
3299         
3300         if ((rve1==0) || (rve2==0))
3301                 return 0;
3302         bad_rve=0;
3303         bad_t=0;
3304         exp_t=0;
3305         cfg_pos_join(&pos, &rve1->fpos, &rve2->fpos);
3306         ret=mk_rval_expr2(op, rve1, rve2, &pos);
3307         if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
3308                 if (bad_rve)
3309                         yyerror_at(&pos, "bad expression: type mismatch:"
3310                                                 " %s instead of %s at (%d,%d)",
3311                                                 rval_type_name(bad_t), rval_type_name(exp_t),
3312                                                 bad_rve->fpos.s_line, bad_rve->fpos.s_col);
3313                 else
3314                         yyerror("BUG: unexpected null \"bad\" expression\n");
3315                 rve_destroy(ret);
3316                 ret=0;
3317         }
3318         return ret;
3319 }
3320
3321
3322 /** check if the expression is an int.
3323  * if the expression does not evaluate to an int return -1 and
3324  * log an error.
3325  * @return 0 success, no warnings; 1 success but warnings; -1 on error */
3326 static int rval_expr_int_check(struct rval_expr *rve)
3327 {
3328         struct rval_expr* bad_rve;
3329         enum rval_type type, bad_t, exp_t;
3330         
3331         if (rve==0){
3332                 yyerror("invalid expression");
3333                 return -1;
3334         }else if (!rve_check_type(&type, rve, &bad_rve, &bad_t ,&exp_t)){
3335                 if (bad_rve)
3336                         yyerror_at(&rve->fpos, "bad expression: type mismatch:"
3337                                                 " %s instead of %s at (%d,%d)",
3338                                                 rval_type_name(bad_t), rval_type_name(exp_t),
3339                                                 bad_rve->fpos.s_line, bad_rve->fpos.s_col);
3340                 else
3341                         yyerror("BUG: unexpected null \"bad\" expression\n");
3342                 return -1;
3343         }else if (type!=RV_INT && type!=RV_NONE){
3344                 warn_at(&rve->fpos, "non-int expression (you might want to use"
3345                                 " casts)\n");
3346                 return 1;
3347         }
3348         return 0;
3349 }
3350
3351
3352 /** warn if the expression is constant.
3353  * @return 0 on success (no warning), 1 when warning */
3354 static int warn_ct_rve(struct rval_expr *rve, char* name)
3355 {
3356         if (rve && rve_is_constant(rve)){
3357                 warn_at(&rve->fpos, "constant value in %s%s",
3358                                 name?name:"expression", name?"(...)":"");
3359                 return 1;
3360         }
3361         return 0;
3362 }
3363
3364
3365 static struct name_lst* mk_name_lst(char* host, int flags)
3366 {
3367         struct name_lst* l;
3368         if (host==0) return 0;
3369         l=pkg_malloc(sizeof(struct name_lst));
3370         if (l==0) {
3371                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
3372         } else {
3373                 l->name=host;
3374                 l->flags=flags;
3375                 l->next=0;
3376         }
3377         return l;
3378 }
3379
3380
3381 static struct socket_id* mk_listen_id(char* host, int proto, int port)
3382 {
3383         struct socket_id* l;
3384         if (host==0) return 0;
3385         l=pkg_malloc(sizeof(struct socket_id));
3386         if (l==0) {
3387                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
3388         } else {
3389                 l->addr_lst=mk_name_lst(host, 0);
3390                 if (l->addr_lst==0){
3391                         pkg_free(l);
3392                         return 0;
3393                 }
3394                 l->flags=0;
3395                 l->port=port;
3396                 l->proto=proto;
3397                 l->next=0;
3398         }
3399         return l;
3400 }
3401
3402
3403 static void free_name_lst(struct name_lst* lst)
3404 {
3405         struct name_lst* tmp;
3406         
3407         while(lst){
3408                 tmp=lst;
3409                 lst=lst->next;
3410                 pkg_free(tmp);
3411         }
3412 }
3413
3414
3415 static struct socket_id* mk_listen_id2(struct name_lst* addr_l, int proto,
3416                                                                                 int port)
3417 {
3418         struct socket_id* l;
3419         if (addr_l==0) return 0;
3420         l=pkg_malloc(sizeof(struct socket_id));
3421         if (l==0) {
3422                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
3423         } else {
3424                 l->flags=addr_l->flags;
3425                 l->port=port;
3426                 l->proto=proto;
3427                 l->addr_lst=addr_l;
3428                 l->next=0;
3429         }
3430         return l;
3431 }
3432
3433
3434 static void free_socket_id(struct socket_id* i)
3435 {
3436         free_name_lst(i->addr_lst);
3437         pkg_free(i);
3438 }
3439
3440
3441 static void free_socket_id_lst(struct socket_id* lst)
3442 {
3443         struct socket_id* tmp;
3444         
3445         while(lst){
3446                 tmp=lst;
3447                 lst=lst->next;
3448                 free_socket_id(tmp);
3449         }
3450 }
3451
3452
3453 /** create a temporary case statmenet structure.
3454  *  *err will be filled in case of error (return == 0):
3455  *   -1 - non constant expression
3456  *   -2 - expression error (bad type)
3457  *   -10 - memory allocation error
3458  */
3459 static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re,
3460                                                                                         struct action* a, int* err)
3461 {
3462         struct case_stms* s;
3463         struct rval_expr* bad_rve;
3464         enum rval_type type, bad_t, exp_t;
3465         enum match_str_type t;
3466         
3467         t=MATCH_UNKNOWN;
3468         if (ct){
3469                 /* if ct!=0 => case, else if ct==0 is a default */
3470                 if (!rve_is_constant(ct)){
3471                         yyerror_at(&ct->fpos, "non constant expression in case");
3472                         *err=-1;
3473                         return 0;
3474                 }
3475                 if (rve_check_type(&type, ct, &bad_rve, &bad_t, &exp_t)!=1){
3476                         yyerror_at(&ct->fpos, "bad expression: type mismatch:"
3477                                                         " %s instead of %s at (%d,%d)",
3478                                                         rval_type_name(bad_t), rval_type_name(exp_t),
3479                                                         bad_rve->fpos.s_line, bad_rve->fpos.s_col);
3480                         *err=-2;
3481                         return 0;
3482                 }
3483                 if (is_re)
3484                         t=MATCH_RE;
3485                 else if (type==RV_STR)
3486                         t=MATCH_STR;
3487                 else
3488                         t=MATCH_INT;
3489         }
3490
3491         s=pkg_malloc(sizeof(*s));
3492         if (s==0) {
3493                 yyerror("internal error: memory allocation failure");
3494                 *err=-10;
3495         } else {
3496                 memset(s, 0, sizeof(*s));
3497                 s->ct_rve=ct;
3498                 s->type=t;
3499                 s->actions=a;
3500                 s->next=0;
3501                 s->append=0;
3502         }
3503         return s;
3504 }
3505
3506
3507 /*
3508  * @return 0 on success, -1 on error.
3509  */
3510 static int case_check_type(struct case_stms* stms)
3511 {
3512         struct case_stms* c;
3513         struct case_stms* s;
3514         
3515         for(c=stms; c ; c=c->next){
3516                 if (!c->ct_rve) continue;
3517                 for (s=c->next; s; s=s->next){
3518                         if (!s->ct_rve) continue;
3519                         if ((s->type!=c->type) &&
3520                                 !(      (c->type==MATCH_STR || c->type==MATCH_RE) &&
3521                                         (s->type==MATCH_STR || s->type==MATCH_RE) ) ){
3522                                         yyerror_at(&s->ct_rve->fpos, "type mismatch in case");
3523                                         return -1;
3524                         }
3525                 }
3526         }
3527         return 0;
3528 }
3529
3530
3531 /*
3532  * @return 0 on success, -1 on error.
3533  */
3534 static int case_check_default(struct case_stms* stms)
3535 {
3536         struct case_stms* c;
3537         int default_no;
3538         
3539         default_no=0;
3540         for(c=stms; c ; c=c->next)
3541                 if (c->ct_rve==0) default_no++;
3542         return (default_no<=1)?0:-1;
3543 }
3544
3545
3546
3547 /*
3548 int main(int argc, char ** argv)
3549 {
3550         if (yyparse()!=0)
3551                 fprintf(stderr, "parsing error\n");
3552 }
3553 */