[syslog-ng][PATCH] netmask-filter

Gert Menke gert@menke.za.net
Sun, 20 Jan 2002 01:17:08 +0100


--AqsLC8rIMeq19msA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi everybody,

I have implemented a new filter for syslog-ng.
You can now filter log messages based on their sender's IP address like this:

  # match a single host
  filter f_noc21 { netmask("134.130.3.73"); };

  # match a whole subnet
  filter f_noc { netmask("134.130.3.0/255.255.255.0"); };

I'll attach patches for syslog-ng versions 1.4.14 and 1.5.13.

I have also made a small patch that fixes the behaviour of the emulated
inet_aton function in utils.c. (It would not work with "255.255.255.255".)
On some architectures you need this patch for my netmask-filter to work
properly!

Have fun and tell me what you think about it!

Greetings
Gert

--AqsLC8rIMeq19msA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="syslog-ng-1.4.14-netmask.patch"

diff -U3 -r syslog-ng-1.4.14/src/cfg-grammar.y syslog-ng-1.4.14nm/src/cfg-grammar.y
--- syslog-ng-1.4.14/src/cfg-grammar.y	Sun Feb 25 13:30:22 2001
+++ syslog-ng-1.4.14nm/src/cfg-grammar.y	Tue Jan 15 16:01:43 2002
@@ -73,7 +73,7 @@
 %token KW_COMPRESS KW_MAC KW_AUTH KW_ENCRYPT
 
 /* filter items*/
-%token KW_FACILITY KW_LEVEL KW_PROGRAM KW_HOST KW_MATCH
+%token KW_FACILITY KW_LEVEL KW_PROGRAM KW_NETMASK KW_HOST KW_MATCH
 
 /* yes/no switches */
 %token KW_YES KW_NO
@@ -522,6 +522,7 @@
 	| KW_FACILITY '(' NUMBER ')'		{ $$ = make_filter_facility(0x80000000 | $3); }
 	| KW_LEVEL '(' filter_level_list ')' 	{ $$ = make_filter_level($3); }
 	| KW_PROGRAM '(' string ')'		{ $$ = make_filter_prog($3); free($3); }
+	| KW_NETMASK '(' string ')'		{ $$ = make_filter_netmask($3); free($3); }	
 	| KW_HOST '(' string ')'		{ $$ = make_filter_host($3); free($3); }	
 	| KW_MATCH '(' string ')'		{ $$ = make_filter_match($3); free($3); }
 	| KW_FILTER '(' string ')'		{ $$ = make_filter_call($3); free($3); }
diff -U3 -r syslog-ng-1.4.14/src/cfg-lex.l syslog-ng-1.4.14nm/src/cfg-lex.l
--- syslog-ng-1.4.14/src/cfg-lex.l	Sun Feb 25 13:30:22 2001
+++ syslog-ng-1.4.14nm/src/cfg-lex.l	Tue Jan 15 16:03:02 2002
@@ -111,6 +111,7 @@
 	{ "priority",           KW_LEVEL },
 	{ "facility",           KW_FACILITY },
 	{ "program",		KW_PROGRAM },
+        { "netmask",            KW_NETMASK },
         { "host",               KW_HOST },
         { "match",		KW_MATCH },
 
diff -U3 -r syslog-ng-1.4.14/src/filters.c syslog-ng-1.4.14nm/src/filters.c
--- syslog-ng-1.4.14/src/filters.c	Wed May 16 09:13:57 2001
+++ syslog-ng-1.4.14nm/src/filters.c	Thu Jan 17 14:25:19 2002
@@ -35,6 +35,10 @@
 #include "filters.h.x"
 #undef CLASS_DEFINE
 
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 static void free_regexp(regex_t *re);
 
 #include "filters.c.x"
@@ -153,6 +157,86 @@
 	return &self->super;
 }
 
+/* CLASS:
+   (class
+     (name filter_expr_netmask)
+     (super filter_expr_node)
+     (vars
+       (network simple "struct in_addr")
+       (netmask simple "struct in_addr")))
+*/
+
+static int do_filter_netmask(struct filter_expr_node *c, 
+			     struct log_filter *rule UNUSED,
+			     struct log_info *log)
+{
+	char a_host[16]="";
+	char a_netw[16]="";
+	char a_mask[16]="";
+
+	CAST(filter_expr_netmask, self, c);
+	CAST(inet_address_info, adrinf, log->saddr);
+
+	in_addr_t host;
+	in_addr_t netw;
+	in_addr_t mask;
+
+	if(adrinf==NULL) {
+		return 0;
+	}
+
+	host = adrinf->sa.sin_addr.s_addr;
+	netw = self->network.s_addr;
+	mask = self->netmask.s_addr;
+
+	strcpy (a_host, inet_ntoa(adrinf->sa.sin_addr));
+	strcpy (a_netw, inet_ntoa(self->network));
+	strcpy (a_mask, inet_ntoa(self->netmask));
+
+	return ( (host & mask) == (netw & mask) );
+}
+
+struct filter_expr_node *make_filter_netmask(const char *nm)
+{
+	char a_nw[16]="";
+	char a_nm[16]="255.255.255.255";
+	int i;
+
+	NEW(filter_expr_netmask, self);
+
+	self->super.eval = do_filter_netmask;
+
+	for (i=0; nm[i] != 0 && nm[i] != '/'; i++) {
+		if(i>=15) {
+			/* no ip address can be longer than 15 bytes! */
+			KILL(self);
+			return NULL;
+		}
+		a_nw[i]=nm[i];
+	}
+	a_nw[i]=0;
+
+	if(nm[i]) {
+		nm+=i+1;
+		for (i=0; nm[i] != 0 && nm[i] != '/'; i++) {
+			if(i>=15) {
+				/* no ip address can be longer than 15 bytes! */
+				KILL(self);
+				return NULL;
+			}
+			a_nm[i]=nm[i];
+		}
+		a_nm[i]=0;
+	}
+
+	if (! (inet_aton(a_nw, &self->network) && inet_aton(a_nm, &self->netmask)) ) {
+		KILL(self);
+		return NULL;
+	}
+
+	return &self->super;
+}
+
 /* CLASS:
    (class
      (name filter_expr_re)
diff -U3 -r syslog-ng-1.4.14/src/filters.c.x syslog-ng-1.4.14nm/src/filters.c.x
--- syslog-ng-1.4.14/src/filters.c.x	Sun Jun 17 14:01:20 2001
+++ syslog-ng-1.4.14nm/src/filters.c.x	Tue Jan 15 16:20:10 2002
@@ -44,6 +44,25 @@
 #endif /* !CLASS_DECLARE */
 
 #ifndef CLASS_DEFINE
+struct filter_expr_netmask
+{
+  struct filter_expr_node super;
+  struct in_addr network;
+  struct in_addr netmask;
+};
+extern struct ol_class filter_expr_netmask_class;
+#endif /* !CLASS_DEFINE */
+
+#ifndef CLASS_DECLARE
+struct ol_class filter_expr_netmask_class =
+{ STATIC_HEADER,
+  &filter_expr_node_class, "filter_expr_netmask", sizeof(struct filter_expr_netmask),
+  NULL,
+  NULL
+};
+#endif /* !CLASS_DECLARE */
+
+#ifndef CLASS_DEFINE
 struct filter_expr_re
 {
   struct filter_expr_node super;
diff -U3 -r syslog-ng-1.4.14/src/filters.h syslog-ng-1.4.14nm/src/filters.h
--- syslog-ng-1.4.14/src/filters.h	Sun Feb 25 13:30:22 2001
+++ syslog-ng-1.4.14nm/src/filters.h	Tue Jan 15 15:59:01 2002
@@ -63,6 +63,7 @@
 struct filter_expr_node *make_filter_facility(UINT32 valid);
 struct filter_expr_node *make_filter_level(UINT32 valid);
 struct filter_expr_node *make_filter_prog(const char *name);
+struct filter_expr_node *make_filter_netmask(const char *nm);
 struct filter_expr_node *make_filter_host(const char *re);
 struct filter_expr_node *make_filter_match(const char *re);
 struct filter_expr_node *make_filter_call(const char *name);

--AqsLC8rIMeq19msA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="syslog-ng-1.5.13-netmask.patch"

diff -U3 -r syslog-ng-1.5.13/src/cfg-grammar.y syslog-ng-1.5.13nm/src/cfg-grammar.y
--- syslog-ng-1.5.13/src/cfg-grammar.y	Mon Sep  3 18:46:01 2001
+++ syslog-ng-1.5.13nm/src/cfg-grammar.y	Thu Jan 10 15:19:42 2002
@@ -77,7 +77,7 @@
 %token KW_DNS_CACHE_EXPIRE KW_DNS_CACHE_EXPIRE_FAILED
 
 /* filter items*/
-%token KW_FACILITY KW_LEVEL KW_HOST KW_MATCH
+%token KW_FACILITY KW_LEVEL KW_NETMASK KW_HOST KW_MATCH
 
 /* yes/no switches */
 %token KW_YES KW_NO
@@ -580,6 +580,7 @@
 	| KW_FACILITY '(' NUMBER ')'		{ $$ = make_filter_facility(0x80000000 | $3); }
 	| KW_LEVEL '(' filter_level_list ')' 	{ $$ = make_filter_level($3); }
 	| KW_PROGRAM '(' string ')'		{ $$ = make_filter_prog($3); free($3); }
+	| KW_NETMASK '(' string ')'		{ $$ = make_filter_netmask($3); free($3); }	
 	| KW_HOST '(' string ')'		{ $$ = make_filter_host($3); free($3); }	
 	| KW_MATCH '(' string ')'		{ $$ = make_filter_match($3); free($3); }
 	| KW_FILTER '(' string ')'		{ $$ = make_filter_call($3); free($3); }
diff -U3 -r syslog-ng-1.5.13/src/cfg-lex.l syslog-ng-1.5.13nm/src/cfg-lex.l
--- syslog-ng-1.5.13/src/cfg-lex.l	Mon Sep  3 18:46:01 2001
+++ syslog-ng-1.5.13nm/src/cfg-lex.l	Thu Jan 10 15:18:53 2002
@@ -125,6 +125,7 @@
 	{ "priority",           KW_LEVEL },
 	{ "facility",           KW_FACILITY },
 	{ "program",		KW_PROGRAM },
+        { "netmask",            KW_NETMASK },
         { "host",               KW_HOST },
         { "match",		KW_MATCH },
 
diff -U3 -r syslog-ng-1.5.13/src/filters.c syslog-ng-1.5.13nm/src/filters.c
--- syslog-ng-1.5.13/src/filters.c	Mon May 14 11:07:25 2001
+++ syslog-ng-1.5.13nm/src/filters.c	Thu Jan 17 14:32:56 2002
@@ -35,6 +35,10 @@
 #include "filters.h.x"
 #undef CLASS_DEFINE
 
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 static void free_regexp(regex_t *re);
 
 #include "filters.c.x"
@@ -153,6 +157,86 @@
 	return &self->super;
 }
 
+/* CLASS:
+   (class
+     (name filter_expr_netmask)
+     (super filter_expr_node)
+     (vars
+       (network simple "struct in_addr")
+       (netmask simple "struct in_addr")))
+*/
+
+static int do_filter_netmask(struct filter_expr_node *c, 
+			     struct log_filter *rule UNUSED,
+			     struct log_info *log)
+{
+	char a_host[16]="";
+	char a_netw[16]="";
+	char a_mask[16]="";
+
+	CAST(filter_expr_netmask, self, c);
+	CAST(inet_address_info, adrinf, log->saddr);
+
+	in_addr_t host;
+	in_addr_t netw;
+	in_addr_t mask;
+
+	if(adrinf==NULL) {
+		return 0;
+	}
+
+	host = adrinf->sa.sin_addr.s_addr;
+	netw = self->network.s_addr;
+	mask = self->netmask.s_addr;
+
+	strcpy (a_host, inet_ntoa(adrinf->sa.sin_addr));
+	strcpy (a_netw, inet_ntoa(self->network));
+	strcpy (a_mask, inet_ntoa(self->netmask));
+
+	return ( (host & mask) == (netw & mask) );
+}
+
+struct filter_expr_node *make_filter_netmask(const char *nm)
+{
+	char a_nw[16]="";
+	char a_nm[16]="255.255.255.255";
+	int i;
+
+	NEW(filter_expr_netmask, self);
+
+	self->super.eval = do_filter_netmask;
+
+	for (i=0; nm[i] != 0 && nm[i] != '/'; i++) {
+		if(i>=15) {
+			/* no ip address can be longer than 15 bytes! */
+			KILL(self);
+			return NULL;
+		}
+		a_nw[i]=nm[i];
+	}
+	a_nw[i]=0;
+
+	if(nm[i]) {
+		nm+=i+1;
+		for (i=0; nm[i] != 0 && nm[i] != '/'; i++) {
+			if(i>=15) {
+				/* no ip address can be longer than 15 bytes! */
+				KILL(self);
+				return NULL;
+			}
+			a_nm[i]=nm[i];
+		}
+		a_nm[i]=0;
+	}
+
+	if (! (inet_aton(a_nw, &self->network) && inet_aton(a_nm, &self->netmask)) ) {
+		KILL(self);
+		return NULL;
+	}
+
+	return &self->super;
+}
+
 /* CLASS:
    (class
      (name filter_expr_re)
diff -U3 -r syslog-ng-1.5.13/src/filters.c.x syslog-ng-1.5.13nm/src/filters.c.x
--- syslog-ng-1.5.13/src/filters.c.x	Fri Jun  8 09:42:03 2001
+++ syslog-ng-1.5.13nm/src/filters.c.x	Thu Jan 17 14:35:06 2002
@@ -44,6 +44,25 @@
 #endif /* !CLASS_DECLARE */
 
 #ifndef CLASS_DEFINE
+struct filter_expr_netmask
+{
+  struct filter_expr_node super;
+  struct in_addr network;
+  struct in_addr netmask;
+};
+extern struct ol_class filter_expr_netmask_class;
+#endif /* !CLASS_DEFINE */
+
+#ifndef CLASS_DECLARE
+struct ol_class filter_expr_netmask_class =
+{ STATIC_HEADER,
+  &filter_expr_node_class, "filter_expr_netmask", sizeof(struct filter_expr_netmask),
+  NULL,
+  NULL
+};
+#endif /* !CLASS_DECLARE */
+
+#ifndef CLASS_DEFINE
 struct filter_expr_re
 {
   struct filter_expr_node super;
diff -U3 -r syslog-ng-1.5.13/src/filters.h syslog-ng-1.5.13nm/src/filters.h
--- syslog-ng-1.5.13/src/filters.h	Sun Feb 25 13:00:22 2001
+++ syslog-ng-1.5.13nm/src/filters.h	Thu Jan 10 15:20:36 2002
@@ -63,6 +63,7 @@
 struct filter_expr_node *make_filter_facility(UINT32 valid);
 struct filter_expr_node *make_filter_level(UINT32 valid);
 struct filter_expr_node *make_filter_prog(const char *name);
+struct filter_expr_node *make_filter_netmask(const char *nm);
 struct filter_expr_node *make_filter_host(const char *re);
 struct filter_expr_node *make_filter_match(const char *re);
 struct filter_expr_node *make_filter_call(const char *name);

--AqsLC8rIMeq19msA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="syslog-ng-inet_aton.patch"

diff -U3 -r syslog-ng-1.4.14nm/src/utils.c syslog-ng-1.4.14nm_aton/src/utils.c
--- syslog-ng-1.4.14nm/src/utils.c	Sun Feb 25 13:30:22 2001
+++ syslog-ng-1.4.14nm_aton/src/utils.c	Thu Jan 17 13:56:48 2002
@@ -53,6 +53,11 @@
 #if !HAVE_INET_ATON
 int inet_aton(const char *cp, struct in_addr *addr)
 {
+	if(!strcmp(cp,"255.255.255.255")) {
+		addr->s_addr = 0xFFFFFFFF;
+		return 1;
+	}
+
 	addr->s_addr = inet_addr(cp);
 	if (addr->s_addr == -1) 
 		return 0;

--AqsLC8rIMeq19msA--