* [ULOGD2] UNIXSOCK plugin (v5b) @ 2010-10-20 11:44 Pierre Chifflier 2010-10-20 11:44 ` [PATCH 1/2] Add new input plugin UNIXSOCK Pierre Chifflier ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Pierre Chifflier @ 2010-10-20 11:44 UTC (permalink / raw) To: netfilter-devel; +Cc: Eric Leblond Hi, First of all, sorry for the long time with no updates on this patch. This is a resend of the patches for the UNIXSOCK input plugin for ulogd2. Please let me know if there are any issues. PS: hope you enjoyed the oowall presentation :) Changes for v5: - align all structures on 64 bits instead of 32 This has been tested on a sparc64 (thanks to Jan) - update pcap2ulog to handle different pcap formats Changes for v4: - use structures instead of reading integers directly - all structures and fields are now aligned (4 bytes) - update pcap2ulog script to use aligned data as well Changes for v3: - if the bufsize value (from conf) is 0, try to guess the buffer size using getsockopt(SOL_SOCKET, SO_RCVBUF ..) - set default path to /var/run/ulogd/ulogd2.sock with mode 0600 - add new configuration options perms, owner and group to be able to set these parameters on the created socket - change the input algorithm to make it more robust against junk data (which can happen if the client is desynchronized) - fixed a few bugs Description: [1] 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. [2] is a Perl script to load a PCAP file and send it to ulogd using the UNIXSOCK plugin. Pierre ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] Add new input plugin UNIXSOCK 2010-10-20 11:44 [ULOGD2] UNIXSOCK plugin (v5b) Pierre Chifflier @ 2010-10-20 11:44 ` Pierre Chifflier 2010-10-20 11:44 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 2010-10-23 9:54 ` [ULOGD2] UNIXSOCK plugin (v5b) Eric Leblond 2 siblings, 0 replies; 8+ messages in thread From: Pierre Chifflier @ 2010-10-20 11:44 UTC (permalink / raw) To: netfilter-devel; +Cc: Eric Leblond, Pierre Chifflier, Pierre Chifflier From: Pierre Chifflier <chifflier@inl.fr> 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@edenwall.com> --- input/packet/Makefile.am | 5 +- input/packet/ulogd_inppkt_UNIXSOCK.c | 826 ++++++++++++++++++++++++++++++++++ ulogd.conf.in | 7 + 3 files changed, 837 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..368df93 --- /dev/null +++ b/input/packet/ulogd_inppkt_UNIXSOCK.c @@ -0,0 +1,826 @@ +/* + * UNIXSOCK input module for ulogd + * + * Copyright(C) 2008-2010 INL + * Written by Pierre Chifflier <chifflier@edenwall.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2· + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <unistd.h> +#include <stdlib.h> +#include <netinet/ether.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <pwd.h> +#include <grp.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 + +#define UNIXSOCK_PERMS_DEFAULT 0600 + +#define UNIXSOCK_UNIXPATH_DEFAULT "/var/run/ulogd/ulogd2.sock" + +#define ULOGD_SOCKET_MARK 0x41c90fd4 + +struct unixsock_input { + char *path; + char *unixsock_buf; + unsigned int unixsock_perms; + 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, + /* Add new keys after this line */ +}; + +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 = 5, + .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, + }, + { + .key = "perms", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = UNIXSOCK_PERMS_DEFAULT, + }, + { + .key = "owner", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, + { + .key = "group", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, + }, +}; + +enum { + UNIXSOCK_OPT_UNIXPATH = 0, + UNIXSOCK_OPT_BUFSIZE, + UNIXSOCK_OPT_PERM, + UNIXSOCK_OPT_OWNER, + UNIXSOCK_OPT_GROUP, +}; + +#define unixpath_ce(x) ((x)->ces[UNIXSOCK_OPT_UNIXPATH]) +#define bufsize_ce(x) ((x)->ces[UNIXSOCK_OPT_BUFSIZE]) +#define perms_ce(x) ((x)->ces[UNIXSOCK_OPT_PERM]) +#define owner_ce(x) ((x)->ces[UNIXSOCK_OPT_OWNER]) +#define group_ce(x) ((x)->ces[UNIXSOCK_OPT_GROUP]) + +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) */ + + /* Add new options after this line */ +}; + +struct ulogd_unixsock_packet_t { + uint32_t marker; + uint16_t total_size; + uint32_t version:4, + reserved:28; + uint16_t payload_length; + struct iphdr payload; +} __attribute__((packed)); + +struct ulogd_unixsock_option_t { + uint32_t option_id; + uint32_t option_length; + char option_value[0]; +} __attribute__((packed)); + +#define USOCK_ALIGNTO 8 +#define USOCK_ALIGN(len) ( ((len)+USOCK_ALIGNTO-1) & ~(USOCK_ALIGNTO-1) ) + +static int handle_packet(struct ulogd_pluginstance *upi, struct ulogd_unixsock_packet_t *pkt, u_int16_t total_len) +{ + char *data = NULL; + struct iphdr *ip; + struct ulogd_key *ret = upi->output.keys; + u_int8_t oob_family; + u_int16_t payload_len; + u_int32_t option_number; + u_int32_t option_length; + char *buf; + struct ulogd_unixsock_option_t *option; + int new_offset; + char *options_start; + + ulogd_log(ULOGD_DEBUG, + "ulogd2: handling packet\n"); + + payload_len = ntohs(pkt->payload_length); + + ip = &pkt->payload; + 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)) { + /* option starts at the next aligned address after the payload */ + new_offset = USOCK_ALIGN(payload_len); + options_start = (void*)ip + new_offset; + data = options_start; + total_len -= (options_start - (char*)pkt); + + while ( (data - options_start) < total_len) { + + option = (void*)data; + option_number = ntohl(option->option_id); + option_length = ntohl(option->option_length); + buf = option->option_value; + + /* next option is also aligned */ + new_offset = USOCK_ALIGN(option_length); + data += sizeof(option->option_id) + sizeof(option->option_length) + new_offset; + + 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); + + return 0; +} + +static int _create_unix_socket(const char *unix_path) +{ + int ret = -1; + struct sockaddr_un server_sock; + int s; + struct stat st_dummy; + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) { + ulogd_log(ULOGD_ERROR, + "ulogd2: could not create unix socket\n"); + 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'; + + if (stat(unix_path, &st_dummy) == 0 && st_dummy.st_size > 0) { + ulogd_log(ULOGD_ERROR, + "ulogd2: unix socket \'%s\' already exists\n", + unix_path); + close(s); + return -1; + } + + 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; +} + +static int _unix_socket_set_permissions(struct ulogd_pluginstance *upi) +{ + const char *socket_path; + const char *owner = owner_ce(upi->config_kset).u.string; + const char *group = group_ce(upi->config_kset).u.string; + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + + socket_path = unixpath_ce(upi->config_kset).u.string; + + if (chmod(socket_path, perms_ce(upi->config_kset).u.value) < 0) { + ulogd_log(ULOGD_ERROR, "Could not set permissions on unix socket\n"); + return -1; + } + + if (owner && strlen(owner)>0) { + struct passwd *p = getpwnam(owner); + + if (p == NULL) { + ulogd_log(ULOGD_ERROR, "Invalid owner specified for unix socket (%s)\n", owner); + return -1; + } + + uid = p->pw_uid; + } + + if (group && strlen(group)>0) { + struct group *g = getgrnam(group); + + if (g == NULL) { + ulogd_log(ULOGD_ERROR, "Invalid group specified for unix socket (%s)\n", group); + return -1; + } + + gid = g->gr_gid; + } + + if (chown(socket_path, uid, gid) < 0) { + ulogd_log(ULOGD_ERROR, "Could not set owner/group of unix socket\n"); + return -1; + } + + return 0; +} + +/* 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; + ui->unixsock_buf_avail = 0; + } +} + +static void _disconnect_client(struct unixsock_input *ui) +{ + struct ulogd_timer *t = malloc(sizeof(struct ulogd_timer)); + + /* 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); +} + +/* 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; + u_int32_t packet_sig; + struct ulogd_unixsock_packet_t *unixsock_packet; + + 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) { + _disconnect_client(ui); + ulogd_log(ULOGD_DEBUG, " client disconnected\n"); + return 0; + } + + 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; + + while(1) { + unixsock_packet = (void*)ui->unixsock_buf; + packet_sig = ntohl(unixsock_packet->marker); + if (packet_sig != ULOGD_SOCKET_MARK) { + ulogd_log(ULOGD_ERROR, + "ulogd2: invalid packet marked received " + "(read %lx, expected %lx), closing socket.\n", + packet_sig, ULOGD_SOCKET_MARK); + _disconnect_client(ui); + return -1; + + } + + needed_len = ntohs(unixsock_packet->total_size); + + if (ui->unixsock_buf_avail >= needed_len + sizeof(u_int32_t)) { + ulogd_log(ULOGD_DEBUG, + " We have enough data (%d bytes required), handling packet\n", + needed_len); + + if (handle_packet(upi, unixsock_packet, needed_len) != 0) { + return -1; + } + /* consume data */ + ui->unixsock_buf_avail -= (sizeof(u_int32_t) + needed_len); + if (ui->unixsock_buf_avail > 0) { + /* we need to shift data .. */ + memmove(ui->unixsock_buf, + ui->unixsock_buf + (sizeof(u_int32_t) + needed_len) , + ui->unixsock_buf_avail); + } else { + /* input buffer is empty, do not loop */ + return 0; + } + + } else { + ulogd_log(ULOGD_DEBUG, " We have %d bytes, but need %d. Requesting more\n", + ui->unixsock_buf_avail, needed_len + sizeof(u_int32_t)); + return 0; + } + + /* handle_packet has shifted data in buffer */ + }; + + 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(ui->path); + if (fd < 0) { + ulogd_log(ULOGD_ERROR, "Unable to create unix socket on `%s'\n", + ui->path); + return -1; + } + + if (_unix_socket_set_permissions(upi) < 0) { + 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 cda5bb9..634e37f 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" @@ -82,6 +83,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 @@ -145,6 +149,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.7.1 -- 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 related [flat|nested] 8+ messages in thread
* [PATCH 2/2] Add helper script pcap2ulog 2010-10-20 11:44 [ULOGD2] UNIXSOCK plugin (v5b) Pierre Chifflier 2010-10-20 11:44 ` [PATCH 1/2] Add new input plugin UNIXSOCK Pierre Chifflier @ 2010-10-20 11:44 ` Pierre Chifflier 2010-10-23 9:54 ` [ULOGD2] UNIXSOCK plugin (v5b) Eric Leblond 2 siblings, 0 replies; 8+ messages in thread From: Pierre Chifflier @ 2010-10-20 11:44 UTC (permalink / raw) To: netfilter-devel; +Cc: Eric Leblond, Pierre Chifflier, Pierre Chifflier From: Pierre Chifflier <chifflier@inl.fr> 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@edenwall.com> --- contrib/pcap2ulog | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 166 insertions(+), 0 deletions(-) create mode 100755 contrib/pcap2ulog diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog new file mode 100755 index 0000000..d4cd3dc --- /dev/null +++ b/contrib/pcap2ulog @@ -0,0 +1,166 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2009-2010 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 $ULOGD_SOCKET_MARK = 0x41c90fd4; + +my $dumpfile = shift or die "Unable to open pcap file"; +my($pcap_t, $err); +my($ulogd_client); +my $socketfile = "/var/run/ulogd2.sock"; +my $data_buffer; +my $linktype; +my $proto_offset; + +my %linktype_to_offset = ( + Net::Pcap::DLT_LINUX_SLL => 14, + Net::Pcap::DLT_EN10MB => 12, +); + +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 $!; + $ulogd_client->autoflush(0); +} + +sub print_padding +{ + my ($offset) = @_; + my $padding; + my $align = 8; + my $data; + + $padding = ($align - ($offset % $align)) % $align; + #print "offset: $offset padding $padding\n"; + + $data = "\0" x $padding; + $data_buffer .= $data; +} + +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"; + + my $size = length($pkt) - ($proto_offset+2); + + #my $pcaphdr = unpack ("H*", substr ($pkt, 0, 16)); + #printf("pcap hdr: $pcaphdr\n"); + my $proto = unpack ("H*", substr ($pkt, $proto_offset, 2)); + #printf("proto: $proto\n"); + + if ($proto ne "0800") { + print "ignoring packet with proto $proto\n"; + return; + } + + #my $ip_firstbyte = unpack ("H*", substr ($pkt, $proto_offset+2, 2)); + #printf("ip_firstbyte: $ip_firstbyte\n"); + + # decode packet for a SLL: + # 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 $srcmac = substr ($pkt, 6, 6); + + (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; + + $data_buffer = undef; + + # ulogd packet signature + $data = pack ('N', $ULOGD_SOCKET_MARK); + + $data_buffer .= $data; + + my $options_num=2; + my $options_len=length($hex_src) + length($hex_dst); + # total length (will be filled later) + my $total_size = 0; + $data = pack ('n', $total_size); + $data_buffer .= $data; + + # reserved + payload length + payload + $data = pack ('Nna*', 0, $size, substr($pkt,$proto_offset+2,$size)); + $data_buffer .= $data; + print_padding($size); + + # options + my $OOB_IN = 2; + $data = pack ('NNa*', $OOB_IN, length($hex_src), $hex_src); + $data_buffer .= $data; + print_padding(length($hex_src)); + my $OOB_OUT = 3; + $data = pack ('NNa*', $OOB_OUT, length($hex_dst), $hex_dst); + $data_buffer .= $data; + print_padding(length($hex_dst)); + + # replace total size in buffer + my $l = length($data_buffer) - 4; + substr($data_buffer, 4, 2) = pack('n', $l); + + #(my $hex = unpack("H*", $data_buffer)) =~ s/(..)/$1 /g; + #print "$l will be encoded as " . unpack("H*", pack('n', $l)) . "\n"; + #print $hex, "\n"; + + print $ulogd_client $data_buffer; + + $ulogd_client->flush; + + #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; +} + +$linktype = Net::Pcap::pcap_datalink($pcap_t); + +if (not exists $linktype_to_offset{$linktype}) { + print("Unsupported link type ", Net::Pcap::pcap_datalink_val_to_name($linktype), "\n"); + exit 1; +} + +$proto_offset = $linktype_to_offset{$linktype}; + +Net::Pcap::loop($pcap_t, -1, \&process_pkt, "xyz"); +Net::Pcap::close($pcap_t); + + + -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [ULOGD2] UNIXSOCK plugin (v5b) 2010-10-20 11:44 [ULOGD2] UNIXSOCK plugin (v5b) Pierre Chifflier 2010-10-20 11:44 ` [PATCH 1/2] Add new input plugin UNIXSOCK Pierre Chifflier 2010-10-20 11:44 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier @ 2010-10-23 9:54 ` Eric Leblond 2 siblings, 0 replies; 8+ messages in thread From: Eric Leblond @ 2010-10-23 9:54 UTC (permalink / raw) To: Pierre Chifflier; +Cc: netfilter-devel [-- Attachment #1: Type: text/plain, Size: 1720 bytes --] Hi, Le mercredi 20 octobre 2010 à 13:44 +0200, Pierre Chifflier a écrit : > Hi, > > First of all, sorry for the long time with no updates on this patch. > This is a resend of the patches for the UNIXSOCK input plugin for ulogd2. > > Please let me know if there are any issues. Patches pushed to the git tree. BR, > > PS: hope you enjoyed the oowall presentation :) > > > > Changes for v5: > - align all structures on 64 bits instead of 32 > This has been tested on a sparc64 (thanks to Jan) > - update pcap2ulog to handle different pcap formats > > Changes for v4: > - use structures instead of reading integers directly > - all structures and fields are now aligned (4 bytes) > - update pcap2ulog script to use aligned data as well > > Changes for v3: > - if the bufsize value (from conf) is 0, try to guess the buffer size > using getsockopt(SOL_SOCKET, SO_RCVBUF ..) > - set default path to /var/run/ulogd/ulogd2.sock with mode 0600 > - add new configuration options perms, owner and group to be able > to set these parameters on the created socket > - change the input algorithm to make it more robust against junk data (which > can happen if the client is desynchronized) > - fixed a few bugs > > Description: > > [1] 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. > > [2] is a Perl script to load a PCAP file and send it to ulogd using the > UNIXSOCK plugin. > > Pierre -- Eric Leblond <eric@inl.fr> INL: http://www.inl.fr/ NuFW: http://www.nufw.org/ [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 190 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] Add new input plugin UNIXSOCK
@ 2010-03-01 19:33 Pablo Neira Ayuso
2010-03-01 22:16 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier
0 siblings, 1 reply; 8+ messages in thread
From: Pablo Neira Ayuso @ 2010-03-01 19:33 UTC (permalink / raw)
To: Pierre Chifflier; +Cc: netfilter-devel, eleblond, Jan Engelhardt
Pierre Chifflier wrote:
> On Sun, Feb 28, 2010 at 05:28:38PM +0100, Pablo Neira Ayuso wrote:
>>>>> +struct ulogd_unixsock_option_t {
>>>>> + uint16_t option_id;
>>>>> + uint16_t option_length;
>>>>> + char option_value[0];
>>>>> +} __attribute__((packed));
>>>>> +
>>>>> +#define ALIGN_SIZE 8
>>>> Minor question: why align this to 64 bits?
>>> I originally used an alignment to 32 bits, but Jan noticed it would
>>> break if using options/values on 64 bits (and a test confirmed that). I
>>> took 64 bits as the biggest allowed value for integers.
>> I would need to look into this in more detail, not sure where the
>> problem is. I think that you can use something like `struct nlattr' (see
>> include/linux/netlink.h) and then nla_put() to add attributes in the TLV
>> format (see lib/nlattr.c). Those are align-safe. I'm using something
>> similar for conntrackd for the synchronization messages (src/build.c and
>> src/parse.c).
>
> Yes, this is very similar though NLA_ALIGNTO is set to 4 which will
> cause problems with 64 bits integers.
> The other way to solve this would be to read integers byte per byte,
> like in [1], but I found this not very elegant (and is likely to be slow
> compared to aligned access).
>
> Or do you have any preferred solution ? Maybe using nlattr + one special
> function for dealing with 64 bits variables ?
Aligning this to 8 bytes seems fine to me (messages would be bigger
though). I think that you can use something like:
struct ulogd_unixsock_option_t {
uint32_t option_id;
uint32_t option_length;
char option_value[0];
} __attribute__((packed));
So you can benefit from the extra bytes that would be added as padding.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] Add helper script pcap2ulog 2010-03-01 19:33 [PATCH 1/2] Add new input plugin UNIXSOCK Pablo Neira Ayuso @ 2010-03-01 22:16 ` Pierre Chifflier 0 siblings, 0 replies; 8+ messages in thread From: Pierre Chifflier @ 2010-03-01 22:16 UTC (permalink / raw) To: netfilter-devel; +Cc: eleblond, Pierre Chifflier, Pierre Chifflier From: Pierre Chifflier <chifflier@inl.fr> 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@edenwall.com> --- contrib/pcap2ulog | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 166 insertions(+), 0 deletions(-) create mode 100755 contrib/pcap2ulog diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog new file mode 100755 index 0000000..d4cd3dc --- /dev/null +++ b/contrib/pcap2ulog @@ -0,0 +1,166 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2009-2010 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 $ULOGD_SOCKET_MARK = 0x41c90fd4; + +my $dumpfile = shift or die "Unable to open pcap file"; +my($pcap_t, $err); +my($ulogd_client); +my $socketfile = "/var/run/ulogd2.sock"; +my $data_buffer; +my $linktype; +my $proto_offset; + +my %linktype_to_offset = ( + Net::Pcap::DLT_LINUX_SLL => 14, + Net::Pcap::DLT_EN10MB => 12, +); + +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 $!; + $ulogd_client->autoflush(0); +} + +sub print_padding +{ + my ($offset) = @_; + my $padding; + my $align = 8; + my $data; + + $padding = ($align - ($offset % $align)) % $align; + #print "offset: $offset padding $padding\n"; + + $data = "\0" x $padding; + $data_buffer .= $data; +} + +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"; + + my $size = length($pkt) - ($proto_offset+2); + + #my $pcaphdr = unpack ("H*", substr ($pkt, 0, 16)); + #printf("pcap hdr: $pcaphdr\n"); + my $proto = unpack ("H*", substr ($pkt, $proto_offset, 2)); + #printf("proto: $proto\n"); + + if ($proto ne "0800") { + print "ignoring packet with proto $proto\n"; + return; + } + + #my $ip_firstbyte = unpack ("H*", substr ($pkt, $proto_offset+2, 2)); + #printf("ip_firstbyte: $ip_firstbyte\n"); + + # decode packet for a SLL: + # 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 $srcmac = substr ($pkt, 6, 6); + + (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; + + $data_buffer = undef; + + # ulogd packet signature + $data = pack ('N', $ULOGD_SOCKET_MARK); + + $data_buffer .= $data; + + my $options_num=2; + my $options_len=length($hex_src) + length($hex_dst); + # total length (will be filled later) + my $total_size = 0; + $data = pack ('n', $total_size); + $data_buffer .= $data; + + # reserved + payload length + payload + $data = pack ('Nna*', 0, $size, substr($pkt,$proto_offset+2,$size)); + $data_buffer .= $data; + print_padding($size); + + # options + my $OOB_IN = 2; + $data = pack ('NNa*', $OOB_IN, length($hex_src), $hex_src); + $data_buffer .= $data; + print_padding(length($hex_src)); + my $OOB_OUT = 3; + $data = pack ('NNa*', $OOB_OUT, length($hex_dst), $hex_dst); + $data_buffer .= $data; + print_padding(length($hex_dst)); + + # replace total size in buffer + my $l = length($data_buffer) - 4; + substr($data_buffer, 4, 2) = pack('n', $l); + + #(my $hex = unpack("H*", $data_buffer)) =~ s/(..)/$1 /g; + #print "$l will be encoded as " . unpack("H*", pack('n', $l)) . "\n"; + #print $hex, "\n"; + + print $ulogd_client $data_buffer; + + $ulogd_client->flush; + + #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; +} + +$linktype = Net::Pcap::pcap_datalink($pcap_t); + +if (not exists $linktype_to_offset{$linktype}) { + print("Unsupported link type ", Net::Pcap::pcap_datalink_val_to_name($linktype), "\n"); + exit 1; +} + +$proto_offset = $linktype_to_offset{$linktype}; + +Net::Pcap::loop($pcap_t, -1, \&process_pkt, "xyz"); +Net::Pcap::close($pcap_t); + + + -- 1.7.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [ULOGD2] UNIXSOCK plugin (v5) @ 2010-02-26 20:54 Pierre Chifflier 2010-02-26 20:54 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 0 siblings, 1 reply; 8+ messages in thread From: Pierre Chifflier @ 2010-02-26 20:54 UTC (permalink / raw) To: netfilter-devel; +Cc: eleblond Hi, Here is an updated version of the UNIXSOCK plugin. Changes for v5: - align all structures on 64 bits instead of 32 This has been tested on a sparc64 (thanks to Jan) - update pcap2ulog to handle different pcap formats Changes for v4: - use structures instead of reading integers directly - all structures and fields are now aligned (4 bytes) - update pcap2ulog script to use aligned data as well Changes for v3: - if the bufsize value (from conf) is 0, try to guess the buffer size using getsockopt(SOL_SOCKET, SO_RCVBUF ..) - set default path to /var/run/ulogd/ulogd2.sock with mode 0600 - add new configuration options perms, owner and group to be able to set these parameters on the created socket - change the input algorithm to make it more robust against junk data (which can happen if the client is desynchronized) - fixed a few bugs Description: [1] 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. [2] is a Perl script to load a PCAP file and send it to ulogd using the UNIXSOCK plugin. Pierre ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] Add helper script pcap2ulog 2010-02-26 20:54 [ULOGD2] UNIXSOCK plugin (v5) Pierre Chifflier @ 2010-02-26 20:54 ` Pierre Chifflier 0 siblings, 0 replies; 8+ messages in thread From: Pierre Chifflier @ 2010-02-26 20:54 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@edenwall.com> --- contrib/pcap2ulog | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 166 insertions(+), 0 deletions(-) create mode 100755 contrib/pcap2ulog diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog new file mode 100755 index 0000000..65fd5ab --- /dev/null +++ b/contrib/pcap2ulog @@ -0,0 +1,166 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2009-2010 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 $ULOGD_SOCKET_MARK = 0x41c90fd4; + +my $dumpfile = shift or die "Unable to open pcap file"; +my($pcap_t, $err); +my($ulogd_client); +my $socketfile = "/var/run/ulogd2.sock"; +my $data_buffer; +my $linktype; +my $proto_offset; + +my %linktype_to_offset = ( + Net::Pcap::DLT_LINUX_SLL => 14, + Net::Pcap::DLT_EN10MB => 12, +); + +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 $!; + $ulogd_client->autoflush(0); +} + +sub print_padding +{ + my ($offset) = @_; + my $padding; + my $align = 8; + my $data; + + $padding = ($align - ($offset % $align)) % $align; + #print "offset: $offset padding $padding\n"; + + $data = "\0" x $padding; + $data_buffer .= $data; +} + +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"; + + my $size = length($pkt) - ($proto_offset+2); + + #my $pcaphdr = unpack ("H*", substr ($pkt, 0, 16)); + #printf("pcap hdr: $pcaphdr\n"); + my $proto = unpack ("H*", substr ($pkt, $proto_offset, 2)); + #printf("proto: $proto\n"); + + if ($proto ne "0800") { + print "ignoring packet with proto $proto\n"; + return; + } + + #my $ip_firstbyte = unpack ("H*", substr ($pkt, $proto_offset+2, 2)); + #printf("ip_firstbyte: $ip_firstbyte\n"); + + # decode packet for a SLL: + # 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 $srcmac = substr ($pkt, 6, 6); + + (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; + + $data_buffer = undef; + + # ulogd packet signature + $data = pack ('N', $ULOGD_SOCKET_MARK); + + $data_buffer .= $data; + + my $options_num=2; + my $options_len=length($hex_src) + length($hex_dst); + # total length (will be filled later) + my $total_size = 0; + $data = pack ('n', $total_size); + $data_buffer .= $data; + + # payload length + reserved + payload + $data = pack ('nNa*', $size, 0, substr($pkt,$proto_offset+2,$size)); + $data_buffer .= $data; + print_padding($size); + + # options + my $OOB_IN = 2; + $data = pack ('nna*', $OOB_IN, length($hex_src), $hex_src); + $data_buffer .= $data; + print_padding(length($hex_src)); + my $OOB_OUT = 3; + $data = pack ('nna*', $OOB_OUT, length($hex_dst), $hex_dst); + $data_buffer .= $data; + print_padding(length($hex_dst)); + + # replace total size in buffer + my $l = length($data_buffer) - 4; + substr($data_buffer, 4, 2) = pack('n', $l); + + #(my $hex = unpack("H*", $data_buffer)) =~ s/(..)/$1 /g; + #print "$l will be encoded as " . unpack("H*", pack('n', $l)) . "\n"; + #print $hex, "\n"; + + print $ulogd_client $data_buffer; + + $ulogd_client->flush; + + #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; +} + +$linktype = Net::Pcap::pcap_datalink($pcap_t); + +if (not exists $linktype_to_offset{$linktype}) { + print("Unsupported link type ", Net::Pcap::pcap_datalink_val_to_name($linktype), "\n"); + exit 1; +} + +$proto_offset = $linktype_to_offset{$linktype}; + +Net::Pcap::loop($pcap_t, -1, \&process_pkt, "xyz"); +Net::Pcap::close($pcap_t); + + + -- 1.7.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [ULOGD2] UNIXSOCK plugin (v4) @ 2010-01-14 19:41 Pierre Chifflier 2010-01-14 19:41 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 0 siblings, 1 reply; 8+ messages in thread From: Pierre Chifflier @ 2010-01-14 19:41 UTC (permalink / raw) To: netfilter-devel; +Cc: eleblond Hi, Here is an updated version of the UNIXSOCK plugin. Changes for v4: - use structures instead of reading integers directly - all structures and fields are now aligned (4 bytes) - update pcap2ulog script to use aligned data as well Changes for v3: - if the bufsize value (from conf) is 0, try to guess the buffer size using getsockopt(SOL_SOCKET, SO_RCVBUF ..) - set default path to /var/run/ulogd/ulogd2.sock with mode 0600 - add new configuration options perms, owner and group to be able to set these parameters on the created socket - change the input algorithm to make it more robust against junk data (which can happen if the client is desynchronized) - fixed a few bugs Description: [1] 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. [2] is a Perl script to load a PCAP file and send it to ulogd using the UNIXSOCK plugin. Pierre ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] Add helper script pcap2ulog 2010-01-14 19:41 [ULOGD2] UNIXSOCK plugin (v4) Pierre Chifflier @ 2010-01-14 19:41 ` Pierre Chifflier 0 siblings, 0 replies; 8+ messages in thread From: Pierre Chifflier @ 2010-01-14 19:41 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 | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 149 insertions(+), 0 deletions(-) create mode 100755 contrib/pcap2ulog diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog new file mode 100755 index 0000000..6f0d571 --- /dev/null +++ b/contrib/pcap2ulog @@ -0,0 +1,149 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2009-2010 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 $ULOGD_SOCKET_MARK = 0x41c90fd4; + +my $dumpfile = shift or die "Unable to open pcap file"; +my($pcap_t, $err); +my($ulogd_client); +my $socketfile = "/var/run/ulogd2.sock"; +my $data_buffer; + +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 $!; + $ulogd_client->autoflush(0); +} + +sub print_padding +{ + my ($offset) = @_; + my $padding; + my $align = 4; + my $data; + + $padding = ($align - ($offset % $align)) % $align; + #print "offset: $offset padding $padding\n"; + + $data = "\0" x $padding; + $data_buffer .= $data; +} + +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 $pcaphdr = unpack ("H*", substr ($pkt, 0, 16)); + #printf("pcap hdr: $pcaphdr\n"); + my $proto = unpack ("H*", substr ($pkt, 14, 2)); + #printf("proto: $proto\n"); + + if ($proto ne "0800") { + print "ignoring packet with proto $proto\n"; + return; + } + + (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; + + $data_buffer = undef; + + # ulogd packet signature + $data = pack ('N', $ULOGD_SOCKET_MARK); + + $data_buffer .= $data; + + my $options_num=2; + my $options_len=length($hex_src) + length($hex_dst); + # total length (will be filled later) + my $total_size = 0; + $data = pack ('n', $total_size); + $data_buffer .= $data; + + # payload length + payload + $data = pack ('na*', $size, substr($pkt,16,$size)); + $data_buffer .= $data; + print_padding($size); + + # options + my $OOB_IN = 2; + $data = pack ('nna*', $OOB_IN, length($hex_src), $hex_src); + $data_buffer .= $data; + print_padding(length($hex_src)); + my $OOB_OUT = 3; + $data = pack ('nna*', $OOB_OUT, length($hex_dst), $hex_dst); + $data_buffer .= $data; + print_padding(length($hex_dst)); + + # replace total size in buffer + my $l = length($data_buffer) - 4; + substr($data_buffer, 4, 2) = pack('n', $l); + + #(my $hex = unpack("H*", $data_buffer)) =~ s/(..)/$1 /g; + #print "total size $total_size, length is $l\n"; + #print "$l will be encoded as " . unpack("H*", pack('n', $l)) . "\n"; + #print $hex, "\n"; + + print $ulogd_client $data_buffer; + + $ulogd_client->flush; + + #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.6 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [ULOGD2] UNIXSOCK plugin (v3) @ 2009-11-01 10:53 Pierre Chifflier 2009-11-01 10:53 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 0 siblings, 1 reply; 8+ messages in thread From: Pierre Chifflier @ 2009-11-01 10:53 UTC (permalink / raw) To: netfilter-devel; +Cc: eleblond Hi, Here is an updated version of the UNIXSOCK plugin. Changes since last version: - if the bufsize value (from conf) is 0, try to guess the buffer size using getsockopt(SOL_SOCKET, SO_RCVBUF ..) - set default path to /var/run/ulogd/ulogd2.sock with mode 0600 - add new configuration options perms, owner and group to be able to set these parameters on the created socket - change the input algorithm to make it more robust against junk data (which can happen if the client is desynchronized) - fixed a few bugs Description: [1] 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. [2] is a Perl script to load a PCAP file and send it to ulogd using the UNIXSOCK plugin. Pierre ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] Add helper script pcap2ulog 2009-11-01 10:53 [ULOGD2] UNIXSOCK plugin (v3) Pierre Chifflier @ 2009-11-01 10:53 ` Pierre Chifflier 0 siblings, 0 replies; 8+ messages in thread From: Pierre Chifflier @ 2009-11-01 10:53 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 | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) create mode 100755 contrib/pcap2ulog diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog new file mode 100755 index 0000000..6c04dd9 --- /dev/null +++ b/contrib/pcap2ulog @@ -0,0 +1,101 @@ +#!/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 $ULOGD_SOCKET_MARK = 0x41c90fd4; + +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; + + # ulogd packet signature + $data = pack ('N', $ULOGD_SOCKET_MARK); + print $ulogd_client $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.5.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-10-26 14:50 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-10-20 11:44 [ULOGD2] UNIXSOCK plugin (v5b) Pierre Chifflier 2010-10-20 11:44 ` [PATCH 1/2] Add new input plugin UNIXSOCK Pierre Chifflier 2010-10-20 11:44 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 2010-10-23 9:54 ` [ULOGD2] UNIXSOCK plugin (v5b) Eric Leblond -- strict thread matches above, loose matches on Subject: below -- 2010-03-01 19:33 [PATCH 1/2] Add new input plugin UNIXSOCK Pablo Neira Ayuso 2010-03-01 22:16 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 2010-02-26 20:54 [ULOGD2] UNIXSOCK plugin (v5) Pierre Chifflier 2010-02-26 20:54 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 2010-01-14 19:41 [ULOGD2] UNIXSOCK plugin (v4) Pierre Chifflier 2010-01-14 19:41 ` [PATCH 2/2] Add helper script pcap2ulog Pierre Chifflier 2009-11-01 10:53 [ULOGD2] UNIXSOCK plugin (v3) Pierre Chifflier 2009-11-01 10:53 ` [PATCH 2/2] 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).