netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Remove debian directory, and add new UNIXSOCK input plugin
@ 2009-08-23 19:36 Pierre Chifflier
  2009-08-23 19:36 ` [PATCH 1/3] Remove debian directory Pierre Chifflier
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Pierre Chifflier @ 2009-08-23 19:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eleblond

Hi,

[1] remove debian directory: the packaging is outdated, and not used in
Debian anyway. It is easier to maintain it outside sources, so delete it.

(These patches are not related)

[2] add new input plugin UNISOCK, using a unix socket. This allows userspace
applications to send packets to ulogd, for example to send packets offline.
It uses a key-length-value protocol to handle optional fields or extensions.
[3] is a Perl script to load a PCAP file and send it to ulogd using the
UNIXSOCK plugin.

Regards,
Pierre


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

* [PATCH 1/3] Remove debian directory
  2009-08-23 19:36 Remove debian directory, and add new UNIXSOCK input plugin Pierre Chifflier
@ 2009-08-23 19:36 ` Pierre Chifflier
  2009-08-23 19:36 ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
  2009-08-23 19:36 ` [PATCH 3/3] Add helper script pcap2ulog Pierre Chifflier
  2 siblings, 0 replies; 10+ messages in thread
From: Pierre Chifflier @ 2009-08-23 19:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eleblond, Pierre Chifflier

Remove Debian packaging files, it is easier to maintain the packaging
files outside of the sources.

Signed-off-by: Pierre Chifflier <chifflier@inl.fr>
---
 debian/changelog                    |    5 ---
 debian/control                      |   54 -----------------------------------
 debian/rules                        |   11 -------
 debian/ulogd-input-nfct.install     |    1 -
 debian/ulogd-input-nflog.install    |    1 -
 debian/ulogd-output-mysql.install   |    1 -
 debian/ulogd-output-pcap.install    |    1 -
 debian/ulogd-output-pgsql.install   |    1 -
 debian/ulogd-output-sqlite3.install |    1 -
 debian/ulogd.install                |   10 ------
 10 files changed, 0 insertions(+), 86 deletions(-)
 delete mode 100644 debian/changelog
 delete mode 100644 debian/control
 delete mode 100755 debian/rules
 delete mode 100644 debian/ulogd-input-nfct.install
 delete mode 100644 debian/ulogd-input-nflog.install
 delete mode 100644 debian/ulogd-output-mysql.install
 delete mode 100644 debian/ulogd-output-pcap.install
 delete mode 100644 debian/ulogd-output-pgsql.install
 delete mode 100644 debian/ulogd-output-sqlite3.install
 delete mode 100644 debian/ulogd.install

diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index d71ceba..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-ulogd (2.00beta1) unstable; urgency=low
-
-  * initial debian release
-
- -- Harald Welte <laforge@netfilter.org>  Sat, 07 Jan 2006 15:55:51 +0100
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 0118862..0000000
--- a/debian/control
+++ /dev/null
@@ -1,54 +0,0 @@
-Source: ulogd
-Section: net
-Priority: optional
-Maintainer: Harald Welte <laforge@netfilter.org>
-Build-Depends: cdbs (>= 0.4), debhelper (>= 4.2), gcc (>= 3.4), libnfnetlink-dev (>= 0.0.13), libnetfilter-conntrack-dev (>= 0.0.28), libnetfilter-log-dev (>= 0.0.12), libmysqlclient-dev, libpq-dev, libpcap-dev, libsqlite-dev
-Standards-Version: 3.6.2
-
-Package: ulogd
-Architecture: any
-Depends: ${shlibs:Depends}
-Description: Userspace logging daemon for netfilter/iptables
-
-Package: ulogd-output-pgsql
-Architecture: any
-Depends: ${shlibs:Depends}, ulogd (= ${Source-Version})
-Description: Userspace logging daemon for netfilter/iptables
- The userspace connection tracking table administration program.
- .
- This package provides the PostgreSQL output plugin.
-
-Package: ulogd-output-mysql
-Architecture: any
-Depends: ${shlibs:Depends}, ulogd (= ${Source-Version})
-Description: Userspace logging daemon for netfilter/iptables
- .
- This package provides the MySQL output plugin.
-
-Package: ulogd-output-pcap
-Architecture: any
-Depends: ${shlibs:Depends}, ulogd (= ${Source-Version})
-Description: Userspace logging daemon for netfilter/iptables
- .
- This package provides the PCAP output plugin.
-
-Package: ulogd-output-sqlite3
-Architecture: any
-Depends: ${shlibs:Depends}, ulogd (= ${Source-Version})
-Description: Userspace logging daemon for netfilter/iptables
- .
- This package provides the SQLITE3 output plugin.
-
-Package: ulogd-input-nflog
-Architecture: any
-Depends: ${shlibs:Depends}, ulogd (= ${Source-Version})
-Description: Userspace logging daemon for netfilter/iptables
- .
- This package provides the NFLOG input plugin.
-
-Package: ulogd-input-nfct
-Architecture: any
-Depends: ${shlibs:Depends}, ulogd (= ${Source-Version})
-Description: Userspace logging daemon for netfilter/iptables
- .
- This package provides the conntrack_netlink input plugin.
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 138a976..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/make -f
-# -*- mode: makefile; coding: utf-8 -*-
-
-UPSTREAM_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f2 -d' ' | cut -f1 -d-)
-DEB_TARBALL := ulogd-$(UPSTREAM_VERSION).tar.bz2
-DEB_TAR_SRCDIR := ulogd-$(UPSTREAM_VERSION)
-
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/class/autotools.mk
-
-DEB_DH_INSTALL_SOURCEDIR := debian/tmp
diff --git a/debian/ulogd-input-nfct.install b/debian/ulogd-input-nfct.install
deleted file mode 100644
index 4fa02c3..0000000
--- a/debian/ulogd-input-nfct.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/ulogd/ulogd_input_NFCT.so*
diff --git a/debian/ulogd-input-nflog.install b/debian/ulogd-input-nflog.install
deleted file mode 100644
index e99af30..0000000
--- a/debian/ulogd-input-nflog.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/ulogd/ulogd_input_NFLOG.so*
diff --git a/debian/ulogd-output-mysql.install b/debian/ulogd-output-mysql.install
deleted file mode 100644
index 19eb379..0000000
--- a/debian/ulogd-output-mysql.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/ulogd/ulogd_output_MYSQL.so*
diff --git a/debian/ulogd-output-pcap.install b/debian/ulogd-output-pcap.install
deleted file mode 100644
index de25c45..0000000
--- a/debian/ulogd-output-pcap.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/ulogd/ulogd_output_PCAP.so*
diff --git a/debian/ulogd-output-pgsql.install b/debian/ulogd-output-pgsql.install
deleted file mode 100644
index eddd68b..0000000
--- a/debian/ulogd-output-pgsql.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/ulogd/ulogd_output_PGSQL.so*
diff --git a/debian/ulogd-output-sqlite3.install b/debian/ulogd-output-sqlite3.install
deleted file mode 100644
index 9ea3344..0000000
--- a/debian/ulogd-output-sqlite3.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/ulogd/ulogd_output_SQLITE3.so*
diff --git a/debian/ulogd.install b/debian/ulogd.install
deleted file mode 100644
index dec8583..0000000
--- a/debian/ulogd.install
+++ /dev/null
@@ -1,10 +0,0 @@
-usr/sbin
-usr/share/man
-usr/lib/ulogd/ulogd_filter_IFINDEX.so*
-usr/lib/ulogd/ulogd_filter_PWSNIFF.so*
-usr/lib/ulogd/ulogd_inppkt_ULOG.so*
-usr/lib/ulogd/ulogd_output_IPFIX.so*
-usr/lib/ulogd/ulogd_output_LOGEMU.so*
-usr/lib/ulogd/ulogd_output_OPRINT.so*
-usr/lib/ulogd/ulogd_output_SYSLOG.so*
-usr/lib/ulogd/ulogd_raw2packet_BASE.so*
-- 
1.6.3.3


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

* [PATCH 2/3] Add new input plugin UNIXSOCK
  2009-08-23 19:36 Remove debian directory, and add new UNIXSOCK input plugin Pierre Chifflier
  2009-08-23 19:36 ` [PATCH 1/3] Remove debian directory Pierre Chifflier
@ 2009-08-23 19:36 ` Pierre Chifflier
  2009-08-23 22:45   ` Jan Engelhardt
  2009-08-23 19:36 ` [PATCH 3/3] Add helper script pcap2ulog Pierre Chifflier
  2 siblings, 1 reply; 10+ messages in thread
From: Pierre Chifflier @ 2009-08-23 19:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eleblond, Pierre Chifflier

This input plugins creates a unix socket which can be used to log packets.
Scripts or applications can connect to the socket (only one client allowed
per socket) and send data in a Key-Length-Value format (including the
payload).

Signed-off-by: Pierre Chifflier <chifflier@inl.fr>
---
 input/packet/Makefile.am             |    5 +-
 input/packet/ulogd_inppkt_UNIXSOCK.c |  658 ++++++++++++++++++++++++++++++++++
 ulogd.conf.in                        |    7 +
 3 files changed, 669 insertions(+), 1 deletions(-)
 create mode 100644 input/packet/ulogd_inppkt_UNIXSOCK.c

diff --git a/input/packet/Makefile.am b/input/packet/Makefile.am
index e90e46e..566b817 100644
--- a/input/packet/Makefile.am
+++ b/input/packet/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
 AM_CFLAGS=-fPIC -Wall
 LIBS=
 
-pkglib_LTLIBRARIES = ulogd_inppkt_NFLOG.la ulogd_inppkt_ULOG.la
+pkglib_LTLIBRARIES = ulogd_inppkt_NFLOG.la ulogd_inppkt_ULOG.la ulogd_inppkt_UNIXSOCK.la
 
 ulogd_inppkt_NFLOG_la_SOURCES = ulogd_inppkt_NFLOG.c
 ulogd_inppkt_NFLOG_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_LOG_LIBS)
@@ -12,3 +12,6 @@ ulogd_inppkt_NFLOG_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_LOG_CFLAGS)
 ulogd_inppkt_ULOG_la_SOURCES = ulogd_inppkt_ULOG.c
 ulogd_inppkt_ULOG_la_LDFLAGS = -avoid-version -module
 ulogd_inppkt_ULOG_la_LIBADD = ../../libipulog/libipulog.la
+
+ulogd_inppkt_UNIXSOCK_la_SOURCES = ulogd_inppkt_UNIXSOCK.c
+ulogd_inppkt_UNIXSOCK_la_LDFLAGS = -avoid-version -module
diff --git a/input/packet/ulogd_inppkt_UNIXSOCK.c b/input/packet/ulogd_inppkt_UNIXSOCK.c
new file mode 100644
index 0000000..cf58d6f
--- /dev/null
+++ b/input/packet/ulogd_inppkt_UNIXSOCK.c
@@ -0,0 +1,658 @@
+/*
+ ** Copyright(C) 2008 INL
+ ** Written by  Pierre Chifflier <chifflier@inl.fr>
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#include <ulogd/ulogd.h>
+
+/* Size of the receive buffer for the unix socket. */
+#define UNIXSOCK_BUFSIZE_DEFAULT	150000
+
+/* Default unix socket path */
+#define UNIXSOCK_UNIXPATH_DEFAULT	"/tmp/ulogd2.sock"
+
+
+#define UNIX_PATH_MAX	108
+
+
+struct unixsock_input {
+	char *path;
+	char *unixsock_buf;
+	unsigned int unixsock_buf_avail;
+	unsigned int unixsock_buf_size;
+	struct ulogd_fd unixsock_server_fd;
+	struct ulogd_fd unixsock_instance_fd;
+};
+
+enum nflog_keys {
+	UNIXSOCK_KEY_RAW_MAC = 0,
+	UNIXSOCK_KEY_RAW_PCKT,
+	UNIXSOCK_KEY_RAW_PCKTLEN,
+	UNIXSOCK_KEY_RAW_PCKTCOUNT,
+	UNIXSOCK_KEY_OOB_PREFIX,
+	UNIXSOCK_KEY_OOB_TIME_SEC,
+	UNIXSOCK_KEY_OOB_TIME_USEC,
+	UNIXSOCK_KEY_OOB_MARK,
+	UNIXSOCK_KEY_OOB_IN,
+	UNIXSOCK_KEY_OOB_OUT,
+	UNIXSOCK_KEY_OOB_HOOK,
+	UNIXSOCK_KEY_RAW_MAC_LEN,
+	UNIXSOCK_KEY_OOB_SEQ_LOCAL,
+	UNIXSOCK_KEY_OOB_SEQ_GLOBAL,
+	UNIXSOCK_KEY_OOB_FAMILY,
+	UNIXSOCK_KEY_OOB_PROTOCOL,
+	UNIXSOCK_KEY_OOB_UID,
+	UNIXSOCK_KEY_OOB_GID,
+	UNIXSOCK_KEY_RAW_LABEL,
+	UNIXSOCK_KEY_RAW_TYPE,
+	UNIXSOCK_KEY_RAW_MAC_SADDR,
+	UNIXSOCK_KEY_RAW_MAC_ADDRLEN,
+	UNIXSOCK_KEY_NUFW_USER_NAME,
+	UNIXSOCK_KEY_NUFW_USER_ID,
+	UNIXSOCK_KEY_NUFW_OS_NAME,
+	UNIXSOCK_KEY_NUFW_OS_REL,
+	UNIXSOCK_KEY_NUFW_OS_VERS,
+	UNIXSOCK_KEY_NUFW_APP_NAME,
+};
+
+static struct ulogd_key output_keys[] = {
+	[UNIXSOCK_KEY_RAW_MAC] = {
+		.type = ULOGD_RET_RAW,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac",
+	},
+	[UNIXSOCK_KEY_RAW_MAC_SADDR] = {
+		.type = ULOGD_RET_RAW,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac.saddr",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_sourceMacAddress,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_PCKT] = {
+		.type = ULOGD_RET_RAW,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.pkt",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_rawpacket,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_PCKTLEN] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.pktlen",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_rawpacket_length,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_PCKTCOUNT] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.pktcount",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_packetDeltaCount,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_PREFIX] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.prefix",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_prefix,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_TIME_SEC] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.time.sec",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_flowStartSeconds,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_TIME_USEC] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.time.usec",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_flowStartMicroSeconds,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_MARK] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.mark",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_mark,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_IN] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.in",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_ingressInterface,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_OUT] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.out",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_egressInterface,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_HOOK] = {
+		.type = ULOGD_RET_UINT8,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.hook",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_hook,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_MAC_LEN] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac_len",
+	},
+	[UNIXSOCK_KEY_RAW_MAC_ADDRLEN] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac.addrlen",
+	},
+
+	[UNIXSOCK_KEY_OOB_SEQ_LOCAL] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.seq.local",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_seq_local,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_SEQ_GLOBAL] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.seq.global",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_seq_global,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_FAMILY] = {
+		.type = ULOGD_RET_UINT8,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.family",
+	},
+	[UNIXSOCK_KEY_OOB_PROTOCOL] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.protocol",
+	},
+	[UNIXSOCK_KEY_OOB_UID] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.uid",
+	},
+	[UNIXSOCK_KEY_OOB_GID] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.gid",
+	},
+	[UNIXSOCK_KEY_RAW_LABEL] = {
+		.type = ULOGD_RET_UINT8,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.label",
+	},
+	[UNIXSOCK_KEY_RAW_TYPE] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.type",
+	},
+	[UNIXSOCK_KEY_NUFW_USER_NAME] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.user.name",
+	},
+	[UNIXSOCK_KEY_NUFW_USER_ID] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.user.id",
+	},
+	[UNIXSOCK_KEY_NUFW_OS_NAME] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.os.name",
+	},
+	[UNIXSOCK_KEY_NUFW_OS_REL] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.os.rel",
+	},
+	[UNIXSOCK_KEY_NUFW_OS_VERS] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.os.vers",
+	},
+	[UNIXSOCK_KEY_NUFW_APP_NAME] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.app.name",
+	},
+};
+
+static struct config_keyset libunixsock_kset = {
+	.num_ces = 2,
+	.ces = {
+		{
+			.key 	 = "socket_path",
+			.type 	 = CONFIG_TYPE_STRING,
+			.options = CONFIG_OPT_NONE,
+			.u.string = UNIXSOCK_UNIXPATH_DEFAULT,
+		},
+		{
+			.key 	 = "bufsize",
+			.type 	 = CONFIG_TYPE_INT,
+			.options = CONFIG_OPT_NONE,
+			.u.value = UNIXSOCK_BUFSIZE_DEFAULT,
+		},
+	},
+};
+
+#define unixpath_ce(x)		(x->ces[0])
+#define bufsize_ce(x)		(x->ces[1])
+
+
+enum ulogd2_option_type {
+	ULOGD2_OPT_UNUSED = 0,
+	ULOGD2_OPT_PREFIX,	/* log prefix (string) */
+	ULOGD2_OPT_OOB_IN,	/* input device (string) */
+	ULOGD2_OPT_OOB_OUT,	/* output device (string) */
+
+	ULOGD2_OPT_USER=200,	/* user name (string) */
+	ULOGD2_OPT_USERID,	/* user id (u_int32_t) */
+	ULOGD2_OPT_OSNAME,	/* OS name (string) */
+	ULOGD2_OPT_OSREL,	/* OS release (string) */
+	ULOGD2_OPT_OSVERS,	/* OS version (string) */
+	ULOGD2_OPT_APPNAME,	/* application name (string) */
+};
+
+static int handle_packet(struct ulogd_pluginstance *upi, u_int16_t total_len)
+{
+	struct unixsock_input *ui = (struct unixsock_input *)upi->private;
+	char *data;
+	struct iphdr *ip;
+	struct ulogd_key *ret = upi->output.keys;
+	u_int8_t oob_family;
+	u_int16_t payload_len;
+	u_int16_t option_number;
+	u_int16_t option_length;
+	char *buf;
+
+	ulogd_log(ULOGD_ERROR,
+			"ulogd2: handling packet\n");
+
+	data = ui->unixsock_buf + sizeof(u_int16_t);
+	payload_len = ntohs(*(u_int16_t*)data);
+	data += sizeof(u_int16_t);
+
+
+	ip = (struct iphdr *) data;
+
+	if (ip->version == 4)
+		oob_family = AF_INET;
+	else if (ip->version == 6)
+		oob_family = AF_INET6;
+	else oob_family = 0;
+
+	okey_set_u8(&ret[UNIXSOCK_KEY_OOB_FAMILY], oob_family);
+
+	okey_set_ptr(&ret[UNIXSOCK_KEY_RAW_PCKT], ip);
+	okey_set_u32(&ret[UNIXSOCK_KEY_RAW_PCKTLEN], payload_len);
+
+	/* options */
+	if (total_len > payload_len + sizeof(u_int16_t)) {
+		data = ui->unixsock_buf + payload_len + 2*sizeof(u_int16_t);
+
+		while ( (data - ui->unixsock_buf) < total_len) {
+
+			option_number = ntohs(*(u_int16_t*)(data));
+			data += sizeof(u_int16_t);
+			option_length = ntohs(*(u_int16_t*)(data));
+			data += sizeof(u_int16_t);
+			buf = data;
+			data += option_length;
+
+			ulogd_log(ULOGD_DEBUG,
+					"ulogd2: option %d (len %d) `%s'\n",
+					option_number, option_length, buf);
+
+			switch(option_number) {
+				case ULOGD2_OPT_PREFIX:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_OOB_PREFIX], buf);
+					break;
+				case ULOGD2_OPT_OOB_IN:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_OOB_IN], buf);
+					break;
+				case ULOGD2_OPT_OOB_OUT:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_OOB_OUT], buf);
+					break;
+				case ULOGD2_OPT_USER:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_USER_NAME], buf);
+					break;
+				case ULOGD2_OPT_USERID:
+					okey_set_u32(&ret[UNIXSOCK_KEY_NUFW_USER_ID], *(u_int32_t*)buf);
+					break;
+				case ULOGD2_OPT_OSNAME:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_OS_NAME], buf);
+					break;
+				case ULOGD2_OPT_OSREL:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_OS_REL], buf);
+					break;
+				case ULOGD2_OPT_OSVERS:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_OS_VERS], buf);
+					break;
+				case ULOGD2_OPT_APPNAME:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_APP_NAME], buf);
+					break;
+				default:
+					ulogd_log(ULOGD_NOTICE,
+							"ulogd2: unknown option %d\n",
+							option_number);
+					break;
+			};
+		}
+	}
+
+	/* number of packets */
+	okey_set_u32(&ret[UNIXSOCK_KEY_RAW_PCKTCOUNT], 1);
+
+	ulogd_propagate_results(upi);
+
+	/* consume data */
+	ui->unixsock_buf_avail -= total_len;
+	if (ui->unixsock_buf_avail > 0) {
+		/* we need to shift data .. */
+		memmove(ui->unixsock_buf,
+			ui->unixsock_buf + total_len ,
+			ui->unixsock_buf_avail);
+	}
+
+	return 0;
+}
+
+static int _create_unix_socket(const char *unix_path)
+{
+	int ret = -1;
+	struct sockaddr_un server_sock;
+	int s;
+	socklen_t len;
+
+	s = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (s < 0)
+		return -1;
+
+	server_sock.sun_family = AF_UNIX;
+	strncpy(server_sock.sun_path, unix_path, UNIX_PATH_MAX-1);
+	len = strlen(server_sock.sun_path) + sizeof(server_sock.sun_family);
+
+	/* remove existing socket, if any */
+	unlink(unix_path);
+
+	ret = bind(s, (struct sockaddr *)&server_sock, len);
+	if (ret < 0) {
+		ulogd_log(ULOGD_ERROR,
+				"ulogd2: could not bind to unix socket \'%s\'\n",
+				server_sock.sun_path);
+		close(s);
+		return -1;
+	}
+
+	ret = listen(s, 10);
+	if (ret < 0) {
+		ulogd_log(ULOGD_ERROR,
+				"ulogd2: could not bind to unix socket \'%s\'\n",
+				server_sock.sun_path);
+		close(s);
+		return -1;
+	}
+
+
+	return s;
+}
+
+/* warning: this code is NOT reentrant ! */
+static void _timer_unregister_cb(struct ulogd_timer *a, void *param)
+{
+	struct unixsock_input *ui = (struct unixsock_input *)param;
+
+	if (ui->unixsock_instance_fd.fd >= 0) {
+		ulogd_log(ULOGD_DEBUG, "  removing client from list\n");
+		ulogd_unregister_fd(&ui->unixsock_instance_fd);
+		close(ui->unixsock_instance_fd.fd);
+		ui->unixsock_instance_fd.fd = -1;
+	}
+}
+
+/* callback called from ulogd core when fd is readable */
+static int unixsock_instance_read_cb(int fd, unsigned int what, void *param)
+{
+	struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;
+	struct unixsock_input *ui = (struct unixsock_input *)upi->private;
+	int len;
+	u_int16_t needed_len;
+
+	char buf[4096];
+
+	if (!(what & ULOGD_FD_READ))
+		return 0;
+
+	len = read(fd, buf, sizeof(buf));
+	if (len < 0) {
+		ulogd_log(ULOGD_NOTICE, "  read returned %d, errno is %d (%s)\n",
+					len, errno, strerror(errno));
+		exit(-1);
+		return len;
+	}
+	if (len == 0) {
+		struct ulogd_timer *t = malloc(sizeof(struct ulogd_timer));
+
+		ulogd_log(ULOGD_DEBUG, "  client disconnected\n");
+		/* we can't call ulogd_unregister_fd fd, it will segfault
+		 * (unable to remove an entry while inside llist_for_each_entry)
+		 * so we schedule removal for next loop
+		 */
+		ulogd_init_timer(t, ui, _timer_unregister_cb);
+		ulogd_add_timer(t, 0);
+		return 0;
+	}
+
+	buf[len] = '\0';
+
+	ulogd_log(ULOGD_DEBUG, "  read %d bytes\n", len);
+	//ulogd_log(ULOGD_DEBUG, "  buffer [%s]\n", buf);
+
+	if (ui->unixsock_buf_avail + len > ui->unixsock_buf_size) {
+		ulogd_log(ULOGD_NOTICE,
+			  "We are losing events. Please consider using the clause "
+			  "bufsize\n");
+		return -1;
+	}
+
+	memcpy(ui->unixsock_buf + ui->unixsock_buf_avail,
+	       buf,
+	       len);
+	ui->unixsock_buf_avail += len;
+
+	needed_len = ntohs(*(u_int16_t*)ui->unixsock_buf);
+
+	if (ui->unixsock_buf_avail >= needed_len) {
+		ulogd_log(ULOGD_DEBUG, "  We have enough data, handling packet\n");
+
+		return handle_packet(upi, needed_len);
+	}
+	ulogd_log(ULOGD_DEBUG, "  We have %d bytes, but need %d. Requesting more\n",
+		  ui->unixsock_buf_avail, needed_len);
+
+	return 0;
+}
+
+/* callback called from ulogd core when fd is readable */
+static int unixsock_server_read_cb(int fd, unsigned int what, void *param)
+{
+	struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;
+	struct unixsock_input *ui = (struct unixsock_input *)upi->private;
+	socklen_t len;
+	int s;
+	struct sockaddr_storage saddr;
+
+	if (!(what & ULOGD_FD_READ))
+		return 0;
+
+	ulogd_log(ULOGD_DEBUG, "New server connected on unixsock socket\n");
+
+	len = sizeof(saddr);
+	s = accept(fd, (struct sockaddr*)&saddr, &len);
+	if (s < 0) {
+		ulogd_log(ULOGD_NOTICE,
+				"  error while accepting new unixsock client, errno is %d (%s)\n",
+				errno, strerror(errno));
+		return len;
+	}
+
+	if (ui->unixsock_instance_fd.fd >= 0) {
+		ulogd_log(ULOGD_NOTICE, "a client is already connecting, rejecting new connection");
+		close(s);
+		return 0;
+	}
+
+	ui->unixsock_instance_fd.fd = s;
+	ui->unixsock_instance_fd.cb = &unixsock_instance_read_cb;
+	ui->unixsock_instance_fd.data = upi;
+	ui->unixsock_instance_fd.when = ULOGD_FD_READ;
+
+	if (ulogd_register_fd(&ui->unixsock_instance_fd) < 0) {
+		ulogd_log(ULOGD_ERROR, "unable to register client fd to ulogd\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+
+
+static int configure(struct ulogd_pluginstance *upi,
+		     struct ulogd_pluginstance_stack *stack)
+{
+	ulogd_log(ULOGD_DEBUG, "parsing config file section `%s', "
+		  "plugin `%s'\n", upi->id, upi->plugin->name);
+
+	config_parse_file(upi->id, upi->config_kset);
+	return 0;
+}
+
+static int start(struct ulogd_pluginstance *upi)
+{
+	struct unixsock_input *ui = (struct unixsock_input *) upi->private;
+	int fd;
+
+	ulogd_log(ULOGD_DEBUG, "Starting plugin `%s'\n",
+		  upi->plugin->name);
+
+	ui->path = unixpath_ce(upi->config_kset).u.string;
+
+	ulogd_log(ULOGD_DEBUG, "Creating Unix socket `%s'\n",
+		  ui->path);
+	fd = _create_unix_socket(unixpath_ce(upi->config_kset).u.string);
+	if (fd < 0) {
+		ulogd_log(ULOGD_ERROR, "unable to create unix socket on `%s'\n",
+			  ui->path);
+		return -1;
+	}
+
+	ui->unixsock_buf_avail = 0;
+	ui->unixsock_buf_size = bufsize_ce(upi->config_kset).u.value;
+	ui->unixsock_buf = malloc(ui->unixsock_buf_size);
+
+	ui->unixsock_server_fd.fd = fd;
+	ui->unixsock_server_fd.cb = &unixsock_server_read_cb;
+	ui->unixsock_server_fd.data = upi;
+	ui->unixsock_server_fd.when = ULOGD_FD_READ;
+
+	ui->unixsock_instance_fd.fd = -1;
+	ui->unixsock_instance_fd.cb = &unixsock_instance_read_cb;
+	ui->unixsock_instance_fd.data = upi;
+	ui->unixsock_instance_fd.when = ULOGD_FD_READ;
+
+	if (ulogd_register_fd(&ui->unixsock_server_fd) < 0) {
+		ulogd_log(ULOGD_ERROR, "unable to register fd to ulogd\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int stop(struct ulogd_pluginstance *upi)
+{
+	struct unixsock_input *ui = (struct unixsock_input *) upi->private;
+	char *unix_path = unixpath_ce(upi->config_kset).u.string;
+
+	ulogd_log(ULOGD_DEBUG, "Stopping plugin `%s'\n",
+		  upi->plugin->name);
+
+	if (unix_path)
+		unlink(unix_path);
+
+	free(ui->unixsock_buf);
+
+	return 0;
+}
+
+
+
+
+struct ulogd_plugin libunixsock_plugin = {
+	.name = "UNIXSOCK",
+	.input = {
+		.type = ULOGD_DTYPE_SOURCE,
+	},
+	.output = {
+		.type = ULOGD_DTYPE_RAW,
+		.keys = output_keys,
+		.num_keys = sizeof(output_keys)/sizeof(struct ulogd_key),
+	},
+	.priv_size 	= sizeof(struct unixsock_input),
+	.configure 	= &configure,
+	.start 		= &start,
+	.stop 		= &stop,
+	.config_kset 	= &libunixsock_kset,
+	.version	= ULOGD_VERSION,
+};
+
+void __attribute__ ((constructor)) init(void);
+
+void init(void)
+{
+	ulogd_register_plugin(&libunixsock_plugin);
+}
diff --git a/ulogd.conf.in b/ulogd.conf.in
index 4542fc4..603efff 100644
--- a/ulogd.conf.in
+++ b/ulogd.conf.in
@@ -27,6 +27,7 @@ loglevel=1
 
 plugin="@libdir@/ulogd/ulogd_inppkt_NFLOG.so"
 #plugin="@libdir@/ulogd/ulogd_inppkt_ULOG.so"
+#plugin="@libdir@/ulogd/ulogd_inppkt_UNIXSOCK.so"
 plugin="@libdir@/ulogd/ulogd_inpflow_NFCT.so"
 plugin="@libdir@/ulogd/ulogd_filter_IFINDEX.so"
 plugin="@libdir@/ulogd/ulogd_filter_IP2STR.so"
@@ -75,6 +76,9 @@ plugin="@libdir@/ulogd/ulogd_raw2packet_BASE.so"
 # this is a stack for logging packets to syslog after a collect via NFLOG
 #stack=log3:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG
 
+# this is a stack for logging packets to syslog after a collect via NuFW
+#stack=nuauth1:UNIXSOCK,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG
+
 # this is a stack for flow-based logging to MySQL
 #stack=ct1:NFCT,ip2bin1:IP2BIN,mysql2:MYSQL
 
@@ -137,6 +141,9 @@ numeric_label=1 # you can label the log info based on the packet verdict
 nlgroup=1
 #numeric_label=0 # optional argument
 
+[nuauth1]
+socket_path="/tmp/nuauth_ulogd2.sock"
+
 [emu1]
 file="/var/log/ulogd_syslogemu.log"
 sync=1
-- 
1.6.3.3


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

* [PATCH 3/3] Add helper script pcap2ulog
  2009-08-23 19:36 Remove debian directory, and add new UNIXSOCK input plugin Pierre Chifflier
  2009-08-23 19:36 ` [PATCH 1/3] Remove debian directory Pierre Chifflier
  2009-08-23 19:36 ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
@ 2009-08-23 19:36 ` Pierre Chifflier
  2 siblings, 0 replies; 10+ messages in thread
From: Pierre Chifflier @ 2009-08-23 19:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eleblond, Pierre Chifflier

This script uses the Net::Pcap Perl library to parse an pcap file and
send packets to ulogd2 throught the UNIXSOCK input module.

Signed-off-by: Pierre Chifflier <chifflier@inl.fr>
---
 contrib/pcap2ulog |   96 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)
 create mode 100755 contrib/pcap2ulog

diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog
new file mode 100755
index 0000000..0a42b89
--- /dev/null
+++ b/contrib/pcap2ulog
@@ -0,0 +1,96 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2009 Pierre Chifflier <chifflier@inl.fr>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the same terms as Perl itself, either Perl version 5.8.4 or,
+# at your option, any later version of Perl 5 you may have available.
+
+use strict;
+
+use IO::Socket;
+use Net::Pcap;
+
+
+my $dumpfile = shift or die "Unable to open pcap file";
+my($pcap_t, $err);
+my($ulogd_client);
+my $socketfile = "/var/run/ulogd2.sock";
+
+sub connect_ulogd2 {
+    (-S $socketfile) or die "ulogd2 socket $socketfile does not exist - is ulogd running ?";
+
+    $ulogd_client = IO::Socket::UNIX->new(Peer  => $socketfile,
+                                          Type      => SOCK_STREAM ) or die $!;
+}
+
+sub process_pkt {
+    my($user, $hdr, $pkt) = @_;
+
+    if (($user ne "xyz") or !defined($hdr) or !defined($pkt)) {
+        print("Bad args passed to callback\n");
+        print("Bad user data\n"), if ($user ne "xyz");
+        print("Bad pkthdr\n"), if (!defined($hdr));
+        print("Bad pkt data\n"), if (!defined($pkt));
+        print("not ok\n");
+        exit;
+    }
+
+    #print "Header: len $hdr->{len}\n";
+    #my $len = length $pkt;
+    #print "Packet length: $len\n";
+
+    # decode packet
+    # packet type (sent by us: 4)
+    # link layer address type: 1
+    # link layer address length: 6
+    # src dst
+    # protocol (IP, ARP, PPP, SNMP ...)
+    # data
+    my $ignored = substr ($pkt, 0, 6);
+    my $srcmac = substr ($pkt, 6, 6);
+    my $protocol = unpack ("n", substr ($pkt, 12, 2));
+    my $size = length($pkt) - 16;
+
+    (my $hex_src = unpack("H*", $srcmac)) =~ s/(..)/$1:/g;
+    chop $hex_src;
+    #printf "source mac: $hex_src\n";
+
+    my $hex_dst = "\0";
+
+    # format data
+    my $data;
+
+    my $options_num=2;
+    my $options_len=length($hex_src) + length($hex_dst);
+    # total length
+    $data = pack ('n', $size + 4 + (4*$options_num) + ($options_len));
+    print $ulogd_client $data;
+    # payload length + payload
+    $data = pack ('na*', $size, substr($pkt,16,$size));
+    print $ulogd_client $data;
+    # options
+    my $OOB_IN = 2;
+    $data = pack ('nna*', $OOB_IN, length($hex_src), $hex_src);
+    print $ulogd_client $data;
+    my $OOB_OUT = 3;
+    $data = pack ('nna*', $OOB_OUT, length($hex_dst), $hex_dst);
+    print $ulogd_client $data;
+
+    #exit;
+}
+
+
+connect_ulogd2 or die $!;
+
+$pcap_t = Net::Pcap::open_offline($dumpfile, \$err);
+if (!defined($pcap_t)) {
+    print("Net::Pcap::dump_open failed: ", Net::Pcap::geterr($pcap_t), "\n");
+    exit;
+}
+
+Net::Pcap::loop($pcap_t, 10, \&process_pkt, "xyz");
+Net::Pcap::close($pcap_t);
+
+
+
-- 
1.6.3.3


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

* Re: [PATCH 2/3] Add new input plugin UNIXSOCK
  2009-08-23 19:36 ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
@ 2009-08-23 22:45   ` Jan Engelhardt
  2009-09-02 20:45     ` Pierre Chifflier
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Jan Engelhardt @ 2009-08-23 22:45 UTC (permalink / raw)
  To: Pierre Chifflier; +Cc: netfilter-devel, eleblond


On Sunday 2009-08-23 21:36, Pierre Chifflier wrote:
>+
>+/* Size of the receive buffer for the unix socket. */
>+#define UNIXSOCK_BUFSIZE_DEFAULT	150000

Hm. Would it make some sene to '(ab)use' getsockopt(SO_RCVBUF) as the
(runtime!) value for the default buffer size?

>+/* Default unix socket path */
>+#define UNIXSOCK_UNIXPATH_DEFAULT	"/tmp/ulogd2.sock"
>+
>+
>+#define UNIX_PATH_MAX	108
>...
>+static int _create_unix_socket(const char *unix_path)
>+{
>+	int ret = -1;
>+	struct sockaddr_un server_sock;
>+	int s;
>+	socklen_t len;
>+
>+	s = socket(AF_UNIX, SOCK_STREAM, 0);
>+	if (s < 0)
>+		return -1;
>+
>+	server_sock.sun_family = AF_UNIX;
>+	strncpy(server_sock.sun_path, unix_path, UNIX_PATH_MAX-1);

You can use sizeof(server_sock.sun_path) instead,
obviating the need for UNIX_PATH_MAX.

Also you should - as printf is called in the error case below -
ensure it is '\0'-terminated.

>+	len = strlen(server_sock.sun_path) + sizeof(server_sock.sun_family);

len should be sizeof(server_sock)...

>+	ret = bind(s, (struct sockaddr *)&server_sock, len);

... and since it can be directly passed in:

	ret = bind(s, server_sock, sizeof(server_sock));

>+/* callback called from ulogd core when fd is readable */
>+static int unixsock_instance_read_cb(int fd, unsigned int what, void *param)
>+{
>+	struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;

There is no cast needed for void*s.

>+/* callback called from ulogd core when fd is readable */
>+static int unixsock_server_read_cb(int fd, unsigned int what, void *param)
>+{
>+	struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;

Same

>+	struct sockaddr_storage saddr;
>+
>+	if (!(what & ULOGD_FD_READ))
>+		return 0;
>+
>+	ulogd_log(ULOGD_DEBUG, "New server connected on unixsock socket\n");
>+
>+	len = sizeof(saddr);
>+	s = accept(fd, (struct sockaddr*)&saddr, &len);

Since only unix sockets can connect, one could probably
use sockaddr_un over sockaddr_storage (though _storage is always
a good fallback).

>+struct ulogd_plugin libunixsock_plugin = {
>+	.name = "UNIXSOCK",
>+	.input = {
>+		.type = ULOGD_DTYPE_SOURCE,
>+	},
>+	.output = {
>+		.type = ULOGD_DTYPE_RAW,
>+		.keys = output_keys,
>+		.num_keys = sizeof(output_keys)/sizeof(struct ulogd_key),

Hmmm. Does ulogd have an ARRAY_SIZE that could make .num_keys easier?

>+void __attribute__ ((constructor)) init(void);
>+
>+void init(void)
>+{
>+	ulogd_register_plugin(&libunixsock_plugin);
>+}

This can become

static void __attribute__((constructor)) init(void) { ... }

Modules are always self-contained shared libraries if I read
the Makefiles right, so there should not be any benefit of
giving them 'extern'al linkage.


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

* Re: [PATCH 2/3] Add new input plugin UNIXSOCK
  2009-08-23 22:45   ` Jan Engelhardt
@ 2009-09-02 20:45     ` Pierre Chifflier
  2009-09-03 21:23     ` (unknown), Pierre Chifflier
  2009-09-03 21:23     ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
  2 siblings, 0 replies; 10+ messages in thread
From: Pierre Chifflier @ 2009-09-02 20:45 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel, eleblond


Hi Jan,

Thanks for your feedback.
I'm currently working on a new version of the patch with the changes
(and some other fixes that were found after some real-life tests)
I will send the updated parts ASAP.

Regards,
Pierre

On Mon, Aug 24, 2009 at 12:45:11AM +0200, Jan Engelhardt wrote:
> 
> On Sunday 2009-08-23 21:36, Pierre Chifflier wrote:
> >+
> >+/* Size of the receive buffer for the unix socket. */
> >+#define UNIXSOCK_BUFSIZE_DEFAULT	150000
> 
> Hm. Would it make some sene to '(ab)use' getsockopt(SO_RCVBUF) as the
> (runtime!) value for the default buffer size?
> 
> >+/* Default unix socket path */
> >+#define UNIXSOCK_UNIXPATH_DEFAULT	"/tmp/ulogd2.sock"
> >+
> >+
> >+#define UNIX_PATH_MAX	108
> >...
> >+static int _create_unix_socket(const char *unix_path)
> >+{
> >+	int ret = -1;
> >+	struct sockaddr_un server_sock;
> >+	int s;
> >+	socklen_t len;
> >+
> >+	s = socket(AF_UNIX, SOCK_STREAM, 0);
> >+	if (s < 0)
> >+		return -1;
> >+
> >+	server_sock.sun_family = AF_UNIX;
> >+	strncpy(server_sock.sun_path, unix_path, UNIX_PATH_MAX-1);
> 
> You can use sizeof(server_sock.sun_path) instead,
> obviating the need for UNIX_PATH_MAX.
> 
> Also you should - as printf is called in the error case below -
> ensure it is '\0'-terminated.
> 
> >+	len = strlen(server_sock.sun_path) + sizeof(server_sock.sun_family);
> 
> len should be sizeof(server_sock)...
> 
> >+	ret = bind(s, (struct sockaddr *)&server_sock, len);
> 
> ... and since it can be directly passed in:
> 
> 	ret = bind(s, server_sock, sizeof(server_sock));
> 
> >+/* callback called from ulogd core when fd is readable */
> >+static int unixsock_instance_read_cb(int fd, unsigned int what, void *param)
> >+{
> >+	struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;
> 
> There is no cast needed for void*s.
> 
> >+/* callback called from ulogd core when fd is readable */
> >+static int unixsock_server_read_cb(int fd, unsigned int what, void *param)
> >+{
> >+	struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;
> 
> Same
> 
> >+	struct sockaddr_storage saddr;
> >+
> >+	if (!(what & ULOGD_FD_READ))
> >+		return 0;
> >+
> >+	ulogd_log(ULOGD_DEBUG, "New server connected on unixsock socket\n");
> >+
> >+	len = sizeof(saddr);
> >+	s = accept(fd, (struct sockaddr*)&saddr, &len);
> 
> Since only unix sockets can connect, one could probably
> use sockaddr_un over sockaddr_storage (though _storage is always
> a good fallback).
> 
> >+struct ulogd_plugin libunixsock_plugin = {
> >+	.name = "UNIXSOCK",
> >+	.input = {
> >+		.type = ULOGD_DTYPE_SOURCE,
> >+	},
> >+	.output = {
> >+		.type = ULOGD_DTYPE_RAW,
> >+		.keys = output_keys,
> >+		.num_keys = sizeof(output_keys)/sizeof(struct ulogd_key),
> 
> Hmmm. Does ulogd have an ARRAY_SIZE that could make .num_keys easier?
> 
> >+void __attribute__ ((constructor)) init(void);
> >+
> >+void init(void)
> >+{
> >+	ulogd_register_plugin(&libunixsock_plugin);
> >+}
> 
> This can become
> 
> static void __attribute__((constructor)) init(void) { ... }
> 
> Modules are always self-contained shared libraries if I read
> the Makefiles right, so there should not be any benefit of
> giving them 'extern'al linkage.
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* (unknown), 
  2009-08-23 22:45   ` Jan Engelhardt
  2009-09-02 20:45     ` Pierre Chifflier
@ 2009-09-03 21:23     ` Pierre Chifflier
  2009-09-03 21:23     ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
  2 siblings, 0 replies; 10+ messages in thread
From: Pierre Chifflier @ 2009-09-03 21:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eleblond

Hi,

Here is an updated version of the UNIXSOCK plugin (part 2 only, other
parts are unchanged).
I think all remarks from Jan have been integrated:
- use sizeof(server_sock.sun_path) and do not use UNIX_PATH_MAX
- remove useless casts from void*
- use ARRAY_SIZE
- if no buffer size was provided, try to determine it using
  getsockopt(SO_RECVBUF) at runtime
- use one line for init function attributes, and make it static

Cheers,
Pierre



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

* [PATCH 2/3] Add new input plugin UNIXSOCK
  2009-08-23 22:45   ` Jan Engelhardt
  2009-09-02 20:45     ` Pierre Chifflier
  2009-09-03 21:23     ` (unknown), Pierre Chifflier
@ 2009-09-03 21:23     ` Pierre Chifflier
  2009-09-03 23:54       ` Jan Engelhardt
  2 siblings, 1 reply; 10+ messages in thread
From: Pierre Chifflier @ 2009-09-03 21:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eleblond, Pierre Chifflier

This input plugins creates a unix socket which can be used to log packets.
Scripts or applications can connect to the socket (only one client allowed
per socket) and send data in a Key-Length-Value format (including the
payload).

Signed-off-by: Pierre Chifflier <chifflier@inl.fr>
---
 input/packet/Makefile.am             |    5 +-
 input/packet/ulogd_inppkt_UNIXSOCK.c |  694 ++++++++++++++++++++++++++++++++++
 ulogd.conf.in                        |    7 +
 3 files changed, 705 insertions(+), 1 deletions(-)
 create mode 100644 input/packet/ulogd_inppkt_UNIXSOCK.c

diff --git a/input/packet/Makefile.am b/input/packet/Makefile.am
index e90e46e..566b817 100644
--- a/input/packet/Makefile.am
+++ b/input/packet/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
 AM_CFLAGS=-fPIC -Wall
 LIBS=
 
-pkglib_LTLIBRARIES = ulogd_inppkt_NFLOG.la ulogd_inppkt_ULOG.la
+pkglib_LTLIBRARIES = ulogd_inppkt_NFLOG.la ulogd_inppkt_ULOG.la ulogd_inppkt_UNIXSOCK.la
 
 ulogd_inppkt_NFLOG_la_SOURCES = ulogd_inppkt_NFLOG.c
 ulogd_inppkt_NFLOG_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_LOG_LIBS)
@@ -12,3 +12,6 @@ ulogd_inppkt_NFLOG_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_LOG_CFLAGS)
 ulogd_inppkt_ULOG_la_SOURCES = ulogd_inppkt_ULOG.c
 ulogd_inppkt_ULOG_la_LDFLAGS = -avoid-version -module
 ulogd_inppkt_ULOG_la_LIBADD = ../../libipulog/libipulog.la
+
+ulogd_inppkt_UNIXSOCK_la_SOURCES = ulogd_inppkt_UNIXSOCK.c
+ulogd_inppkt_UNIXSOCK_la_LDFLAGS = -avoid-version -module
diff --git a/input/packet/ulogd_inppkt_UNIXSOCK.c b/input/packet/ulogd_inppkt_UNIXSOCK.c
new file mode 100644
index 0000000..9720784
--- /dev/null
+++ b/input/packet/ulogd_inppkt_UNIXSOCK.c
@@ -0,0 +1,694 @@
+/*
+ ** Copyright(C) 2008-2009 INL
+ ** Written by  Pierre Chifflier <chifflier@inl.fr>
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#include <ulogd/ulogd.h>
+
+/* Default size of the receive buffer for the unix socket
+   0 means that ulogd will use getsockopt(SO_RCVBUF) to determine it
+   at runtime */
+#define UNIXSOCK_BUFSIZE_DEFAULT	0
+
+/* Default unix socket path */
+#define UNIXSOCK_UNIXPATH_DEFAULT	"/tmp/ulogd2.sock"
+
+
+#define UNIX_PATH_MAX	108
+
+
+struct unixsock_input {
+	char *path;
+	char *unixsock_buf;
+	unsigned int unixsock_buf_avail;
+	unsigned int unixsock_buf_size;
+	struct ulogd_fd unixsock_server_fd;
+	struct ulogd_fd unixsock_instance_fd;
+};
+
+enum nflog_keys {
+	UNIXSOCK_KEY_RAW_MAC = 0,
+	UNIXSOCK_KEY_RAW_PCKT,
+	UNIXSOCK_KEY_RAW_PCKTLEN,
+	UNIXSOCK_KEY_RAW_PCKTCOUNT,
+	UNIXSOCK_KEY_OOB_PREFIX,
+	UNIXSOCK_KEY_OOB_TIME_SEC,
+	UNIXSOCK_KEY_OOB_TIME_USEC,
+	UNIXSOCK_KEY_OOB_MARK,
+	UNIXSOCK_KEY_OOB_IN,
+	UNIXSOCK_KEY_OOB_OUT,
+	UNIXSOCK_KEY_OOB_HOOK,
+	UNIXSOCK_KEY_RAW_MAC_LEN,
+	UNIXSOCK_KEY_OOB_SEQ_LOCAL,
+	UNIXSOCK_KEY_OOB_SEQ_GLOBAL,
+	UNIXSOCK_KEY_OOB_FAMILY,
+	UNIXSOCK_KEY_OOB_PROTOCOL,
+	UNIXSOCK_KEY_OOB_UID,
+	UNIXSOCK_KEY_OOB_GID,
+	UNIXSOCK_KEY_RAW_LABEL,
+	UNIXSOCK_KEY_RAW_TYPE,
+	UNIXSOCK_KEY_RAW_MAC_SADDR,
+	UNIXSOCK_KEY_RAW_MAC_ADDRLEN,
+	UNIXSOCK_KEY_NUFW_USER_NAME,
+	UNIXSOCK_KEY_NUFW_USER_ID,
+	UNIXSOCK_KEY_NUFW_OS_NAME,
+	UNIXSOCK_KEY_NUFW_OS_REL,
+	UNIXSOCK_KEY_NUFW_OS_VERS,
+	UNIXSOCK_KEY_NUFW_APP_NAME,
+};
+
+static struct ulogd_key output_keys[] = {
+	[UNIXSOCK_KEY_RAW_MAC] = {
+		.type = ULOGD_RET_RAW,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac",
+	},
+	[UNIXSOCK_KEY_RAW_MAC_SADDR] = {
+		.type = ULOGD_RET_RAW,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac.saddr",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_sourceMacAddress,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_PCKT] = {
+		.type = ULOGD_RET_RAW,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.pkt",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_rawpacket,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_PCKTLEN] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.pktlen",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_rawpacket_length,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_PCKTCOUNT] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.pktcount",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_packetDeltaCount,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_PREFIX] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.prefix",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_prefix,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_TIME_SEC] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.time.sec",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_flowStartSeconds,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_TIME_USEC] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.time.usec",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_flowStartMicroSeconds,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_MARK] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.mark",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_mark,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_IN] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.in",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_ingressInterface,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_OUT] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.out",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_IETF,
+			.field_id = IPFIX_egressInterface,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_HOOK] = {
+		.type = ULOGD_RET_UINT8,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.hook",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_hook,
+		},
+	},
+	[UNIXSOCK_KEY_RAW_MAC_LEN] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac_len",
+	},
+	[UNIXSOCK_KEY_RAW_MAC_ADDRLEN] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.mac.addrlen",
+	},
+
+	[UNIXSOCK_KEY_OOB_SEQ_LOCAL] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.seq.local",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_seq_local,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_SEQ_GLOBAL] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.seq.global",
+		.ipfix = {
+			.vendor = IPFIX_VENDOR_NETFILTER,
+			.field_id = IPFIX_NF_seq_global,
+		},
+	},
+	[UNIXSOCK_KEY_OOB_FAMILY] = {
+		.type = ULOGD_RET_UINT8,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.family",
+	},
+	[UNIXSOCK_KEY_OOB_PROTOCOL] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.protocol",
+	},
+	[UNIXSOCK_KEY_OOB_UID] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.uid",
+	},
+	[UNIXSOCK_KEY_OOB_GID] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "oob.gid",
+	},
+	[UNIXSOCK_KEY_RAW_LABEL] = {
+		.type = ULOGD_RET_UINT8,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.label",
+	},
+	[UNIXSOCK_KEY_RAW_TYPE] = {
+		.type = ULOGD_RET_UINT16,
+		.flags = ULOGD_RETF_NONE,
+		.name = "raw.type",
+	},
+	[UNIXSOCK_KEY_NUFW_USER_NAME] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.user.name",
+	},
+	[UNIXSOCK_KEY_NUFW_USER_ID] = {
+		.type = ULOGD_RET_UINT32,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.user.id",
+	},
+	[UNIXSOCK_KEY_NUFW_OS_NAME] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.os.name",
+	},
+	[UNIXSOCK_KEY_NUFW_OS_REL] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.os.rel",
+	},
+	[UNIXSOCK_KEY_NUFW_OS_VERS] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.os.vers",
+	},
+	[UNIXSOCK_KEY_NUFW_APP_NAME] = {
+		.type = ULOGD_RET_STRING,
+		.flags = ULOGD_RETF_NONE,
+		.name = "nufw.app.name",
+	},
+};
+
+static struct config_keyset libunixsock_kset = {
+	.num_ces = 2,
+	.ces = {
+		{
+			.key 	 = "socket_path",
+			.type 	 = CONFIG_TYPE_STRING,
+			.options = CONFIG_OPT_NONE,
+			.u.string = UNIXSOCK_UNIXPATH_DEFAULT,
+		},
+		{
+			.key 	 = "bufsize",
+			.type 	 = CONFIG_TYPE_INT,
+			.options = CONFIG_OPT_NONE,
+			.u.value = UNIXSOCK_BUFSIZE_DEFAULT,
+		},
+	},
+};
+
+#define unixpath_ce(x)		(x->ces[0])
+#define bufsize_ce(x)		(x->ces[1])
+
+
+enum ulogd2_option_type {
+	ULOGD2_OPT_UNUSED = 0,
+	ULOGD2_OPT_PREFIX,	/* log prefix (string) */
+	ULOGD2_OPT_OOB_IN,	/* input device (string) */
+	ULOGD2_OPT_OOB_OUT,	/* output device (string) */
+	ULOGD2_OPT_OOB_TIME_SEC,	/* packet arrival time (u_int32_t) */
+
+	ULOGD2_OPT_USER=200,	/* user name (string) */
+	ULOGD2_OPT_USERID,	/* user id (u_int32_t) */
+	ULOGD2_OPT_OSNAME,	/* OS name (string) */
+	ULOGD2_OPT_OSREL,	/* OS release (string) */
+	ULOGD2_OPT_OSVERS,	/* OS version (string) */
+	ULOGD2_OPT_APPNAME,	/* application name (string) */
+	ULOGD2_OPT_STATE,	/* connection state: 0 (drop), 1 (open), 2 (established), 3 (close), 4 (unknown) */
+};
+
+static int handle_packet(struct ulogd_pluginstance *upi, u_int16_t total_len)
+{
+	struct unixsock_input *ui = (struct unixsock_input *)upi->private;
+	char *data;
+	struct iphdr *ip;
+	struct ulogd_key *ret = upi->output.keys;
+	u_int8_t oob_family;
+	u_int16_t payload_len;
+	u_int16_t option_number;
+	u_int16_t option_length;
+	char *buf;
+
+	ulogd_log(ULOGD_DEBUG,
+			"ulogd2: handling packet\n");
+
+	data = ui->unixsock_buf + sizeof(u_int16_t);
+	payload_len = ntohs(*(u_int16_t*)data);
+	data += sizeof(u_int16_t);
+
+
+	ip = (struct iphdr *) data;
+
+	if (ip->version == 4)
+		oob_family = AF_INET;
+	else if (ip->version == 6)
+		oob_family = AF_INET6;
+	else oob_family = 0;
+
+	okey_set_u8(&ret[UNIXSOCK_KEY_OOB_FAMILY], oob_family);
+
+	okey_set_ptr(&ret[UNIXSOCK_KEY_RAW_PCKT], ip);
+	okey_set_u32(&ret[UNIXSOCK_KEY_RAW_PCKTLEN], payload_len);
+
+	/* options */
+	if (total_len > payload_len + sizeof(u_int16_t)) {
+		data = ui->unixsock_buf + payload_len + 2*sizeof(u_int16_t);
+
+		while ( (data - ui->unixsock_buf) < total_len) {
+
+			option_number = ntohs(*(u_int16_t*)(data));
+			data += sizeof(u_int16_t);
+			option_length = ntohs(*(u_int16_t*)(data));
+			data += sizeof(u_int16_t);
+			buf = data;
+			data += option_length;
+
+			ulogd_log(ULOGD_DEBUG,
+					"ulogd2: option %d (len %d) `%s'\n",
+					option_number, option_length, buf);
+
+			switch(option_number) {
+				case ULOGD2_OPT_PREFIX:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_OOB_PREFIX], buf);
+					break;
+				case ULOGD2_OPT_OOB_IN:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_OOB_IN], buf);
+					break;
+				case ULOGD2_OPT_OOB_OUT:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_OOB_OUT], buf);
+					break;
+				case ULOGD2_OPT_OOB_TIME_SEC:
+					okey_set_u32(&ret[UNIXSOCK_KEY_OOB_TIME_SEC], *(u_int32_t*)buf);
+					break;
+				case ULOGD2_OPT_USER:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_USER_NAME], buf);
+					break;
+				case ULOGD2_OPT_USERID:
+					okey_set_u32(&ret[UNIXSOCK_KEY_NUFW_USER_ID], *(u_int32_t*)buf);
+					break;
+				case ULOGD2_OPT_OSNAME:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_OS_NAME], buf);
+					break;
+				case ULOGD2_OPT_OSREL:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_OS_REL], buf);
+					break;
+				case ULOGD2_OPT_OSVERS:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_OS_VERS], buf);
+					break;
+				case ULOGD2_OPT_APPNAME:
+					okey_set_ptr(&ret[UNIXSOCK_KEY_NUFW_APP_NAME], buf);
+					break;
+				case ULOGD2_OPT_STATE:
+					okey_set_u8(&ret[UNIXSOCK_KEY_RAW_LABEL], *(u_int8_t*)buf);
+					break;
+				default:
+					ulogd_log(ULOGD_NOTICE,
+							"ulogd2: unknown option %d\n",
+							option_number);
+					break;
+			};
+		}
+	}
+
+	/* number of packets */
+	okey_set_u32(&ret[UNIXSOCK_KEY_RAW_PCKTCOUNT], 1);
+
+	ulogd_propagate_results(upi);
+
+	/* consume data */
+	ui->unixsock_buf_avail -= total_len;
+	if (ui->unixsock_buf_avail > 0) {
+		/* we need to shift data .. */
+		memmove(ui->unixsock_buf,
+			ui->unixsock_buf + total_len ,
+			ui->unixsock_buf_avail);
+	}
+
+	return 0;
+}
+
+static int _create_unix_socket(const char *unix_path)
+{
+	int ret = -1;
+	struct sockaddr_un server_sock;
+	int s;
+
+	s = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (s < 0)
+		return -1;
+
+	server_sock.sun_family = AF_UNIX;
+	strncpy(server_sock.sun_path, unix_path, sizeof(server_sock.sun_path));
+	server_sock.sun_path[sizeof(server_sock.sun_path)-1] = '\0';
+
+	/* remove existing socket, if any */
+	unlink(unix_path);
+
+	ret = bind(s, (struct sockaddr *)&server_sock, sizeof(server_sock));
+	if (ret < 0) {
+		ulogd_log(ULOGD_ERROR,
+				"ulogd2: could not bind to unix socket \'%s\'\n",
+				server_sock.sun_path);
+		close(s);
+		return -1;
+	}
+
+	ret = listen(s, 10);
+	if (ret < 0) {
+		ulogd_log(ULOGD_ERROR,
+				"ulogd2: could not bind to unix socket \'%s\'\n",
+				server_sock.sun_path);
+		close(s);
+		return -1;
+	}
+
+
+	return s;
+}
+
+/* warning: this code is NOT reentrant ! */
+static void _timer_unregister_cb(struct ulogd_timer *a, void *param)
+{
+	struct unixsock_input *ui = param;
+
+	if (ui->unixsock_instance_fd.fd >= 0) {
+		ulogd_log(ULOGD_DEBUG, "  removing client from list\n");
+		ulogd_unregister_fd(&ui->unixsock_instance_fd);
+		close(ui->unixsock_instance_fd.fd);
+		ui->unixsock_instance_fd.fd = -1;
+	}
+}
+
+/* callback called from ulogd core when fd is readable */
+static int unixsock_instance_read_cb(int fd, unsigned int what, void *param)
+{
+	struct ulogd_pluginstance *upi = param;
+	struct unixsock_input *ui = (struct unixsock_input*)upi->private;
+	int len;
+	u_int16_t needed_len;
+
+	char buf[4096];
+
+	if (!(what & ULOGD_FD_READ))
+		return 0;
+
+	len = read(fd, buf, sizeof(buf));
+	if (len < 0) {
+		ulogd_log(ULOGD_NOTICE, "  read returned %d, errno is %d (%s)\n",
+					len, errno, strerror(errno));
+		exit(-1);
+		return len;
+	}
+	if (len == 0) {
+		struct ulogd_timer *t = malloc(sizeof(struct ulogd_timer));
+
+		ulogd_log(ULOGD_DEBUG, "  client disconnected\n");
+		/* we can't call ulogd_unregister_fd fd, it will segfault
+		 * (unable to remove an entry while inside llist_for_each_entry)
+		 * so we schedule removal for next loop
+		 */
+		ulogd_init_timer(t, ui, _timer_unregister_cb);
+		ulogd_add_timer(t, 0);
+		return 0;
+	}
+
+	buf[len] = '\0';
+
+	ulogd_log(ULOGD_DEBUG, "  read %d bytes\n", len);
+	//ulogd_log(ULOGD_DEBUG, "  buffer [%s]\n", buf);
+
+	if (ui->unixsock_buf_avail + len > ui->unixsock_buf_size) {
+		ulogd_log(ULOGD_NOTICE,
+			  "We are losing events. Please consider using the clause "
+			  "bufsize\n");
+		return -1;
+	}
+
+	memcpy(ui->unixsock_buf + ui->unixsock_buf_avail,
+	       buf,
+	       len);
+	ui->unixsock_buf_avail += len;
+
+	do {
+		needed_len = ntohs(*(u_int16_t*)ui->unixsock_buf);
+
+		if (ui->unixsock_buf_avail >= needed_len) {
+			ulogd_log(ULOGD_DEBUG, "  We have enough data, handling packet\n");
+
+
+			/* do we have only one packet */
+			if (ui->unixsock_buf_avail == needed_len)
+				return handle_packet(upi, needed_len);
+			else {
+				if (handle_packet(upi, needed_len) != 0)
+					return -1;
+			}
+
+		} else {
+			ulogd_log(ULOGD_DEBUG, "  We have %d bytes, but need %d. Requesting more\n",
+					ui->unixsock_buf_avail, needed_len);
+			return 0;
+		}
+
+		/* handle_packet has shifted data in buffer */
+	} while (1);
+
+	return 0;
+}
+
+/* callback called from ulogd core when fd is readable */
+static int unixsock_server_read_cb(int fd, unsigned int what, void *param)
+{
+	struct ulogd_pluginstance *upi = param;
+	struct unixsock_input *ui = (struct unixsock_input*)upi->private;
+	socklen_t len;
+	int s;
+	struct sockaddr_storage saddr;
+
+	if (!(what & ULOGD_FD_READ))
+		return 0;
+
+	ulogd_log(ULOGD_DEBUG, "New server connected on unixsock socket\n");
+
+	len = sizeof(saddr);
+	s = accept(fd, (struct sockaddr*)&saddr, &len);
+	if (s < 0) {
+		ulogd_log(ULOGD_NOTICE,
+				"  error while accepting new unixsock client, errno is %d (%s)\n",
+				errno, strerror(errno));
+		return len;
+	}
+
+	if (ui->unixsock_instance_fd.fd >= 0) {
+		ulogd_log(ULOGD_NOTICE, "a client is already connecting, rejecting new connection");
+		close(s);
+		return 0;
+	}
+
+	ui->unixsock_instance_fd.fd = s;
+	ui->unixsock_instance_fd.cb = &unixsock_instance_read_cb;
+	ui->unixsock_instance_fd.data = upi;
+	ui->unixsock_instance_fd.when = ULOGD_FD_READ;
+
+	if (ulogd_register_fd(&ui->unixsock_instance_fd) < 0) {
+		ulogd_log(ULOGD_ERROR, "unable to register client fd to ulogd\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+
+
+static int configure(struct ulogd_pluginstance *upi,
+		     struct ulogd_pluginstance_stack *stack)
+{
+	ulogd_log(ULOGD_DEBUG, "parsing config file section `%s', "
+		  "plugin `%s'\n", upi->id, upi->plugin->name);
+
+	config_parse_file(upi->id, upi->config_kset);
+	return 0;
+}
+
+static int start(struct ulogd_pluginstance *upi)
+{
+	struct unixsock_input *ui = (struct unixsock_input *) upi->private;
+	int fd;
+
+	ulogd_log(ULOGD_DEBUG, "Starting plugin `%s'\n",
+		  upi->plugin->name);
+
+	ui->path = unixpath_ce(upi->config_kset).u.string;
+
+	ulogd_log(ULOGD_DEBUG, "Creating Unix socket `%s'\n",
+		  ui->path);
+	fd = _create_unix_socket(unixpath_ce(upi->config_kset).u.string);
+	if (fd < 0) {
+		ulogd_log(ULOGD_ERROR, "unable to create unix socket on `%s'\n",
+			  ui->path);
+		return -1;
+	}
+
+	ui->unixsock_buf_avail = 0;
+	ui->unixsock_buf_size = bufsize_ce(upi->config_kset).u.value;
+
+	if (ui->unixsock_buf_size == 0) {
+		int fd_bufsize = 0;
+		socklen_t optlen = sizeof(fd_bufsize);
+
+		if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &fd_bufsize, &optlen) < 0) {
+			ulogd_log(ULOGD_ERROR,
+					"Could not determine socket buffer size. You have to use the clause "
+					"bufsize\n");
+			return -1;
+		}
+		ulogd_log(ULOGD_DEBUG, "bufsize is %d\n", fd_bufsize);
+
+		ui->unixsock_buf_size = fd_bufsize;
+	}
+	ui->unixsock_buf = malloc(ui->unixsock_buf_size);
+
+	ui->unixsock_server_fd.fd = fd;
+	ui->unixsock_server_fd.cb = &unixsock_server_read_cb;
+	ui->unixsock_server_fd.data = upi;
+	ui->unixsock_server_fd.when = ULOGD_FD_READ;
+
+	ui->unixsock_instance_fd.fd = -1;
+	ui->unixsock_instance_fd.cb = &unixsock_instance_read_cb;
+	ui->unixsock_instance_fd.data = upi;
+	ui->unixsock_instance_fd.when = ULOGD_FD_READ;
+
+	if (ulogd_register_fd(&ui->unixsock_server_fd) < 0) {
+		ulogd_log(ULOGD_ERROR, "unable to register fd to ulogd\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int stop(struct ulogd_pluginstance *upi)
+{
+	struct unixsock_input *ui = (struct unixsock_input *) upi->private;
+	char *unix_path = unixpath_ce(upi->config_kset).u.string;
+
+	ulogd_log(ULOGD_DEBUG, "Stopping plugin `%s'\n",
+		  upi->plugin->name);
+
+	if (unix_path)
+		unlink(unix_path);
+
+	free(ui->unixsock_buf);
+
+	return 0;
+}
+
+
+
+
+struct ulogd_plugin libunixsock_plugin = {
+	.name = "UNIXSOCK",
+	.input = {
+		.type = ULOGD_DTYPE_SOURCE,
+	},
+	.output = {
+		.type = ULOGD_DTYPE_RAW,
+		.keys = output_keys,
+		.num_keys = ARRAY_SIZE(output_keys),
+	},
+	.priv_size 	= sizeof(struct unixsock_input),
+	.configure 	= &configure,
+	.start 		= &start,
+	.stop 		= &stop,
+	.config_kset 	= &libunixsock_kset,
+	.version	= ULOGD_VERSION,
+};
+
+static void __attribute__ ((constructor)) init(void)
+{
+	ulogd_register_plugin(&libunixsock_plugin);
+}
diff --git a/ulogd.conf.in b/ulogd.conf.in
index 4542fc4..323462b 100644
--- a/ulogd.conf.in
+++ b/ulogd.conf.in
@@ -27,6 +27,7 @@ loglevel=1
 
 plugin="@libdir@/ulogd/ulogd_inppkt_NFLOG.so"
 #plugin="@libdir@/ulogd/ulogd_inppkt_ULOG.so"
+#plugin="@libdir@/ulogd/ulogd_inppkt_UNIXSOCK.so"
 plugin="@libdir@/ulogd/ulogd_inpflow_NFCT.so"
 plugin="@libdir@/ulogd/ulogd_filter_IFINDEX.so"
 plugin="@libdir@/ulogd/ulogd_filter_IP2STR.so"
@@ -75,6 +76,9 @@ plugin="@libdir@/ulogd/ulogd_raw2packet_BASE.so"
 # this is a stack for logging packets to syslog after a collect via NFLOG
 #stack=log3:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG
 
+# this is a stack for logging packets to syslog after a collect via NuFW
+#stack=nuauth1:UNIXSOCK,base1:BASE,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG
+
 # this is a stack for flow-based logging to MySQL
 #stack=ct1:NFCT,ip2bin1:IP2BIN,mysql2:MYSQL
 
@@ -137,6 +141,9 @@ numeric_label=1 # you can label the log info based on the packet verdict
 nlgroup=1
 #numeric_label=0 # optional argument
 
+[nuauth1]
+socket_path="/tmp/nuauth_ulogd2.sock"
+
 [emu1]
 file="/var/log/ulogd_syslogemu.log"
 sync=1
-- 
1.6.3.3


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

* Re: [PATCH 2/3] Add new input plugin UNIXSOCK
  2009-09-03 21:23     ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
@ 2009-09-03 23:54       ` Jan Engelhardt
  2009-09-08  9:35         ` Pierre Chifflier
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Engelhardt @ 2009-09-03 23:54 UTC (permalink / raw)
  To: Pierre Chifflier; +Cc: netfilter-devel, eleblond


On Thursday 2009-09-03 23:23, Pierre Chifflier wrote:
>+#include <ulogd/ulogd.h>
>+
>+/* Default size of the receive buffer for the unix socket
>+   0 means that ulogd will use getsockopt(SO_RCVBUF) to determine it
>+   at runtime */
>+#define UNIXSOCK_BUFSIZE_DEFAULT	0
>+
>+/* Default unix socket path */
>+#define UNIXSOCK_UNIXPATH_DEFAULT	"/tmp/ulogd2.sock"

That does not look like a good default path, though it might be
configurable at runtime. It seems that, because sockets are
world-connectable by default, random users could spam your socket.

Subsequently, there also seems to be an easy DoS whereby a user process 
only needs to connect to block a legitimate program from sending packets 
to the module.

Finally, but this is not so much of a problem, a user could also create 
ulogd2.sock first and then receive potentially interesting packets from 
a legitimate program that thought it would connect to ulogd2.

I would just move it out to, for example, /var/run/ulogd/ulogd2.sock
so one can set restrictions on /var/run/ulogd as needed.

What are your thoughts?

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

* Re: [PATCH 2/3] Add new input plugin UNIXSOCK
  2009-09-03 23:54       ` Jan Engelhardt
@ 2009-09-08  9:35         ` Pierre Chifflier
  0 siblings, 0 replies; 10+ messages in thread
From: Pierre Chifflier @ 2009-09-08  9:35 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Pierre Chifflier, netfilter-devel, eleblond

On Fri, Sep 04, 2009 at 01:54:42AM +0200, Jan Engelhardt wrote:
> >+/* Default unix socket path */
> >+#define UNIXSOCK_UNIXPATH_DEFAULT	"/tmp/ulogd2.sock"
> 
> That does not look like a good default path, though it might be
> configurable at runtime. It seems that, because sockets are
> world-connectable by default, random users could spam your socket.
> 
> Subsequently, there also seems to be an easy DoS whereby a user process 
> only needs to connect to block a legitimate program from sending packets 
> to the module.


True, when using unix socket you always have to set path, permissions
and chown it  ...

Maybe this could even be an option of ulogd.conf: unixsock_perms and
unixsock_owner ?

> 
> Finally, but this is not so much of a problem, a user could also create 
> ulogd2.sock first and then receive potentially interesting packets from 
> a legitimate program that thought it would connect to ulogd2.
> 
> I would just move it out to, for example, /var/run/ulogd/ulogd2.sock
> so one can set restrictions on /var/run/ulogd as needed.

Indeed, the only drawback is that the plugin will fail if the parent
directory does not exist.

Pierre

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

end of thread, other threads:[~2009-09-08  9:35 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-23 19:36 Remove debian directory, and add new UNIXSOCK input plugin Pierre Chifflier
2009-08-23 19:36 ` [PATCH 1/3] Remove debian directory Pierre Chifflier
2009-08-23 19:36 ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
2009-08-23 22:45   ` Jan Engelhardt
2009-09-02 20:45     ` Pierre Chifflier
2009-09-03 21:23     ` (unknown), Pierre Chifflier
2009-09-03 21:23     ` [PATCH 2/3] Add new input plugin UNIXSOCK Pierre Chifflier
2009-09-03 23:54       ` Jan Engelhardt
2009-09-08  9:35         ` Pierre Chifflier
2009-08-23 19:36 ` [PATCH 3/3] Add helper script pcap2ulog Pierre Chifflier

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).