Browse code

- if () {} do not have to be followed by ';' anymore - added switch to check the config file (-c) and display aliases and listen interface list if the config is ok. - changes: removed len_gt() and replaced with if (msg:len op number|max_len) - more operators supported: != for special operations (e.g. myself or ip comparisons), != for strings (==, !=, ~=), !=, >, <, >=, <= for numbers (e.g msg:len >= max_len). - updated NEWS

Andrei Pelinescu-Onciul authored on 12/10/2003 15:09:08
Showing 10 changed files
... ...
@@ -43,7 +43,7 @@ export makefile_defs
43 43
 VERSION = 0
44 44
 PATCHLEVEL = 8
45 45
 SUBLEVEL =   12
46
-EXTRAVERSION = dev-18-fifo
46
+EXTRAVERSION = dev-19
47 47
 
48 48
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
49 49
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -7,6 +7,35 @@ $Id$
7 7
 
8 8
 texops:
9 9
  - subst('s/re/repl/flags') support
10
+core:
11
+ - added switch to check the config file (-c)
12
+ - changes: removed len_gt() and replaced with if (msg:len op number|max_len)
13
+ - multiple operator support: ==, != for special operations (e.g myself, ip)
14
+                              ==, !=, ~= for strings
15
+                              ==, !=, >, <, >=, <= for integers
16
+ - new config variables:
17
+     advertised_address= ip | string
18
+       address advertised in via and in the DST_* lumps (e.g RR)
19
+       This is the default value, if empty (default) the socket
20
+       address will be used.
21
+       WARNING: - don't set it unless you know what you are doing
22
+                 (e.g. nat traversal)
23
+               - you can set anything here, no check is made
24
+                (e.g. foo.bar will be accepted even if 
25
+                 foo.bar doesn't exist)
26
+    advertised_port= no
27
+       port advertised in via and in the DST_*lumps (e.g. RR)
28
+       This is the default value, if empty (default) the socket
29
+       port will be used.
30
+       Same warnings as above.
31
+ - new script commands:
32
+    set_advertised_address(ip|string)
33
+       same as advertised_address but it affects only the current message:
34
+       Message host/lump address= the set_advertised one if
35
+       present, else advertised_address else socket address.
36
+    set_advertised_port(no)
37
+       same as advertised_port but it affects only the current
38
+       message; see set_advertised_address & s/address/port/g
10 39
 
11 40
 
12 41
 
... ...
@@ -8,7 +8,7 @@ x update Makefile*  from stable
8 8
 x update all package specs from stable
9 9
 - add BUG checks for  fd > 0 && fd <= maxfd to all selects?
10 10
 x tcp_main_loop: BUG cases should "conitnue;"
11
-- change len_gt into and expr (e.g msg:len).
11
+x change len_gt into and expr (e.g msg:len).
12 12
 - sipit: uri == myself doesn't match tls port = 5061
13 13
 - sipit: fix check_self & *_alias to work with tcp & tls
14 14
 x sipit: fix ipv6 references in check_self
... ...
@@ -99,7 +99,7 @@ x forward to received= if present
99 99
 x add support for -u user and -g group (not only -u uid, -g uid)
100 100
 - change uid/gid after opening the sockets
101 101
 - exec improvments (add format strings to it)
102
-- command line switch for checking the config file syntax
102
+x command line switch for checking the config file syntax
103 103
 - config file version (a la sendmail)
104 104
 0 loop detection
105 105
 - cfg. file reload
... ...
@@ -40,6 +40,7 @@
40 40
  *  2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
41 41
  *  2003-10-02  added {,set_}advertised_{address,port} (andrei)
42 42
  *  2003-10-07  added hex and octal numbers support (andrei)
43
+ *  2003-10-10  replaced len_gt w/ msg:len (andrei)
43 44
  */
44 45
 
45 46
 
... ...
@@ -94,7 +95,6 @@ FORCE_RPORT		"force_rport"|"add_rport"
94 94
 SETFLAG		setflag
95 95
 RESETFLAG	resetflag
96 96
 ISFLAGSET	isflagset
97
-LEN_GT		len_gt
98 97
 SET_HOST		"rewritehost"|"sethost"|"seth"
99 98
 SET_HOSTPORT	"rewritehostport"|"sethostport"|"sethp"
100 99
 SET_USER		"rewriteuser"|"setuser"|"setu"
... ...
@@ -132,9 +132,15 @@ DSTPORT	dst_port
132 132
 PROTO	proto
133 133
 AF		af
134 134
 MYSELF	myself
135
+MSGLEN			"msg:len"
135 136
 /* operators */
136 137
 EQUAL	=
137 138
 EQUAL_T	==
139
+GT	>
140
+LT	<
141
+GTE	>=
142
+LTE	<=
143
+DIFF	!=
138 144
 MATCH	=~
139 145
 NOT		!|"not"
140 146
 AND		"and"|"&&"|"&"
... ...
@@ -244,7 +250,7 @@ EAT_ABLE	[\ \t\b\r]
244 244
 <INITIAL>{SETFLAG}	{ count(); yylval.strval=yytext; return SETFLAG; }
245 245
 <INITIAL>{RESETFLAG}	{ count(); yylval.strval=yytext; return RESETFLAG; }
246 246
 <INITIAL>{ISFLAGSET}	{ count(); yylval.strval=yytext; return ISFLAGSET; }
247
-<INITIAL>{LEN_GT}	{ count(); yylval.strval=yytext; return LEN_GT; }
247
+<INITIAL>{MSGLEN}	{ count(); yylval.strval=yytext; return MSGLEN; }
248 248
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
249 249
 <INITIAL>{ROUTE_ONREPLY}	{ count(); yylval.strval=yytext;
250 250
 								return ROUTE_ONREPLY; }
... ...
@@ -336,6 +342,11 @@ EAT_ABLE	[\ \t\b\r]
336 336
 
337 337
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
338 338
 <INITIAL>{EQUAL_T}	{ count(); return EQUAL_T; }
339
+<INITIAL>{GT}	{ count(); return GT; }
340
+<INITIAL>{LT}	{ count(); return LT; }
341
+<INITIAL>{GTE}	{ count(); return GTE; }
342
+<INITIAL>{LTE}	{ count(); return LTE; }
343
+<INITIAL>{DIFF}	{ count(); return DIFF; }
339 344
 <INITIAL>{MATCH}	{ count(); return MATCH; }
340 345
 <INITIAL>{NOT}		{ count(); return NOT; }
341 346
 <INITIAL>{AND}		{ count(); return AND; }
... ...
@@ -43,6 +43,9 @@
43 43
  *              require_certificate added (andrei)
44 44
  * 2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
45 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)
46 49
  */
47 50
 
48 51
 
... ...
@@ -148,7 +151,6 @@ void warn(char* s);
148 148
 %token SETFLAG
149 149
 %token RESETFLAG
150 150
 %token ISFLAGSET
151
-%token LEN_GT
152 151
 %token METHOD
153 152
 %token URI
154 153
 %token SRCIP
... ...
@@ -158,6 +160,7 @@ void warn(char* s);
158 158
 %token PROTO
159 159
 %token AF
160 160
 %token MYSELF
161
+%token MSGLEN 
161 162
 
162 163
 /* config vars. */
163 164
 %token DEBUG
... ...
@@ -211,6 +214,11 @@ void warn(char* s);
211 211
 /* operators */
212 212
 %nonassoc EQUAL
213 213
 %nonassoc EQUAL_T
214
+%nonassoc GT
215
+%nonassoc LT
216
+%nonassoc GTE
217
+%nonassoc LTE
218
+%nonassoc DIFF
214 219
 %nonassoc MATCH
215 220
 %left OR
216 221
 %left AND
... ...
@@ -244,6 +252,7 @@ void warn(char* s);
244 244
 %type <strval> host
245 245
 %type <strval> listen_id
246 246
 %type <idlst>  id_lst
247
+%type <intval> equalop strop intop
247 248
 /*%type <route_el> rules;
248 249
   %type <route_el> rule;
249 250
 */
... ...
@@ -285,14 +294,6 @@ listen_id:	ip			{	tmp=ip_addr2a($1);
285 285
 								}
286 286
 							}
287 287
 						}
288
-		 |	ID			{	$$=pkg_malloc(strlen($1)+1);
289
-		 					if ($$==0){
290
-									LOG(L_CRIT, "ERROR: cfg. parser: out of "
291
-											"memory.\n");
292
-							}else{
293
-									strncpy($$, $1, strlen($1)+1);
294
-							}
295
-						}
296 288
 		 |	STRING			{	$$=pkg_malloc(strlen($1)+1);
297 289
 		 					if ($$==0){
298 290
 									LOG(L_CRIT, "ERROR: cfg. parser: out of "
... ...
@@ -335,7 +336,7 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
335 335
 		| DEBUG EQUAL error  { yyerror("number  expected"); }
336 336
 		| FORK  EQUAL NUMBER { dont_fork= ! $3; }
337 337
 		| FORK  EQUAL error  { yyerror("boolean value expected"); }
338
-		| LOGSTDERROR EQUAL NUMBER { log_stderr=$3; }
338
+		| LOGSTDERROR EQUAL NUMBER { if (!config_check) log_stderr=$3; }
339 339
 		| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
340 340
 		| DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
341 341
 		| DNS EQUAL error { yyerror("boolean value expected"); }
... ...
@@ -700,117 +701,112 @@ exp:	exp AND exp 	{ $$=mk_exp(AND_OP, $1, $3); }
700 700
 	| exp_elem			{ $$=$1; }
701 701
 	;
702 702
 
703
-exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST, 
703
+equalop:	  EQUAL_T {$$=EQUAL_OP; }
704
+			| DIFF	{$$=DIFF_OP; }
705
+		;
706
+		
707
+intop:	equalop	{$$=$1; }
708
+		|  GT	{$$=GT_OP; }
709
+		| LT	{$$=LT_OP; }
710
+		| GTE	{$$=GTE_OP; }
711
+		| LTE	{$$=LTE_OP; }
712
+		;
713
+		
714
+strop:	equalop	{$$=$1; }
715
+		| MATCH	{$$=MATCH_OP; }
716
+		;
717
+
718
+exp_elem:	METHOD strop STRING	{$$= mk_elem(	$2, STRING_ST, 
704 719
 													METHOD_O, $3);
705 720
 									}
706
-		| METHOD EQUAL_T ID	{$$ = mk_elem(	EQUAL_OP, STRING_ST,
721
+		| METHOD strop  ID	{$$ = mk_elem(	$2, STRING_ST,
707 722
 											METHOD_O, $3); 
708 723
 				 			}
709
-		| METHOD EQUAL_T error { $$=0; yyerror("string expected"); }
710
-		| METHOD MATCH STRING	{$$ = mk_elem(	MATCH_OP, STRING_ST,
711
-												METHOD_O, $3); 
712
-				 				}
713
-		| METHOD MATCH ID	{$$ = mk_elem(	MATCH_OP, STRING_ST,
714
-											METHOD_O, $3); 
715
-				 			}
716
-		| METHOD MATCH error { $$=0; yyerror("string expected"); }
724
+		| METHOD strop error { $$=0; yyerror("string expected"); }
717 725
 		| METHOD error	{ $$=0; yyerror("invalid operator,"
718
-										"== or =~ expected");
726
+										"== , !=, or =~ expected");
719 727
 						}
720
-		| URI EQUAL_T STRING 	{$$ = mk_elem(	EQUAL_OP, STRING_ST,
728
+		| URI strop STRING 	{$$ = mk_elem(	$2, STRING_ST,
721 729
 												URI_O, $3); 
722 730
 				 				}
723
-		| URI EQUAL_T ID 	{$$ = mk_elem(	EQUAL_OP, STRING_ST,
731
+		| URI strop host 	{$$ = mk_elem(	$2, STRING_ST,
724 732
 											URI_O, $3); 
725 733
 				 			}
726
-		| URI EQUAL_T MYSELF    { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
734
+		| URI equalop MYSELF    { $$=mk_elem(	$2, MYSELF_ST,
727 735
 												URI_O, 0);
728 736
 								}
729
-		| URI EQUAL_T error { $$=0; yyerror("string expected"); }
730
-		| URI MATCH STRING	{ $$=mk_elem(	MATCH_OP, STRING_ST,
731
-											URI_O, $3);
732
-							}
733
-		| URI MATCH ID		{ $$=mk_elem(	MATCH_OP, STRING_ST,
734
-											URI_O, $3);
735
-							}
736
-		| URI MATCH error {  $$=0; yyerror("string expected"); }
737
+		| URI strop error { $$=0; yyerror("string or MYSELF expected"); }
737 738
 		| URI error	{ $$=0; yyerror("invalid operator,"
738
-				  					" == or =~ expected");
739
+									" == , != or =~ expected");
739 740
 					}
740
-		| SRCPORT EQUAL_T NUMBER	{ $$=mk_elem(	EQUAL_OP, NUMBER_ST,
741
+		| SRCPORT intop NUMBER	{ $$=mk_elem(	$2, NUMBER_ST,
741 742
 												SRCPORT_O, (void *) $3 ); }
742
-		| SRCPORT EQUAL_T error { $$=0; yyerror("number expected"); }
743
-		| SRCPORT error { $$=0; yyerror("equal operator expected"); }
744
-		| DSTPORT EQUAL_T NUMBER	{ $$=mk_elem(	EQUAL_OP, NUMBER_ST,
743
+		| SRCPORT intop error { $$=0; yyerror("number expected"); }
744
+		| SRCPORT error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
745
+		| DSTPORT intop NUMBER	{ $$=mk_elem(	$2, NUMBER_ST,
745 746
 												DSTPORT_O, (void *) $3 ); }
746
-		| DSTPORT EQUAL_T error { $$=0; yyerror("number expected"); }
747
-		| DSTPORT error { $$=0; yyerror("equal operator expected"); }
748
-		| PROTO EQUAL_T NUMBER	{ $$=mk_elem(	EQUAL_OP, NUMBER_ST,
747
+		| DSTPORT intop error { $$=0; yyerror("number expected"); }
748
+		| DSTPORT error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
749
+		| PROTO intop NUMBER	{ $$=mk_elem(	$2, NUMBER_ST,
749 750
 												PROTO_O, (void *) $3 ); }
750
-		| PROTO EQUAL_T error { $$=0; yyerror("number expected"); }
751
-		| PROTO error { $$=0; yyerror("equal operator expected"); }
752
-		| AF EQUAL_T NUMBER	{ $$=mk_elem(	EQUAL_OP, NUMBER_ST,
751
+		| PROTO intop error { $$=0; yyerror("number expected"); }
752
+		| PROTO error { $$=0; yyerror("equal/!= operator expected"); }
753
+		| AF intop NUMBER	{ $$=mk_elem(	$2, NUMBER_ST,
753 754
 												AF_O, (void *) $3 ); }
754
-		| AF EQUAL_T error { $$=0; yyerror("number expected"); }
755
-		| AF error { $$=0; yyerror("equal operator expected"); }
756
-		| SRCIP EQUAL_T ipnet	{ $$=mk_elem(	EQUAL_OP, NET_ST,
755
+		| AF intop error { $$=0; yyerror("number expected"); }
756
+		| AF error { $$=0; yyerror("equal/!= operator expected"); }
757
+		| MSGLEN intop NUMBER	{ $$=mk_elem(	$2, NUMBER_ST,
758
+												MSGLEN_O, (void *) $3 ); }
759
+		| MSGLEN intop MAX_LEN	{ $$=mk_elem(	$2, NUMBER_ST,
760
+												MSGLEN_O, (void *) BUF_SIZE); }
761
+		| MSGLEN intop error { $$=0; yyerror("number expected"); }
762
+		| MSGLEN error { $$=0; yyerror("equal/!= operator expected"); }
763
+		| SRCIP equalop ipnet	{ $$=mk_elem(	$2, NET_ST,
757 764
 												SRCIP_O, $3);
758 765
 								}
759
-		| SRCIP EQUAL_T STRING	{ $$=mk_elem(	EQUAL_OP, STRING_ST,
766
+		| SRCIP strop STRING	{ $$=mk_elem(	$2, STRING_ST,
760 767
 												SRCIP_O, $3);
761 768
 								}
762
-		| SRCIP EQUAL_T host	{ $$=mk_elem(	EQUAL_OP, STRING_ST,
769
+		| SRCIP strop host	{ $$=mk_elem(	$2, STRING_ST,
763 770
 												SRCIP_O, $3);
764 771
 								}
765
-		| SRCIP EQUAL_T MYSELF  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
772
+		| SRCIP equalop MYSELF  { $$=mk_elem(	$2, MYSELF_ST,
766 773
 												SRCIP_O, 0);
767 774
 								}
768
-		| SRCIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
775
+		| SRCIP strop error { $$=0; yyerror( "ip address or hostname"
769 776
 						 "expected" ); }
770
-		| SRCIP MATCH STRING	{ $$=mk_elem(	MATCH_OP, STRING_ST,
771
-												SRCIP_O, $3);
772
-								}
773
-		| SRCIP MATCH ID		{ $$=mk_elem(	MATCH_OP, STRING_ST,
774
-												SRCIP_O, $3);
775
-								}
776
-		| SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
777 777
 		| SRCIP error  { $$=0; 
778
-						 yyerror("invalid operator, == or =~ expected");}
779
-		| DSTIP EQUAL_T ipnet	{ $$=mk_elem(	EQUAL_OP, NET_ST,
778
+						 yyerror("invalid operator, ==, != or =~ expected");}
779
+		| DSTIP equalop ipnet	{ $$=mk_elem(	$2, NET_ST,
780 780
 												DSTIP_O, $3);
781 781
 								}
782
-		| DSTIP EQUAL_T STRING	{ $$=mk_elem(	EQUAL_OP, STRING_ST,
782
+		| DSTIP strop STRING	{ $$=mk_elem(	$2, STRING_ST,
783 783
 												DSTIP_O, $3);
784 784
 								}
785
-		| DSTIP EQUAL_T host	{ $$=mk_elem(	EQUAL_OP, STRING_ST,
785
+		| DSTIP strop host	{ $$=mk_elem(	$2, STRING_ST,
786 786
 												DSTIP_O, $3);
787 787
 								}
788
-		| DSTIP EQUAL_T MYSELF  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
788
+		| DSTIP equalop MYSELF  { $$=mk_elem(	$2, MYSELF_ST,
789 789
 												DSTIP_O, 0);
790 790
 								}
791
-		| DSTIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
791
+		| DSTIP strop error { $$=0; yyerror( "ip address or hostname"
792 792
 						 			"expected" ); }
793
-		| DSTIP MATCH STRING	{ $$=mk_elem(	MATCH_OP, STRING_ST,
794
-												DSTIP_O, $3);
795
-								}
796
-		| DSTIP MATCH ID	{ $$=mk_elem(	MATCH_OP, STRING_ST,
797
-											DSTIP_O, $3);
798
-							}
799
-		| DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
800 793
 		| DSTIP error { $$=0; 
801
-						yyerror("invalid operator, == or =~ expected");}
802
-		| MYSELF EQUAL_T URI    { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
794
+						yyerror("invalid operator, ==, != or =~ expected");}
795
+		| MYSELF equalop URI    { $$=mk_elem(	$2, MYSELF_ST,
803 796
 												URI_O, 0);
804 797
 								}
805
-		| MYSELF EQUAL_T SRCIP  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
798
+		| MYSELF equalop SRCIP  { $$=mk_elem(	$2, MYSELF_ST,
806 799
 												SRCIP_O, 0);
807 800
 								}
808
-		| MYSELF EQUAL_T DSTIP  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
801
+		| MYSELF equalop DSTIP  { $$=mk_elem(	$2, MYSELF_ST,
809 802
 												DSTIP_O, 0);
810 803
 								}
811
-		| MYSELF EQUAL_T error {	$$=0; 
804
+		| MYSELF equalop error {	$$=0; 
812 805
 									yyerror(" URI, SRCIP or DSTIP expected"); }
813
-		| MYSELF error	{ $$=0; yyerror ("invalid operator, == expected"); }
806
+		| MYSELF error	{ $$=0; 
807
+							yyerror ("invalid operator, == or != expected");
808
+						}
814 809
 		| stm				{ $$=mk_elem( NO_OP, ACTIONS_ST, ACTION_O, $1 ); }
815 810
 		| NUMBER		{$$=mk_elem( NO_OP, NUMBER_ST, NUMBER_O, (void*)$1 ); }
816 811
 	;
... ...
@@ -851,6 +847,7 @@ host:	ID				{ $$=$1; }
851 851
 
852 852
 
853 853
 stm:		cmd						{ $$=$1; }
854
+		|	if_cmd					{ $$=$1; }
854 855
 		|	LBRACE actions RBRACE	{ $$=$2; }
855 856
 	;
856 857
 
... ...
@@ -860,6 +857,7 @@ actions:	actions action	{$$=append_action($1, $2); }
860 860
 	;
861 861
 
862 862
 action:		cmd SEMICOLON {$$=$1;}
863
+		| if_cmd {$$=$1;}
863 864
 		| SEMICOLON /* null action */ {$$=0;}
864 865
 		| cmd error { $$=0; yyerror("bad command: missing ';'?"); }
865 866
 	;
... ...
@@ -1282,13 +1280,6 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
1282 1282
 		| SETFLAG LPAREN NUMBER RPAREN {$$=mk_action( SETFLAG_T, NUMBER_ST, 0,
1283 1283
 													(void *)$3, 0 ); }
1284 1284
 		| SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
1285
-
1286
-		| LEN_GT LPAREN NUMBER RPAREN {$$=mk_action( LEN_GT_T, NUMBER_ST, 0,
1287
-													(void *)$3, 0 ); }
1288
-		| LEN_GT LPAREN MAX_LEN RPAREN {$$=mk_action( LEN_GT_T, NUMBER_ST, 0,
1289
-													(void *) BUF_SIZE, 0 ); }
1290
-		| LEN_GT error { $$=0; yyerror("missing '(' or ')'?"); }
1291
-
1292 1285
 		| RESETFLAG LPAREN NUMBER RPAREN {$$=mk_action(	RESETFLAG_T, NUMBER_ST, 0,
1293 1286
 													(void *)$3, 0 ); }
1294 1287
 		| RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
... ...
@@ -1465,7 +1456,6 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
1465 1465
 									}
1466 1466
 								  }
1467 1467
 		| ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
1468
-		| if_cmd		{ $$=$1; }
1469 1468
 	;
1470 1469
 
1471 1470
 
... ...
@@ -44,6 +44,7 @@
44 44
 
45 45
 
46 46
 extern char * cfg_file;
47
+extern int config_check;
47 48
 extern char *stat_file;
48 49
 extern struct socket_info sock_info[]; /* all addresses we listen/send from*/
49 50
 #ifdef USE_TCP
... ...
@@ -43,6 +43,7 @@
43 43
  *  2003-06-28  kill_all_children is now used instead of kill(0, sig)
44 44
  *                see comment above it for explanations. (andrei)
45 45
  *  2003-06-29  replaced port_no_str snprintf w/ int2str (andrei)
46
+ *  2003-10-10  added switch for config check (-c) (andrei)
46 47
  *
47 48
  */
48 49
 
... ...
@@ -196,6 +197,7 @@ static char help_msg[]= "\
196 196
 Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\
197 197
 Options:\n\
198 198
     -f file      Configuration file (default " CFG_FILE ")\n\
199
+    -c           Check configuration file for errors\n\
199 200
     -p port      Listen on the specified port (default: 5060)\n\
200 201
                   applies to the last address in -l and to all \n\
201 202
                   following that do not have a corespponding -p\n\
... ...
@@ -289,6 +291,7 @@ int sig_flag = 0;              /* last signal received */
289 289
 int debug = L_NOTICE;
290 290
 int dont_fork = 0;
291 291
 int log_stderr = 0;
292
+int config_check = 0;
292 293
 /* check if reply first via host==us */
293 294
 int check_via =  0;        
294 295
 /* shall use stateful synonym branches? faster but not reboot-safe */
... ...
@@ -1262,13 +1265,17 @@ int main(int argc, char** argv)
1262 1262
 #ifdef STATS
1263 1263
 	"s:"
1264 1264
 #endif
1265
-	"f:p:m:b:l:n:N:rRvdDETVhw:t:u:g:P:i:";
1265
+	"f:cp:m:b:l:n:N:rRvdDETVhw:t:u:g:P:i:";
1266 1266
 	
1267 1267
 	while((c=getopt(argc,argv,options))!=-1){
1268 1268
 		switch(c){
1269 1269
 			case 'f':
1270 1270
 					cfg_file=optarg;
1271 1271
 					break;
1272
+			case 'c':
1273
+					config_check=1;
1274
+					log_stderr=1; /* force stderr logging */
1275
+					break;
1272 1276
 			case 's':
1273 1277
 				#ifdef STATS
1274 1278
 					stat_file=optarg;
... ...
@@ -1710,6 +1717,10 @@ try_again:
1710 1710
 				(sock_no>1)?" and more than one listen address found (will"
1711 1711
 							" use only the the first one)":"");
1712 1712
 	}
1713
+	if (config_check){
1714
+		fprintf(stderr, "config file ok, exiting...\n");
1715
+		goto error;
1716
+	}
1713 1717
 	
1714 1718
 #ifdef USE_TCP
1715 1719
 	if (!tcp_disable){
... ...
@@ -38,6 +38,7 @@
38 38
  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
39 39
  *  2003-05-23  comp_ip fixed, now it will resolve its operand and compare
40 40
  *              the ip with all the addresses (andrei)
41
+ *  2003-10-10  added more operators support to comp_* (<,>,<=,>=,!=) (andrei)
41 42
  */
42 43
 
43 44
  
... ...
@@ -247,15 +248,28 @@ static int fix_actions(struct action* a)
247 247
 
248 248
 inline static int comp_no( int port, void *param, int op, int subtype )
249 249
 {
250
-	if (op!=EQUAL_OP) {
251
-		LOG(L_CRIT, "BUG: comp_no: '=' expected: %d\n", op );
252
-		return E_BUG;
253
-	}
250
+	
254 251
 	if (subtype!=NUMBER_ST) {
255 252
 		LOG(L_CRIT, "BUG: comp_no: number expected: %d\n", subtype );
256 253
 		return E_BUG;
257 254
 	}
258
-	return port==(long)param;
255
+	switch (op){
256
+		case EQUAL_OP:
257
+			return port==(long)param;
258
+		case DIFF_OP:
259
+			return port!=(long)param;
260
+		case GT_OP:
261
+			return port>(long)param;
262
+		case LT_OP:
263
+			return port<(long)param;
264
+		case GTE_OP:
265
+			return port>=(long)param;
266
+		case LTE_OP:
267
+			return port<=(long)param;
268
+		default:
269
+		LOG(L_CRIT, "BUG: comp_no: unknown operator: %d\n", op );
270
+		return E_BUG;
271
+	}
259 272
 }
260 273
 
261 274
 /* eval_elem helping function, returns str op param */
... ...
@@ -265,19 +279,29 @@ inline static int comp_strstr(str* str, void* param, int op, int subtype)
265 265
 	char backup;
266 266
 	
267 267
 	ret=-1;
268
-	if (op==EQUAL_OP){
269
-		if (subtype!=STRING_ST){
270
-			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
271
-					"string expected\n", subtype);
272
-			goto error;
273
-		}
274
-		ret=(strncasecmp(str->s, (char*)param, str->len)==0);
275
-	}else if (op==MATCH_OP){
276
-		if (subtype!=RE_ST){
277
-			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
278
-					" RE expected\n", subtype);
279
-			goto error;
280
-		}
268
+	switch(op){
269
+		case EQUAL_OP:
270
+			if (subtype!=STRING_ST){
271
+				LOG(L_CRIT, "BUG: comp_str: bad type %d, "
272
+						"string expected\n", subtype);
273
+				goto error;
274
+			}
275
+			ret=(strncasecmp(str->s, (char*)param, str->len)==0);
276
+			break;
277
+		case DIFF_OP:
278
+			if (subtype!=STRING_ST){
279
+				LOG(L_CRIT, "BUG: comp_str: bad type %d, "
280
+						"string expected\n", subtype);
281
+				goto error;
282
+			}
283
+			ret=(strncasecmp(str->s, (char*)param, str->len)!=0);
284
+			break;
285
+		case MATCH_OP:
286
+			if (subtype!=RE_ST){
287
+				LOG(L_CRIT, "BUG: comp_str: bad type %d, "
288
+						" RE expected\n", subtype);
289
+				goto error;
290
+			}
281 291
 		/* this is really ugly -- we put a temporary zero-terminating
282 292
 		 * character in the original string; that's because regexps
283 293
          * take 0-terminated strings and our messages are not
... ...
@@ -291,12 +315,13 @@ inline static int comp_strstr(str* str, void* param, int op, int subtype)
291 291
          * which might be too slow
292 292
          * -jiri
293 293
          */
294
-		backup=str->s[str->len];str->s[str->len]=0;
295
-		ret=(regexec((regex_t*)param, str->s, 0, 0, 0)==0);
296
-		str->s[str->len]=backup;
297
-	}else{
298
-		LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op);
299
-		goto error;
294
+			backup=str->s[str->len];str->s[str->len]=0;
295
+			ret=(regexec((regex_t*)param, str->s, 0, 0, 0)==0);
296
+			str->s[str->len]=backup;
297
+			break;
298
+		default:
299
+			LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op);
300
+			goto error;
300 301
 	}
301 302
 	return ret;
302 303
 	
... ...
@@ -310,23 +335,34 @@ inline static int comp_str(char* str, void* param, int op, int subtype)
310 310
 	int ret;
311 311
 	
312 312
 	ret=-1;
313
-	if (op==EQUAL_OP){
314
-		if (subtype!=STRING_ST){
315
-			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
316
-					"string expected\n", subtype);
317
-			goto error;
318
-		}
319
-		ret=(strcasecmp(str, (char*)param)==0);
320
-	}else if (op==MATCH_OP){
321
-		if (subtype!=RE_ST){
322
-			LOG(L_CRIT, "BUG: comp_str: bad type %d, "
323
-					" RE expected\n", subtype);
313
+	switch(op){
314
+		case EQUAL_OP:
315
+			if (subtype!=STRING_ST){
316
+				LOG(L_CRIT, "BUG: comp_str: bad type %d, "
317
+						"string expected\n", subtype);
318
+				goto error;
319
+			}
320
+			ret=(strcasecmp(str, (char*)param)==0);
321
+			break;
322
+		case DIFF_OP:
323
+			if (subtype!=STRING_ST){
324
+				LOG(L_CRIT, "BUG: comp_str: bad type %d, "
325
+						"string expected\n", subtype);
326
+				goto error;
327
+			}
328
+			ret=(strcasecmp(str, (char*)param)!=0);
329
+			break;
330
+		case MATCH_OP:
331
+			if (subtype!=RE_ST){
332
+				LOG(L_CRIT, "BUG: comp_str: bad type %d, "
333
+						" RE expected\n", subtype);
334
+				goto error;
335
+			}
336
+			ret=(regexec((regex_t*)param, str, 0, 0, 0)==0);
337
+			break;
338
+		default:
339
+			LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op);
324 340
 			goto error;
325
-		}
326
-		ret=(regexec((regex_t*)param, str, 0, 0, 0)==0);
327
-	}else{
328
-		LOG(L_CRIT, "BUG: comp_str: unknown op %d\n", op);
329
-		goto error;
330 341
 	}
331 342
 	return ret;
332 343
 	
... ...
@@ -335,6 +371,25 @@ error:
335 335
 }
336 336
 
337 337
 
338
+/* check_self wrapper -- it checks also for the op */
339
+inline static int check_self_op(int op, str* s, unsigned short p)
340
+{
341
+	int ret;
342
+	
343
+	ret=check_self(s, p);
344
+	switch(op){
345
+		case EQUAL_OP:
346
+			break;
347
+		case DIFF_OP:
348
+			if (ret>=0) ret=!ret;
349
+			break;
350
+		default:
351
+			LOG(L_CRIT, "BUG: check_self_op: invalid operator %d\n", op);
352
+			ret=-1;
353
+	}
354
+	return ret;
355
+}
356
+
338 357
 
339 358
 /* eval_elem helping function, returns an op param */
340 359
 inline static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
... ...
@@ -347,45 +402,67 @@ inline static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
347 347
 	ret=-1;
348 348
 	switch(subtype){
349 349
 		case NET_ST:
350
-			ret=matchnet(ip, (struct net*) param);
351
-			/*ret=(a&((struct net*)param)->mask)==((struct net*)param)->ip;*/
350
+			switch(op){
351
+				case EQUAL_OP:
352
+					ret=(matchnet(ip, (struct net*) param)==1);
353
+					break;
354
+				case DIFF_OP:
355
+					ret=(matchnet(ip, (struct net*) param)!=1);
356
+					break;
357
+				default:
358
+					goto error_op;
359
+			}
352 360
 			break;
353 361
 		case STRING_ST:
354 362
 		case RE_ST:
355
-			/* 1: compare with ip2str*/
356
-			ret=comp_str(ip_addr2a(ip), param, op, subtype);
357
-			if (ret==1) break;
358
-			/* 2: resolve (name) & compare w/ all the ips */
359
-			he=resolvehost((char*)param);
360
-			if (he==0){
361
-				DBG("comp_ip: could not resolve %s\n", (char*)param);
362
-			}else if (he->h_addrtype==ip->af){
363
-				for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
364
-					ret=(memcmp(ip->u.addr, *h, ip->len)==0);
365
-				}
366
-				if (ret==1) break;
367
-			}
368
-			/* 3: (slow) rev dns the address
369
-			 * and compare with all the aliases
370
-			 * !!??!! review: remove this? */
371
-			he=rev_resolvehost(ip);
372
-			if (he==0){
373
-				print_ip( "comp_ip: could not rev_resolve ip address: ",
374
-							ip, "\n");
375
-				ret=0;
376
-			}else{
377
-				/*  compare with primary host name */
378
-				ret=comp_str(he->h_name, param, op, subtype);
379
-				/* compare with all the aliases */
380
-				for(h=he->h_aliases; (ret!=1) && (*h); h++){
381
-					ret=comp_str(*h, param, op, subtype);
382
-				}
363
+			switch(op){
364
+				case EQUAL_OP:
365
+				case MATCH_OP:
366
+					/* 1: compare with ip2str*/
367
+					ret=comp_str(ip_addr2a(ip), param, op, subtype);
368
+					if (ret==1) break;
369
+					/* 2: resolve (name) & compare w/ all the ips */
370
+					if (subtype==STRING_ST){
371
+						he=resolvehost((char*)param);
372
+						if (he==0){
373
+							DBG("comp_ip: could not resolve %s\n",
374
+									(char*)param);
375
+						}else if (he->h_addrtype==ip->af){
376
+							for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
377
+								ret=(memcmp(ip->u.addr, *h, ip->len)==0);
378
+							}
379
+							if (ret==1) break;
380
+						}
381
+					}
382
+					/* 3: (slow) rev dns the address
383
+					* and compare with all the aliases
384
+					* !!??!! review: remove this? */
385
+					he=rev_resolvehost(ip);
386
+					if (he==0){
387
+						print_ip( "comp_ip: could not rev_resolve ip address:"
388
+									" ", ip, "\n");
389
+					ret=0;
390
+					}else{
391
+						/*  compare with primary host name */
392
+						ret=comp_str(he->h_name, param, op, subtype);
393
+						/* compare with all the aliases */
394
+						for(h=he->h_aliases; (ret!=1) && (*h); h++){
395
+							ret=comp_str(*h, param, op, subtype);
396
+						}
397
+					}
398
+					break;
399
+				case DIFF_OP:
400
+					ret=comp_ip(ip, param, EQUAL_OP, subtype);
401
+					if (ret>=0) ret=!ret;
402
+					break;
403
+				default:
404
+					goto error_op;
383 405
 			}
384 406
 			break;
385 407
 		case MYSELF_ST: /* check if it's one of our addresses*/
386 408
 			tmp.s=ip_addr2a(ip);
387 409
 			tmp.len=strlen(tmp.s);
388
-			ret=check_self(&tmp, 0);
410
+			ret=check_self_op(op, &tmp, 0);
389 411
 			break;
390 412
 		default:
391 413
 			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
... ...
@@ -393,6 +470,9 @@ inline static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
393 393
 			ret=-1;
394 394
 	}
395 395
 	return ret;
396
+error_op:
397
+	LOG(L_CRIT, "BUG: comp_ip: invalid operator %d\n", op);
398
+	return -1;
396 399
 	
397 400
 }
398 401
 
... ...
@@ -418,7 +498,7 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
418 418
 				if(msg->new_uri.s){
419 419
 					if (e->subtype==MYSELF_ST){
420 420
 						if (parse_sip_msg_uri(msg)<0) ret=-1;
421
-						else	ret=check_self(&msg->parsed_uri.host,
421
+						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
422 422
 									msg->parsed_uri.port_no?
423 423
 									msg->parsed_uri.port_no:SIP_PORT);
424 424
 					}else{
... ...
@@ -428,7 +508,7 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
428 428
 				}else{
429 429
 					if (e->subtype==MYSELF_ST){
430 430
 						if (parse_sip_msg_uri(msg)<0) ret=-1;
431
-						else	ret=check_self(&msg->parsed_uri.host,
431
+						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
432 432
 									msg->parsed_uri.port_no?
433 433
 									msg->parsed_uri.port_no:SIP_PORT);
434 434
 					}else{
... ...
@@ -467,6 +547,9 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
467 467
 		case AF_O:
468 468
 				ret=comp_no(msg->rcv.src_ip.af, e->r.param, e->op, e->subtype);
469 469
 				break;
470
+		case MSGLEN_O:
471
+				ret=comp_no(msg->len, e->r.param, e->op, e->subtype);
472
+				break;
470 473
 		default:
471 474
 				LOG(L_CRIT, "BUG: eval_elem: invalid operand %d\n",
472 475
 							e->l.operand);
... ...
@@ -30,6 +30,7 @@
30 30
  *
31 31
  *  2003-04-12  FORCE_RPORT_T added (andrei)
32 32
  *  2003-04-22  strip_tail added (jiri)
33
+ *  2003-10-10  >,<,>=,<=, != and MSGLEN_O added (andrei)
33 34
  */
34 35
 
35 36
 
... ...
@@ -51,9 +52,10 @@
51 51
 
52 52
 enum { EXP_T=1, ELEM_T };
53 53
 enum { AND_OP=1, OR_OP, NOT_OP };
54
-enum { EQUAL_OP=10, MATCH_OP, NO_OP };
54
+enum { EQUAL_OP=10, MATCH_OP, GT_OP, LT_OP, GTE_OP, LTE_OP, DIFF_OP, NO_OP };
55 55
 enum { METHOD_O=1, URI_O, SRCIP_O, SRCPORT_O,
56
-	   DSTIP_O, DSTPORT_O, PROTO_O, AF_O, DEFAULT_O, ACTION_O, NUMBER_O};
56
+	   DSTIP_O, DSTPORT_O, PROTO_O, AF_O, MSGLEN_O, DEFAULT_O, ACTION_O,
57
+	   NUMBER_O};
57 58
 
58 59
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
59 60
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T, 
... ...
@@ -52,7 +52,7 @@ is a very fast and configurable SIP proxy.
52 52
 Displays a short usage description, including all available options.
53 53
 .TP
54 54
 .BI \-c
55
-Performs loop checks and computes branches.
55
+Checks the config file and displays the aliases and listen interface list.
56 56
 .TP
57 57
 .BI \-r
58 58
 Uses dns to check if it is necessary to add a "received=" field to a via.