All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.