netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] ulogd2 supports nfacct infrastructure
@ 2012-02-22 12:33 pablo
  2012-02-22 12:33 ` [PATCH 1/3] output: add GPRINT plugin pablo
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: pablo @ 2012-02-22 12:33 UTC (permalink / raw)
  To: netfilter-devel

From: Pablo Neira Ayuso <pablo@netfilter.org>

Hi,

The upcoming kernel will contain the nfacct infrastructure:

http://lwn.net/Articles/473998/

This patchset contains the support for ulogd2. It also contains the
GPRINT output plugin, that is a generic output in comma-separated
key-value format.

I pushed the patches to git.netfilter.org, if you find any issue,
please send me follow-up patches and I'll apply them.

Thanks!

Pablo Neira Ayuso (3):
  output: add GPRINT plugin
  input: add nfacct plugin
  src: add example use of GPRINT to ulogd.conf.in configuration file

 configure.ac                             |    4 +
 include/Makefile.am                      |    2 +-
 include/linux/Makefile.am                |    2 +
 include/linux/netfilter/Makefile.am      |    2 +
 include/linux/netfilter/nfnetlink_acct.h |   36 ++++
 input/Makefile.am                        |    2 +-
 input/sum/Makefile.am                    |    8 +
 input/sum/ulogd_inpflow_NFACCT.c         |  265 +++++++++++++++++++++++++++++
 output/Makefile.am                       |    5 +-
 output/ulogd_output_GPRINT.c             |  270 ++++++++++++++++++++++++++++++
 ulogd.conf.in                            |   21 ++-
 11 files changed, 611 insertions(+), 6 deletions(-)
 create mode 100644 include/linux/Makefile.am
 create mode 100644 include/linux/netfilter/Makefile.am
 create mode 100644 include/linux/netfilter/nfnetlink_acct.h
 create mode 100644 input/sum/Makefile.am
 create mode 100644 input/sum/ulogd_inpflow_NFACCT.c
 create mode 100644 output/ulogd_output_GPRINT.c

-- 
1.7.7.3


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] output: add GPRINT plugin
  2012-02-22 12:33 [PATCH 0/3] ulogd2 supports nfacct infrastructure pablo
@ 2012-02-22 12:33 ` pablo
  2012-02-22 12:33 ` [PATCH 2/3] input: add nfacct plugin pablo
  2012-02-22 12:33 ` [PATCH 3/3] src: add example use of GPRINT to ulogd.conf.in configuration file pablo
  2 siblings, 0 replies; 4+ messages in thread
From: pablo @ 2012-02-22 12:33 UTC (permalink / raw)
  To: netfilter-devel

From: Pablo Neira Ayuso <pablo@netfilter.org>

This patch adds GPRINT which is a generalization of OPRINT.

It display the set of key-values separated by commas. This is
the generic print that you can attach to whatever kind of
input plugin.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 output/Makefile.am           |    5 +-
 output/ulogd_output_GPRINT.c |  270 ++++++++++++++++++++++++++++++++++++++++++
 ulogd.conf.in                |    6 +
 3 files changed, 280 insertions(+), 1 deletions(-)
 create mode 100644 output/ulogd_output_GPRINT.c

diff --git a/output/Makefile.am b/output/Makefile.am
index 2ec6e8d..bb93b28 100644
--- a/output/Makefile.am
+++ b/output/Makefile.am
@@ -5,9 +5,12 @@ AM_CFLAGS = ${regular_CFLAGS} ${LIBNETFILTER_LOG_CFLAGS} \
 SUBDIRS= pcap mysql pgsql sqlite3 dbi
 
 pkglibexec_LTLIBRARIES = ulogd_output_LOGEMU.la ulogd_output_SYSLOG.la \
-			 ulogd_output_OPRINT.la \
+			 ulogd_output_OPRINT.la ulogd_output_GPRINT.la \
 			 ulogd_output_NACCT.la ulogd_output_XML.la
 
+ulogd_output_GPRINT_la_SOURCES = ulogd_output_GPRINT.c
+ulogd_output_GPRINT_la_LDFLAGS = -avoid-version -module
+
 ulogd_output_LOGEMU_la_SOURCES = ulogd_output_LOGEMU.c
 ulogd_output_LOGEMU_la_LDFLAGS = -avoid-version -module
 
diff --git a/output/ulogd_output_GPRINT.c b/output/ulogd_output_GPRINT.c
new file mode 100644
index 0000000..759a0ca
--- /dev/null
+++ b/output/ulogd_output_GPRINT.c
@@ -0,0 +1,270 @@
+/* ulogd_GPRINT.c
+ *
+ * ulogd output target for logging to a file in comma-separated key-value.
+ * This is a generalization of ulogd_GPRINT.c
+ *
+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2012 by Intra2net AG <http://www.intra2net.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/conffile.h>
+
+#ifndef ULOGD_GPRINT_DEFAULT
+#define ULOGD_GPRINT_DEFAULT	"/var/log/ulogd.gprint"
+#endif
+
+struct gprint_priv {
+	FILE *of;
+};
+
+enum gprint_conf {
+	GPRINT_CONF_FILENAME = 0,
+	GPRINT_CONF_SYNC,
+	GPRINT_CONF_TIMESTAMP,
+	GPRINT_CONF_MAX
+};
+
+static struct config_keyset gprint_kset = {
+	.num_ces = GPRINT_CONF_MAX,
+	.ces = {
+		[GPRINT_CONF_FILENAME] = {
+			.key = "file",
+			.type = CONFIG_TYPE_STRING,
+			.options = CONFIG_OPT_NONE,
+			.u = {.string = ULOGD_GPRINT_DEFAULT },
+		},
+		[GPRINT_CONF_SYNC] = {
+			.key = "sync",
+			.type = CONFIG_TYPE_INT,
+			.options = CONFIG_OPT_NONE,
+			.u = { .value = 0 },
+		},
+		[GPRINT_CONF_TIMESTAMP] = {
+			.key = "timestamp",
+			.type = CONFIG_TYPE_INT,
+			.options = CONFIG_OPT_NONE,
+			.u = { .value = 0 },
+		},
+	},
+};
+
+#define NIPQUAD(addr) \
+        ((unsigned char *)&addr)[0], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[3]
+
+static int gprint_interp(struct ulogd_pluginstance *upi)
+{
+	struct gprint_priv *opi = (struct gprint_priv *) &upi->private;
+	unsigned int i;
+	char buf[4096];
+	int rem = sizeof(buf), size = 0, ret;
+
+	if (upi->config_kset->ces[GPRINT_CONF_TIMESTAMP].u.value != 0) {
+		struct tm tm;
+		time_t now;
+
+		now = time(NULL);
+		localtime_r(&now, &tm);
+
+		ret = snprintf(buf+size, rem,
+				"timestamp=%.4u/%.2u/%.2u-%.2u:%.2u:%.2u,",
+				1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+				tm.tm_hour, tm.tm_min, tm.tm_sec);
+		if (ret < 0)
+			return ULOGD_IRET_OK;
+		rem -= ret;
+		size += ret;
+	}
+
+	for (i = 0; i < upi->input.num_keys; i++) {
+		struct ulogd_key *key = upi->input.keys[i].u.source;
+
+		if (!key)
+			continue;
+
+		if (!IS_VALID(*key))
+			continue;
+
+		switch (key->type) {
+		case ULOGD_RET_STRING:
+			ret = snprintf(buf+size, rem, "%s=", key->name);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+
+			ret = snprintf(buf+size, rem, "%s,",
+					(char *) key->u.value.ptr);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+			break;
+		case ULOGD_RET_BOOL:
+		case ULOGD_RET_INT8:
+		case ULOGD_RET_INT16:
+		case ULOGD_RET_INT32:
+			ret = snprintf(buf+size, rem, "%s=", key->name);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+
+			ret = snprintf(buf+size, rem, "%d,", key->u.value.i32);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+			break;
+		case ULOGD_RET_UINT8:
+		case ULOGD_RET_UINT16:
+		case ULOGD_RET_UINT32:
+		case ULOGD_RET_UINT64:
+			ret = snprintf(buf+size, rem, "%s=", key->name);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+
+			ret = snprintf(buf+size, rem, "%lu,",
+					key->u.value.ui64);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+			break;
+		case ULOGD_RET_IPADDR:
+			ret = snprintf(buf+size, rem, "%s=", key->name);
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+
+			ret = snprintf(buf+size, rem, "%u.%u.%u.%u,",
+				NIPQUAD(key->u.value.ui32));
+			if (ret < 0)
+				break;
+			rem -= ret;
+			size += ret;
+			break;
+		default:
+			/* don't know how to interpret this key. */
+			break;
+		}
+	}
+	buf[size-1]='\0';
+	fprintf(opi->of, "%s\n", buf);
+
+	if (upi->config_kset->ces[GPRINT_CONF_SYNC].u.value != 0)
+		fflush(opi->of);
+
+	return ULOGD_IRET_OK;
+}
+
+static void sighup_handler_print(struct ulogd_pluginstance *upi, int signal)
+{
+	struct gprint_priv *oi = (struct gprint_priv *) &upi->private;
+	FILE *old = oi->of;
+
+	switch (signal) {
+	case SIGHUP:
+		ulogd_log(ULOGD_NOTICE, "GPRINT: reopening logfile\n");
+		oi->of = fopen(upi->config_kset->ces[0].u.string, "a");
+		if (!oi->of) {
+			ulogd_log(ULOGD_ERROR, "can't open GPRINT "
+					       "log file: %s\n",
+				  strerror(errno));
+			oi->of = old;
+		} else {
+			fclose(old);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static int gprint_configure(struct ulogd_pluginstance *upi,
+			    struct ulogd_pluginstance_stack *stack)
+{
+	int ret;
+
+	ret = ulogd_wildcard_inputkeys(upi);
+	if (ret < 0)
+		return ret;
+
+	ret = config_parse_file(upi->id, upi->config_kset);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int gprint_init(struct ulogd_pluginstance *upi)
+{
+	struct gprint_priv *op = (struct gprint_priv *) &upi->private;
+
+	op->of = fopen(upi->config_kset->ces[0].u.string, "a");
+	if (!op->of) {
+		ulogd_log(ULOGD_FATAL, "can't open GPRINT log file: %s\n", 
+			strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+static int gprint_fini(struct ulogd_pluginstance *pi)
+{
+	struct gprint_priv *op = (struct gprint_priv *) &pi->private;
+
+	if (op->of != stdout)
+		fclose(op->of);
+
+	return 0;
+}
+
+static struct ulogd_plugin gprint_plugin = {
+	.name = "GPRINT",
+	.input = {
+		.type = ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW,
+	},
+	.output = {
+		.type = ULOGD_DTYPE_SINK,
+	},
+	.configure = &gprint_configure,
+	.interp	= &gprint_interp,
+	.start 	= &gprint_init,
+	.stop	= &gprint_fini,
+	.signal = &sighup_handler_print,
+	.config_kset = &gprint_kset,
+	.version = ULOGD_VERSION,
+};
+
+void __attribute__ ((constructor)) init(void);
+
+void init(void)
+{
+	ulogd_register_plugin(&gprint_plugin);
+}
diff --git a/ulogd.conf.in b/ulogd.conf.in
index ac7bcae..c0c8559 100644
--- a/ulogd.conf.in
+++ b/ulogd.conf.in
@@ -42,6 +42,7 @@ plugin="@pkglibexecdir@/ulogd_output_SYSLOG.so"
 plugin="@pkglibexecdir@/ulogd_output_XML.so"
 #plugin="@pkglibexecdir@/ulogd_output_SQLITE3.so"
 #plugin="@pkglibexecdir@/ulogd_output_OPRINT.so"
+plugin="@pkglibexecdir@/ulogd_output_GPRINT.so"
 #plugin="@pkglibexecdir@/ulogd_output_NACCT.so"
 #plugin="@pkglibexecdir@/ulogd_output_PCAP.so"
 #plugin="@pkglibexecdir@/ulogd_output_PGSQL.so"
@@ -167,6 +168,11 @@ sync=1
 file="/var/log/ulogd_oprint.log"
 sync=1
 
+[gp1]
+file="/var/log/ulogd_gprint.log"
+sync=1
+timestamp=1
+
 [xml1]
 directory="/var/log/"
 sync=1
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] input: add nfacct plugin
  2012-02-22 12:33 [PATCH 0/3] ulogd2 supports nfacct infrastructure pablo
  2012-02-22 12:33 ` [PATCH 1/3] output: add GPRINT plugin pablo
@ 2012-02-22 12:33 ` pablo
  2012-02-22 12:33 ` [PATCH 3/3] src: add example use of GPRINT to ulogd.conf.in configuration file pablo
  2 siblings, 0 replies; 4+ messages in thread
From: pablo @ 2012-02-22 12:33 UTC (permalink / raw)
  To: netfilter-devel

From: Pablo Neira Ayuso <pablo@netfilter.org>

This patch adds the nfacct plugin.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 configure.ac                             |    4 +
 include/Makefile.am                      |    2 +-
 include/linux/Makefile.am                |    2 +
 include/linux/netfilter/Makefile.am      |    2 +
 include/linux/netfilter/nfnetlink_acct.h |   36 ++++
 input/Makefile.am                        |    2 +-
 input/sum/Makefile.am                    |    8 +
 input/sum/ulogd_inpflow_NFACCT.c         |  265 ++++++++++++++++++++++++++++++
 ulogd.conf.in                            |    7 +
 9 files changed, 326 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/Makefile.am
 create mode 100644 include/linux/netfilter/Makefile.am
 create mode 100644 include/linux/netfilter/nfnetlink_acct.h
 create mode 100644 input/sum/Makefile.am
 create mode 100644 input/sum/ulogd_inpflow_NFACCT.c

diff --git a/configure.ac b/configure.ac
index 132cdbf..89fc338 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,8 @@ AC_SUBST([regular_CFLAGS])
 
 dnl Check for the right nfnetlink version
 PKG_CHECK_MODULES([LIBNFNETLINK], [libnfnetlink >= 0.0.39])
+PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.0])
+PKG_CHECK_MODULES([LIBNETFILTER_ACCT], [libnetfilter_acct >= 1.0.0])
 PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 0.0.95])
 PKG_CHECK_MODULES([LIBNETFILTER_LOG], [libnetfilter_log >= 1.0.0])
 
@@ -74,8 +76,10 @@ dnl AM_CONDITIONAL(HAVE_MYSQL, test x$mysqldir != x)
 dnl AM_CONDITIONAL(HAVE_PGSQL, test x$pgsqldir != x)
 
 AC_CONFIG_FILES(include/Makefile include/ulogd/Makefile include/libipulog/Makefile \
+	  include/linux/Makefile include/linux/netfilter/Makefile \
 	  libipulog/Makefile \
 	  input/Makefile input/packet/Makefile input/flow/Makefile \
+	  input/sum/Makefile \
 	  filter/Makefile filter/raw2packet/Makefile filter/packet2flow/Makefile \
 	  output/Makefile output/pcap/Makefile output/mysql/Makefile output/pgsql/Makefile output/sqlite3/Makefile \
 	  output/dbi/Makefile \
diff --git a/include/Makefile.am b/include/Makefile.am
index fa34473..c62b497 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1 +1 @@
-SUBDIRS = ulogd libipulog
+SUBDIRS = ulogd libipulog linux
diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am
new file mode 100644
index 0000000..ca80d0d
--- /dev/null
+++ b/include/linux/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = netfilter
diff --git a/include/linux/netfilter/Makefile.am b/include/linux/netfilter/Makefile.am
new file mode 100644
index 0000000..fc05a9c
--- /dev/null
+++ b/include/linux/netfilter/Makefile.am
@@ -0,0 +1,2 @@
+
+noinst_HEADERS = nfnetlink_acct.h
diff --git a/include/linux/netfilter/nfnetlink_acct.h b/include/linux/netfilter/nfnetlink_acct.h
new file mode 100644
index 0000000..7c4279b
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_acct.h
@@ -0,0 +1,36 @@
+#ifndef _NFNL_ACCT_H_
+#define _NFNL_ACCT_H_
+
+#ifndef NFACCT_NAME_MAX
+#define NFACCT_NAME_MAX		32
+#endif
+
+enum nfnl_acct_msg_types {
+	NFNL_MSG_ACCT_NEW,
+	NFNL_MSG_ACCT_GET,
+	NFNL_MSG_ACCT_GET_CTRZERO,
+	NFNL_MSG_ACCT_DEL,
+	NFNL_MSG_ACCT_MAX
+};
+
+enum nfnl_acct_type {
+	NFACCT_UNSPEC,
+	NFACCT_NAME,
+	NFACCT_PKTS,
+	NFACCT_BYTES,
+	NFACCT_USE,
+	__NFACCT_MAX
+};
+#define NFACCT_MAX (__NFACCT_MAX - 1)
+
+#ifdef __KERNEL__
+
+struct nf_acct;
+
+extern struct nf_acct *nfnl_acct_find_get(const char *filter_name);
+extern void nfnl_acct_put(struct nf_acct *acct);
+extern void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct);
+
+#endif /* __KERNEL__ */
+
+#endif /* _NFNL_ACCT_H */
diff --git a/input/Makefile.am b/input/Makefile.am
index 77f2838..5ffef1b 100644
--- a/input/Makefile.am
+++ b/input/Makefile.am
@@ -1,2 +1,2 @@
 
-SUBDIRS = packet flow
+SUBDIRS = packet flow sum
diff --git a/input/sum/Makefile.am b/input/sum/Makefile.am
new file mode 100644
index 0000000..04051b4
--- /dev/null
+++ b/input/sum/Makefile.am
@@ -0,0 +1,8 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include
+AM_CFLAGS = ${regular_CFLAGS}
+
+pkglibexec_LTLIBRARIES = ulogd_inpflow_NFACCT.la
+
+ulogd_inpflow_NFACCT_la_SOURCES = ulogd_inpflow_NFACCT.c
+ulogd_inpflow_NFACCT_la_LDFLAGS = -avoid-version -module $(LIBMNL_LIBS) $(LIBNETFILTER_ACCT_LIBS)
+ulogd_inpflow_NFACCT_la_CFLAGS = $(AM_CFLAGS) $(LIBMNL_LIBS) $(LIBNETFILTER_ACCT_CFLAGS)
diff --git a/input/sum/ulogd_inpflow_NFACCT.c b/input/sum/ulogd_inpflow_NFACCT.c
new file mode 100644
index 0000000..152cd48
--- /dev/null
+++ b/input/sum/ulogd_inpflow_NFACCT.c
@@ -0,0 +1,265 @@
+/* ulogd_input_NFACCT.c
+ *
+ * ulogd input plugin for nfacct
+ *
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2012 by Intra2net AG <http://www.intra2net.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/time.h>
+#include <time.h>
+#include <netinet/in.h>
+
+#include <ulogd/ulogd.h>
+#include <ulogd/timer.h>
+
+#include <libmnl/libmnl.h>
+#include <libnetfilter_acct/libnetfilter_acct.h>
+
+struct nfacct_pluginstance {
+	struct mnl_socket	*nl;
+	uint32_t		portid;
+	uint32_t		seq;
+	struct ulogd_fd		ufd;
+	struct ulogd_timer	timer;
+};
+
+static struct config_keyset nfacct_kset = {
+	.ces = {
+		{
+			.key	 = "pollinterval",
+			.type	 = CONFIG_TYPE_INT,
+			.options = CONFIG_OPT_NONE,
+			.u.value = 0,
+		},
+	},
+	.num_ces = 1,
+};
+#define pollint_ce(x)	(x->ces[0])
+
+enum ulogd_nfacct_keys {
+	ULOGD_NFACCT_NAME,
+	ULOGD_NFACCT_PKTS,
+	ULOGD_NFACCT_BYTES,
+};
+
+static struct ulogd_key nfacct_okeys[] = {
+	[ULOGD_NFACCT_NAME] = {
+		.type	= ULOGD_RET_STRING,
+		.flags	= ULOGD_RETF_NONE,
+		.name	= "sum.name",
+	},
+	[ULOGD_NFACCT_PKTS] = {
+		.type	= ULOGD_RET_UINT64,
+		.flags	= ULOGD_RETF_NONE,
+		.name	= "sum.pkts",
+	},
+	[ULOGD_NFACCT_BYTES] = {
+		.type	= ULOGD_RET_UINT64,
+		.flags	= ULOGD_RETF_NONE,
+		.name	= "sum.bytes",
+	},
+};
+
+static void
+propagate_nfacct(struct ulogd_pluginstance *upi, struct nfacct *nfacct)
+{
+	struct ulogd_key *ret = upi->output.keys;
+
+	okey_set_ptr(&ret[ULOGD_NFACCT_NAME],
+			(void *)nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME));
+	okey_set_u64(&ret[ULOGD_NFACCT_PKTS],
+			nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS));
+	okey_set_u64(&ret[ULOGD_NFACCT_BYTES],
+			nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES));
+
+	ulogd_propagate_results(upi);
+}
+
+static void
+do_propagate_nfacct(struct ulogd_pluginstance *upi, struct nfacct *nfacct)
+{
+	struct ulogd_pluginstance *npi = NULL;
+
+	llist_for_each_entry(npi, &upi->plist, plist)
+		propagate_nfacct(npi, nfacct);
+
+	propagate_nfacct(upi, nfacct);
+}
+
+static int nfacct_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nfacct *nfacct;
+	struct ulogd_pluginstance *upi = data;
+
+	nfacct = nfacct_alloc();
+	if (nfacct == NULL) {
+		ulogd_log(ULOGD_ERROR, "OOM");
+		goto err;
+	}
+
+	if (nfacct_nlmsg_parse_payload(nlh, nfacct) < 0) {
+		ulogd_log(ULOGD_ERROR, "Error parsing nfacct message");
+		goto err_free;
+	}
+
+	do_propagate_nfacct(upi, nfacct);
+
+err_free:
+	nfacct_free(nfacct);
+err:
+	return MNL_CB_OK;
+}
+
+static int nfacct_read_cb(int fd, unsigned int what, void *param)
+{
+	int ret;
+	char buf[MNL_SOCKET_BUFFER_SIZE];
+	struct ulogd_pluginstance *upi = param;
+	struct nfacct_pluginstance *cpi =
+		(struct nfacct_pluginstance *) upi->private;
+
+	if (!(what & ULOGD_FD_READ))
+		return 0;
+
+	ret = mnl_socket_recvfrom(cpi->nl, buf, sizeof(buf));
+	if (ret > 0) {
+		ret = mnl_cb_run(buf, ret, cpi->seq,
+				 cpi->portid, nfacct_cb, upi);
+	}
+	return ret;
+}
+
+static int nfacct_send_request(struct nfacct_pluginstance *cpi)
+{
+	struct nlmsghdr *nlh;
+	char buf[MNL_SOCKET_BUFFER_SIZE];
+
+	cpi->seq = time(NULL);
+	nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET_CTRZERO,
+				     NLM_F_DUMP, cpi->seq);
+
+	if (mnl_socket_sendto(cpi->nl, nlh, nlh->nlmsg_len) < 0) {
+		ulogd_log(ULOGD_ERROR, "Cannot send netlink message\n");
+		return -1;
+	}
+	return 0;
+}
+
+static void polling_timer_cb(struct ulogd_timer *t, void *data)
+{
+	struct ulogd_pluginstance *upi = data;
+	struct nfacct_pluginstance *cpi =
+		(struct nfacct_pluginstance *)upi->private;
+
+	nfacct_send_request(cpi);
+
+	ulogd_add_timer(&cpi->timer, pollint_ce(upi->config_kset).u.value);
+}
+
+static int configure_nfacct(struct ulogd_pluginstance *upi,
+			    struct ulogd_pluginstance_stack *stack)
+{
+	int ret;
+
+	ret = config_parse_file(upi->id, upi->config_kset);
+	if (ret < 0)
+		return ret;
+
+	if (pollint_ce(upi->config_kset).u.value <= 0) {
+		ulogd_log(ULOGD_FATAL, "You have to set pollint\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int constructor_nfacct(struct ulogd_pluginstance *upi)
+{
+	struct nfacct_pluginstance *cpi =
+		(struct nfacct_pluginstance *)upi->private;
+
+	if (pollint_ce(upi->config_kset).u.value == 0)
+		return -1;
+
+	cpi->nl = mnl_socket_open(NETLINK_NETFILTER);
+	if (cpi->nl == NULL) {
+		ulogd_log(ULOGD_FATAL, "cannot open netlink socket\n");
+		return -1;
+	}
+
+	if (mnl_socket_bind(cpi->nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+		ulogd_log(ULOGD_FATAL, "cannot bind netlink socket\n");
+		return -1;
+	}
+	cpi->portid = mnl_socket_get_portid(cpi->nl);
+
+	cpi->ufd.fd = mnl_socket_get_fd(cpi->nl);
+	cpi->ufd.cb = &nfacct_read_cb;
+	cpi->ufd.data = upi;
+	cpi->ufd.when = ULOGD_FD_READ;
+
+	ulogd_register_fd(&cpi->ufd);
+	ulogd_init_timer(&cpi->timer, upi, polling_timer_cb);
+	ulogd_add_timer(&cpi->timer,
+			 pollint_ce(upi->config_kset).u.value);
+
+	return 0;
+}
+
+static int destructor_nfacct(struct ulogd_pluginstance *upi)
+{
+	struct nfacct_pluginstance *cpi = (void *)upi->private;
+
+	ulogd_del_timer(&cpi->timer);
+	ulogd_unregister_fd(&cpi->ufd);
+	mnl_socket_close(cpi->nl);
+
+	return 0;
+}
+
+static void signal_nfacct(struct ulogd_pluginstance *upi, int signal)
+{
+	struct nfacct_pluginstance *cpi =
+		(struct nfacct_pluginstance *)upi->private;
+
+	switch (signal) {
+	case SIGUSR2:
+		nfacct_send_request(cpi);
+		break;
+	}
+}
+
+static struct ulogd_plugin nfacct_plugin = {
+	.name = "NFACCT",
+	.input = {
+		.type = ULOGD_DTYPE_SOURCE,
+	},
+	.output = {
+		.keys = nfacct_okeys,
+		.num_keys = ARRAY_SIZE(nfacct_okeys),
+		.type = ULOGD_DTYPE_FLOW,
+	},
+	.config_kset	= &nfacct_kset,
+	.interp		= NULL,
+	.configure	= &configure_nfacct,
+	.start		= &constructor_nfacct,
+	.stop		= &destructor_nfacct,
+	.signal		= &signal_nfacct,
+	.priv_size	= sizeof(struct nfacct_pluginstance),
+	.version	= ULOGD_VERSION,
+};
+
+void __attribute__ ((constructor)) init(void);
+
+void init(void)
+{
+	ulogd_register_plugin(&nfacct_plugin);
+}
diff --git a/ulogd.conf.in b/ulogd.conf.in
index c0c8559..71e8255 100644
--- a/ulogd.conf.in
+++ b/ulogd.conf.in
@@ -49,6 +49,7 @@ plugin="@pkglibexecdir@/ulogd_output_GPRINT.so"
 #plugin="@pkglibexecdir@/ulogd_output_MYSQL.so"
 #plugin="@pkglibexecdir@/ulogd_output_DBI.so"
 plugin="@pkglibexecdir@/ulogd_raw2packet_BASE.so"
+plugin="@pkglibexecdir@/ulogd_inpflow_NFACCT.so"
 
 # this is a stack for logging packet send by system via LOGEMU
 #stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
@@ -107,6 +108,9 @@ plugin="@pkglibexecdir@/ulogd_raw2packet_BASE.so"
 # this is a stack for flow-based logging in NACCT compatible format
 #stack=ct1:NFCT,ip2str1:IP2STR,nacct1:NACCT
 
+# this is a stack for accounting-based logging via GPRINT
+#stack=acct1:NFACCT,gp1:GPRINT
+
 [ct1]
 #netlink_socket_buffer_size=217088
 #netlink_socket_buffer_maxsize=1085440
@@ -250,3 +254,6 @@ sync = 1
 
 [mark1]
 mark = 1
+
+[acct1]
+pollinterval = 2
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] src: add example use of GPRINT to ulogd.conf.in configuration file
  2012-02-22 12:33 [PATCH 0/3] ulogd2 supports nfacct infrastructure pablo
  2012-02-22 12:33 ` [PATCH 1/3] output: add GPRINT plugin pablo
  2012-02-22 12:33 ` [PATCH 2/3] input: add nfacct plugin pablo
@ 2012-02-22 12:33 ` pablo
  2 siblings, 0 replies; 4+ messages in thread
From: pablo @ 2012-02-22 12:33 UTC (permalink / raw)
  To: netfilter-devel

From: Pablo Neira Ayuso <pablo@netfilter.org>

Example on how this display one conntrack:

timestamp=2012/02/22-13:16:54,orig.ip.saddr=192.168.1.129,orig.ip.daddr=173.194.34.235,orig.ip.protocol=6,orig.l4.sport=58221,orig.l4.dport=80,orig.raw.pktlen=1206,orig.raw.pktcount=4,reply.ip.saddr=173.194.34.235,reply.ip.daddr=192.168.1.129,reply.ip.protocol=6,reply.l4.sport=80,reply.l4.dport=58221,reply.raw.pktlen=1104,reply.raw.pktcount=3,ct.mark=0,ct.id=846180008,ct.event=4,flow.end.sec=1329913014,flow.end.usec=413771,oob.family=2,oob.protocol=0

and one NFLOG line look like this

timestamp=2012/02/22-13:21:24,raw.pktlen=40,raw.pktcount=1,oob.prefix=test,oob.time.sec=1329913284,oob.time.usec=226795,oob.mark=0,oob.ifindex_in=3,oob.hook=1,raw.mac_len=14,oob.family=2,oob.protocol=2048,raw.label=0,raw.type=1,raw.mac.addrlen=6

People that like parsing comma-separated key-value files will
like this.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 ulogd.conf.in |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/ulogd.conf.in b/ulogd.conf.in
index 71e8255..b33e69c 100644
--- a/ulogd.conf.in
+++ b/ulogd.conf.in
@@ -41,7 +41,6 @@ plugin="@pkglibexecdir@/ulogd_output_LOGEMU.so"
 plugin="@pkglibexecdir@/ulogd_output_SYSLOG.so"
 plugin="@pkglibexecdir@/ulogd_output_XML.so"
 #plugin="@pkglibexecdir@/ulogd_output_SQLITE3.so"
-#plugin="@pkglibexecdir@/ulogd_output_OPRINT.so"
 plugin="@pkglibexecdir@/ulogd_output_GPRINT.so"
 #plugin="@pkglibexecdir@/ulogd_output_NACCT.so"
 #plugin="@pkglibexecdir@/ulogd_output_PCAP.so"
@@ -63,11 +62,14 @@ plugin="@pkglibexecdir@/ulogd_inpflow_NFACCT.so"
 # this is a stack for packet-based logging via LOGEMU with filtering on MARK
 #stack=log2:NFLOG,mark1:MARK,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
 
+# this is a stack for packet-based logging via GPRINT
+#stack=log1:NFLOG,gp1:GPRINT
+
 # this is a stack for flow-based logging via LOGEMU
 #stack=ct1:NFCT,ip2str1:IP2STR,print1:PRINTFLOW,emu1:LOGEMU
 
-# this is a stack for flow-based logging via OPRINT
-#stack=ct1:NFCT,op1:OPRINT
+# this is a stack for flow-based logging via GPRINT
+#stack=ct1:NFCT,gp1:GPRINT
 
 # this is a stack for flow-based logging via XML
 #stack=ct1:NFCT,xml1:XML
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-02-22 12:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-22 12:33 [PATCH 0/3] ulogd2 supports nfacct infrastructure pablo
2012-02-22 12:33 ` [PATCH 1/3] output: add GPRINT plugin pablo
2012-02-22 12:33 ` [PATCH 2/3] input: add nfacct plugin pablo
2012-02-22 12:33 ` [PATCH 3/3] src: add example use of GPRINT to ulogd.conf.in configuration file pablo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).