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