From: Philip Craig <philipc@snapgear.com>
To: Netfilter Developer Mailing List <netfilter-devel@lists.netfilter.org>
Subject: [PATCH 3/3] libnl: add netfilter log support
Date: Mon, 03 Sep 2007 15:12:32 +1000 [thread overview]
Message-ID: <46DB97C0.3060602@snapgear.com> (raw)
In-Reply-To: <46DB9716.1020400@snapgear.com>
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: nfnl_log.patch --]
[-- Type: text/x-diff, Size: 29757 bytes --]
---
include/linux/netfilter/nfnetlink_log.h | 96 +++++++
include/netlink-types.h | 22 +
include/netlink/netfilter/log.h | 105 +++++++
lib/netfilter/log.c | 349 ++++++++++++++++++++++++++
lib/netfilter/log_obj.c | 425 ++++++++++++++++++++++++++++++++
src/nf-log.c | 142 ++++++++++
6 files changed, 1139 insertions(+)
Index: libnl/include/netlink-types.h
===================================================================
--- libnl.orig/include/netlink-types.h 2007-09-03 14:32:20.000000000 +1000
+++ libnl/include/netlink-types.h 2007-09-03 14:32:21.000000000 +1000
@@ -839,4 +839,26 @@ struct nfnl_ct {
struct nfnl_ct_dir ct_repl;
};
+struct nfnl_log {
+ NLHDR_COMMON
+
+ uint8_t log_family;
+ uint8_t log_hook;
+ uint16_t log_hwproto;
+ uint32_t log_mark;
+ struct timeval log_timestamp;
+ uint32_t log_indev;
+ uint32_t log_outdev;
+ uint32_t log_physindev;
+ uint32_t log_physoutdev;
+ uint8_t log_hwaddr[8];
+ int log_hwaddr_len;
+ void * log_payload;
+ int log_payload_len;
+ char * log_prefix;
+ uint32_t log_uid;
+ uint32_t log_seq;
+ uint32_t log_seq_global;
+};
+
#endif
Index: libnl/include/netlink/netfilter/log.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/include/netlink/netfilter/log.h 2007-09-03 14:32:21.000000000 +1000
@@ -0,0 +1,105 @@
+/*
+ * netlink/netfilter/log.h Netfilter Log
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
+ * Copyright (c) 2007 Secure Computing Corporation
+ */
+
+#ifndef NETLINK_LOG_H_
+#define NETLINK_LOG_H_
+
+#include <netlink/netlink.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct nl_handle;
+struct nlmsghdr;
+struct nfnl_log;
+
+extern struct nl_object_ops log_obj_ops;
+
+/* General */
+extern struct nfnl_log *nfnl_log_alloc(void);
+extern struct nfnl_log *nfnlmsg_log_parse(struct nlmsghdr *);
+
+extern void nfnl_log_get(struct nfnl_log *);
+extern void nfnl_log_put(struct nfnl_log *);
+
+extern struct nl_msg * nfnl_log_build_bind(uint16_t);;
+extern int nfnl_log_bind(struct nl_handle *, uint16_t);
+extern struct nl_msg * nfnl_log_build_unbind(uint16_t);
+extern int nfnl_log_unbind(struct nl_handle *, uint16_t);
+extern struct nl_msg * nfnl_log_build_pf_bind(uint8_t);
+extern int nfnl_log_pf_bind(struct nl_handle *, uint8_t);
+extern struct nl_msg * nfnl_log_build_pf_unbind(uint8_t);
+extern int nfnl_log_pf_unbind(struct nl_handle *, uint8_t);
+extern struct nl_msg * nfnl_log_build_mode(uint16_t, uint8_t, uint32_t);
+extern int nfnl_log_set_mode(struct nl_handle *, uint16_t,
+ uint8_t, uint32_t);
+
+extern void nfnl_log_set_family(struct nfnl_log *, uint8_t);
+extern uint8_t nfnl_log_get_family(const struct nfnl_log *);
+
+extern void nfnl_log_set_hwproto(struct nfnl_log *, uint16_t);
+extern int nfnl_log_test_hwproto(const struct nfnl_log *);
+extern uint16_t nfnl_log_get_hwproto(const struct nfnl_log *);
+
+extern void nfnl_log_set_hook(struct nfnl_log *, uint8_t);
+extern int nfnl_log_test_hook(const struct nfnl_log *);
+extern uint8_t nfnl_log_get_hook(const struct nfnl_log *);
+
+extern void nfnl_log_set_mark(struct nfnl_log *, uint32_t);
+extern int nfnl_log_test_mark(const struct nfnl_log *);
+extern uint32_t nfnl_log_get_mark(const struct nfnl_log *);
+
+extern void nfnl_log_set_timestamp(struct nfnl_log *,
+ struct timeval *);
+extern const struct timeval *nfnl_log_get_timestamp(const struct nfnl_log *);
+
+extern void nfnl_log_set_indev(struct nfnl_log *, uint32_t);
+extern uint32_t nfnl_log_get_indev(const struct nfnl_log *);
+
+extern void nfnl_log_set_outdev(struct nfnl_log *, uint32_t);
+extern uint32_t nfnl_log_get_outdev(const struct nfnl_log *);
+
+extern void nfnl_log_set_physindev(struct nfnl_log *, uint32_t);
+extern uint32_t nfnl_log_get_physindev(const struct nfnl_log *);
+
+extern void nfnl_log_set_physoutdev(struct nfnl_log *, uint32_t);
+extern uint32_t nfnl_log_get_physoutdev(const struct nfnl_log *);
+
+extern void nfnl_log_set_hwaddr(struct nfnl_log *, uint8_t *, int);
+extern const uint8_t * nfnl_log_get_hwaddr(const struct nfnl_log *, int *);
+
+extern int nfnl_log_set_payload(struct nfnl_log *, uint8_t *, int);
+extern const void * nfnl_log_get_payload(const struct nfnl_log *, int *);
+
+extern int nfnl_log_set_prefix(struct nfnl_log *, void *);
+extern const char * nfnl_log_get_prefix(const struct nfnl_log *);
+
+extern void nfnl_log_set_uid(struct nfnl_log *, uint32_t);
+extern int nfnl_log_test_uid(const struct nfnl_log *);
+extern uint32_t nfnl_log_get_uid(const struct nfnl_log *);
+
+extern void nfnl_log_set_seq(struct nfnl_log *, uint32_t);
+extern int nfnl_log_test_seq(const struct nfnl_log *);
+extern uint32_t nfnl_log_get_seq(const struct nfnl_log *);
+
+extern void nfnl_log_set_seq_global(struct nfnl_log *, uint32_t);
+extern int nfnl_log_test_seq_global(const struct nfnl_log *);
+extern uint32_t nfnl_log_get_seq_global(const struct nfnl_log *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: libnl/lib/netfilter/log.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/lib/netfilter/log.c 2007-09-03 14:32:21.000000000 +1000
@@ -0,0 +1,349 @@
+/*
+ * lib/netfilter/log.c Netfilter Log
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
+ * Copyright (c) 2007 Secure Computing Corporation
+ */
+
+/**
+ * @ingroup nfnl
+ * @defgroup log Log
+ * @brief
+ * @{
+ */
+
+#include <sys/types.h>
+#include <linux/netfilter/nfnetlink_log.h>
+
+#include <netlink-local.h>
+#include <netlink/attr.h>
+#include <netlink/netfilter/nfnl.h>
+#include <netlink/netfilter/log.h>
+
+static struct nl_cache_ops nfnl_log_ops;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+static uint64_t ntohll(uint64_t x)
+{
+ return x;
+}
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+static uint64_t ntohll(uint64_t x)
+{
+ return __bswap_64(x);
+}
+#endif
+
+static struct nla_policy log_policy[NFULA_MAX+1] = {
+ [NFULA_PACKET_HDR] = {
+ .minlen = sizeof(struct nfulnl_msg_packet_hdr)
+ },
+ [NFULA_MARK] = { .type = NLA_U32 },
+ [NFULA_TIMESTAMP] = {
+ .minlen = sizeof(struct nfulnl_msg_packet_timestamp)
+ },
+ [NFULA_IFINDEX_INDEV] = { .type = NLA_U32 },
+ [NFULA_IFINDEX_OUTDEV] = { .type = NLA_U32 },
+ [NFULA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 },
+ [NFULA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 },
+ [NFULA_HWADDR] = {
+ .minlen = sizeof(struct nfulnl_msg_packet_hw)
+ },
+ //[NFULA_PAYLOAD]
+ [NFULA_PREFIX] = { .type = NLA_STRING, },
+ [NFULA_UID] = { .type = NLA_U32 },
+ [NFULA_SEQ] = { .type = NLA_U32 },
+ [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 },
+};
+
+struct nfnl_log *nfnlmsg_log_parse(struct nlmsghdr *nlh)
+{
+ struct nfnl_log *log;
+ struct nlattr *tb[NFULA_MAX+1];
+ struct nlattr *attr;
+ int err;
+
+ log = nfnl_log_alloc();
+ if (!log)
+ return NULL;
+
+ log->ce_msgtype = nlh->nlmsg_type;
+
+ err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
+ log_policy);
+ if (err < 0)
+ goto errout;
+
+ nfnl_log_set_family(log, nfnlmsg_family(nlh));
+
+ attr = tb[NFULA_PACKET_HDR];
+ if (attr) {
+ struct nfulnl_msg_packet_hdr *hdr = nla_data(attr);
+
+ nfnl_log_set_hwproto(log, hdr->hw_protocol);
+ nfnl_log_set_hook(log, hdr->hook);
+ }
+
+ attr = tb[NFULA_MARK];
+ if (attr)
+ nfnl_log_set_mark(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_TIMESTAMP];
+ if (attr) {
+ struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
+ struct timeval tv;
+
+ tv.tv_sec = ntohll(timestamp->sec);
+ tv.tv_usec = ntohll(timestamp->usec);
+ nfnl_log_set_timestamp(log, &tv);
+ }
+
+ attr = tb[NFULA_IFINDEX_INDEV];
+ if (attr)
+ nfnl_log_set_indev(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_IFINDEX_OUTDEV];
+ if (attr)
+ nfnl_log_set_outdev(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_IFINDEX_PHYSINDEV];
+ if (attr)
+ nfnl_log_set_physindev(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
+ if (attr)
+ nfnl_log_set_physoutdev(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_HWADDR];
+ if (attr) {
+ struct nfulnl_msg_packet_hw *hw = nla_data(attr);
+
+ nfnl_log_set_hwaddr(log, hw->hw_addr, ntohs(hw->hw_addrlen));
+ }
+
+ attr = tb[NFULA_PAYLOAD];
+ if (attr) {
+ err = nfnl_log_set_payload(log, nla_data(attr), nla_len(attr));
+ if (err < 0)
+ goto errout;
+ }
+
+ attr = tb[NFULA_PREFIX];
+ if (attr) {
+ err = nfnl_log_set_prefix(log, nla_data(attr));
+ if (err < 0)
+ goto errout;
+ }
+
+ attr = tb[NFULA_UID];
+ if (attr)
+ nfnl_log_set_uid(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_SEQ];
+ if (attr)
+ nfnl_log_set_seq(log, ntohl(nla_get_u32(attr)));
+
+ attr = tb[NFULA_SEQ_GLOBAL];
+ if (attr)
+ nfnl_log_set_seq_global(log, ntohl(nla_get_u32(attr)));
+
+ return log;
+
+errout:
+ nfnl_log_put(log);
+ return NULL;
+}
+
+static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
+ struct nlmsghdr *nlh, void *arg)
+{
+ struct nl_parser_param *pp = arg;
+ struct nfnl_log *log;
+ int err;
+
+ log = nfnlmsg_log_parse(nlh);
+ if (log == NULL)
+ goto errout_errno;
+
+ err = pp->pp_cb((struct nl_object *) log, pp);
+ if (err < 0)
+ goto errout;
+
+ return P_ACCEPT;
+
+errout_errno:
+ err = nl_get_errno();
+errout:
+ nfnl_log_put(log);
+ return err;
+}
+
+/**
+ * @name Log Commands
+ * @{
+ */
+
+static struct nl_msg *build_log_cmd_msg(uint8_t family, uint16_t queuenum,
+ uint8_t command)
+{
+ struct nl_msg *msg;
+ struct nfulnl_msg_config_cmd cmd;
+
+ msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
+ family, queuenum);
+ if (msg == NULL)
+ return NULL;
+
+ cmd.command = command;
+ if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
+ goto nla_put_failure;
+
+ return msg;
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return NULL;
+}
+
+static int send_log_msg(struct nl_handle *handle, struct nl_msg *msg)
+{
+ int err;
+
+ err = nl_send_auto_complete(handle, msg);
+ nlmsg_free(msg);
+ if (err < 0)
+ return err;
+
+ return nl_wait_for_ack(handle);
+}
+
+struct nl_msg *nfnl_log_build_bind(uint16_t queuenum)
+{
+ return build_log_cmd_msg(0, queuenum, NFULNL_CFG_CMD_BIND);
+}
+
+int nfnl_log_bind(struct nl_handle *nlh, uint16_t queuenum)
+{
+ struct nl_msg *msg;
+
+ msg = nfnl_log_build_bind(queuenum);
+ if (!msg)
+ return nl_get_errno();
+
+ return send_log_msg(nlh, msg);
+}
+
+struct nl_msg *nfnl_log_build_unbind(uint16_t queuenum)
+{
+ return build_log_cmd_msg(0, queuenum, NFULNL_CFG_CMD_UNBIND);
+}
+
+int nfnl_log_unbind(struct nl_handle *nlh, uint16_t queuenum)
+{
+ struct nl_msg *msg;
+
+ msg = nfnl_log_build_bind(queuenum);
+ if (!msg)
+ return nl_get_errno();
+
+ return send_log_msg(nlh, msg);
+}
+
+struct nl_msg *nfnl_log_build_pf_bind(uint8_t pf)
+{
+ return build_log_cmd_msg(pf, 0, NFULNL_CFG_CMD_PF_BIND);
+}
+
+int nfnl_log_pf_bind(struct nl_handle *nlh, uint8_t pf)
+{
+ struct nl_msg *msg;
+
+ msg = nfnl_log_build_pf_bind(pf);
+ if (!msg)
+ return nl_get_errno();
+
+ return send_log_msg(nlh, msg);
+}
+
+struct nl_msg *nfnl_log_build_pf_unbind(uint8_t pf)
+{
+ return build_log_cmd_msg(pf, 0, NFULNL_CFG_CMD_PF_UNBIND);
+}
+
+int nfnl_log_pf_unbind(struct nl_handle *nlh, uint8_t pf)
+{
+ struct nl_msg *msg;
+
+ msg = nfnl_log_build_pf_unbind(pf);
+ if (!msg)
+ return nl_get_errno();
+
+ return send_log_msg(nlh, msg);
+}
+
+struct nl_msg *nfnl_log_build_mode(uint16_t queuenum, uint8_t copy_mode,
+ uint32_t copy_range)
+{
+ struct nl_msg *msg;
+ struct nfulnl_msg_config_mode mode;
+
+ msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
+ 0, queuenum);
+ if (msg == NULL)
+ return NULL;
+
+ mode.copy_mode = copy_mode;
+ mode.copy_range = htonl(copy_range);
+ if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0)
+ goto nla_put_failure;
+
+ return msg;
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return NULL;
+}
+
+int nfnl_log_set_mode(struct nl_handle *nlh, uint16_t queuenum,
+ uint8_t copy_mode, uint32_t copy_range)
+{
+ struct nl_msg *msg;
+
+ msg = nfnl_log_build_mode(queuenum, copy_mode, copy_range);
+ if (!msg)
+ return nl_get_errno();
+ return send_log_msg(nlh, msg);
+}
+
+/** @} */
+
+#define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
+static struct nl_cache_ops nfnl_log_ops = {
+ .co_name = "netfilter/log",
+ .co_hdrsize = NFNL_HDRLEN,
+ .co_msgtypes = {
+ { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" },
+ END_OF_MSGTYPES_LIST,
+ },
+ .co_protocol = NETLINK_NETFILTER,
+ .co_msg_parser = log_msg_parser,
+ .co_obj_ops = &log_obj_ops,
+};
+
+static void __init log_init(void)
+{
+ nl_cache_mngt_register(&nfnl_log_ops);
+}
+
+static void __exit log_exit(void)
+{
+ nl_cache_mngt_unregister(&nfnl_log_ops);
+}
+
+/** @} */
Index: libnl/lib/netfilter/log_obj.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/lib/netfilter/log_obj.c 2007-09-03 14:32:21.000000000 +1000
@@ -0,0 +1,425 @@
+/*
+ * lib/netfilter/log_obj.c Netfilter Log Object
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
+ * Copyright (c) 2007 Secure Computing Corporation
+ */
+
+#include <netlink-local.h>
+#include <netlink/netfilter/nfnl.h>
+#include <netlink/netfilter/log.h>
+
+/** @cond SKIP */
+#define LOG_ATTR_FAMILY (1UL << 0)
+#define LOG_ATTR_HWPROTO (1UL << 1)
+#define LOG_ATTR_HOOK (1UL << 2)
+#define LOG_ATTR_MARK (1UL << 3)
+#define LOG_ATTR_TIMESTAMP (1UL << 4)
+#define LOG_ATTR_INDEV (1UL << 5)
+#define LOG_ATTR_OUTDEV (1UL << 6)
+#define LOG_ATTR_PHYSINDEV (1UL << 7)
+#define LOG_ATTR_PHYSOUTDEV (1UL << 8)
+#define LOG_ATTR_HWADDR (1UL << 9)
+#define LOG_ATTR_PAYLOAD (1UL << 10)
+#define LOG_ATTR_PREFIX (1UL << 11)
+#define LOG_ATTR_UID (1UL << 12)
+#define LOG_ATTR_SEQ (1UL << 13)
+#define LOG_ATTR_SEQ_GLOBAL (1UL << 14)
+/** @endcond */
+
+static void log_free_data(struct nl_object *c)
+{
+ struct nfnl_log *log = (struct nfnl_log *) c;
+
+ if (log == NULL)
+ return;
+
+ free(log->log_payload);
+ free(log->log_prefix);
+}
+
+static int log_clone(struct nl_object *_dst, struct nl_object *_src)
+{
+ struct nfnl_log *dst = (struct nfnl_log *) _dst;
+ struct nfnl_log *src = (struct nfnl_log *) _src;
+ int err;
+
+ if (src->log_payload) {
+ err = nfnl_log_set_payload(dst, src->log_payload,
+ src->log_payload_len);
+ if (err < 0)
+ goto errout;
+ }
+
+ if (src->log_prefix) {
+ err = nfnl_log_set_prefix(dst, src->log_prefix);
+ if (err < 0)
+ goto errout;
+ }
+
+ return 0;
+errout:
+ return err;
+}
+
+static int log_dump(struct nl_object *a, struct nl_dump_params *p)
+{
+ struct nfnl_log *log = (struct nfnl_log *) a;
+ struct nl_cache *link_cache;
+ char buf[64];
+
+ link_cache = nl_cache_mngt_require("route/link");
+
+ if (log->ce_mask & LOG_ATTR_PREFIX)
+ dp_dump(p, "%s", log->log_prefix);
+
+ if (log->ce_mask & LOG_ATTR_INDEV) {
+ if (link_cache)
+ dp_dump(p, "IN=%s ",
+ rtnl_link_i2name(link_cache, log->log_indev,
+ buf, sizeof(buf)));
+ else
+ dp_dump(p, "IN=%d ", log->log_indev);
+ }
+
+ if (log->ce_mask & LOG_ATTR_PHYSINDEV) {
+ if (link_cache)
+ dp_dump(p, "PHYSIN=%s ",
+ rtnl_link_i2name(link_cache, log->log_physindev,
+ buf, sizeof(buf)));
+ else
+ dp_dump(p, "IN=%d ", log->log_physindev);
+ }
+
+ if (log->ce_mask & LOG_ATTR_OUTDEV) {
+ if (link_cache)
+ dp_dump(p, "OUT=%s ",
+ rtnl_link_i2name(link_cache, log->log_outdev,
+ buf, sizeof(buf)));
+ else
+ dp_dump(p, "OUT=%d ", log->log_outdev);
+ }
+
+ if (log->ce_mask & LOG_ATTR_PHYSOUTDEV) {
+ if (link_cache)
+ dp_dump(p, "PHYSOUT=%s ",
+ rtnl_link_i2name(link_cache,log->log_physoutdev,
+ buf, sizeof(buf)));
+ else
+ dp_dump(p, "PHYSOUT=%d ", log->log_physoutdev);
+ }
+
+ if (log->ce_mask & LOG_ATTR_HWADDR) {
+ int i;
+
+ dp_dump(p, "MAC");
+ for (i = 0; i < log->log_hwaddr_len; i++)
+ dp_dump(p, "%c%02x", i?':':'=', log->log_hwaddr[i]);
+ dp_dump(p, " ");
+ }
+
+ /* FIXME: parse the payload to get iptables LOG compatible format */
+
+ if (log->ce_mask & LOG_ATTR_FAMILY)
+ dp_dump(p, "FAMILY=%s ",
+ nl_af2str(log->log_family, buf, sizeof(buf)));
+
+ if (log->ce_mask & LOG_ATTR_HWPROTO)
+ dp_dump(p, "HWPROTO=%s ",
+ nl_ether_proto2str(ntohs(log->log_hwproto),
+ buf, sizeof(buf)));
+
+ if (log->ce_mask & LOG_ATTR_HOOK)
+ dp_dump(p, "HOOK=%d ", log->log_hook);
+
+ if (log->ce_mask & LOG_ATTR_MARK)
+ dp_dump(p, "MARK=%d ", log->log_mark);
+
+ if (log->ce_mask & LOG_ATTR_PAYLOAD)
+ dp_dump(p, "PAYLOADLEN=%d ", log->log_payload_len);
+
+ if (log->ce_mask & LOG_ATTR_SEQ)
+ dp_dump(p, "SEQ=%d ", log->log_seq);
+
+ if (log->ce_mask & LOG_ATTR_SEQ_GLOBAL)
+ dp_dump(p, "SEQGLOBAL=%d ", log->log_seq_global);
+
+ dp_dump(p, "\n");
+
+ return 1;
+}
+
+/**
+ * @name Allocation/Freeing
+ * @{
+ */
+
+struct nfnl_log *nfnl_log_alloc(void)
+{
+ return (struct nfnl_log *) nl_object_alloc(&log_obj_ops);
+}
+
+void nfnl_log_get(struct nfnl_log *log)
+{
+ nl_object_get((struct nl_object *) log);
+}
+
+void nfnl_log_put(struct nfnl_log *log)
+{
+ nl_object_put((struct nl_object *) log);
+}
+
+/** @} */
+
+/**
+ * @name Attributes
+ * @{
+ */
+
+void nfnl_log_set_family(struct nfnl_log *log, uint8_t family)
+{
+ log->log_family = family;
+ log->ce_mask |= LOG_ATTR_FAMILY;
+}
+
+uint8_t nfnl_log_get_family(const struct nfnl_log *log)
+{
+ if (log->ce_mask & LOG_ATTR_FAMILY)
+ return log->log_family;
+ else
+ return AF_UNSPEC;
+}
+
+void nfnl_log_set_hwproto(struct nfnl_log *log, uint16_t hwproto)
+{
+ log->log_hwproto = hwproto;
+ log->ce_mask |= LOG_ATTR_HWPROTO;
+}
+
+int nfnl_log_test_hwproto(const struct nfnl_log *log)
+{
+ return !!(log->ce_mask & LOG_ATTR_HWPROTO);
+}
+
+uint16_t nfnl_log_get_hwproto(const struct nfnl_log *log)
+{
+ return log->log_hwproto;
+}
+
+void nfnl_log_set_hook(struct nfnl_log *log, uint8_t hook)
+{
+ log->log_hook = hook;
+ log->ce_mask |= LOG_ATTR_HOOK;
+}
+
+int nfnl_log_test_hook(const struct nfnl_log *log)
+{
+ return !!(log->ce_mask & LOG_ATTR_HOOK);
+}
+
+uint8_t nfnl_log_get_hook(const struct nfnl_log *log)
+{
+ return log->log_hook;
+}
+
+void nfnl_log_set_mark(struct nfnl_log *log, uint32_t mark)
+{
+ log->log_mark = mark;
+ log->ce_mask |= LOG_ATTR_MARK;
+}
+
+int nfnl_log_test_mark(const struct nfnl_log *log)
+{
+ return !!(log->ce_mask & LOG_ATTR_MARK);
+}
+
+uint32_t nfnl_log_get_mark(const struct nfnl_log *log)
+{
+ return log->log_mark;
+}
+
+void nfnl_log_set_timestamp(struct nfnl_log *log, struct timeval *tv)
+{
+ log->log_timestamp.tv_sec = tv->tv_sec;
+ log->log_timestamp.tv_usec = tv->tv_usec;
+ log->ce_mask |= LOG_ATTR_TIMESTAMP;
+}
+
+const struct timeval *nfnl_log_get_timestamp(const struct nfnl_log *log)
+{
+ if (!(log->ce_mask & LOG_ATTR_TIMESTAMP))
+ return NULL;
+ return &log->log_timestamp;
+}
+
+void nfnl_log_set_indev(struct nfnl_log *log, uint32_t indev)
+{
+ log->log_indev = indev;
+ log->ce_mask |= LOG_ATTR_INDEV;
+}
+
+uint32_t nfnl_log_get_indev(const struct nfnl_log *log)
+{
+ return log->log_indev;
+}
+
+void nfnl_log_set_outdev(struct nfnl_log *log, uint32_t outdev)
+{
+ log->log_outdev = outdev;
+ log->ce_mask |= LOG_ATTR_OUTDEV;
+}
+
+uint32_t nfnl_log_get_outdev(const struct nfnl_log *log)
+{
+ return log->log_outdev;
+}
+
+void nfnl_log_set_physindev(struct nfnl_log *log, uint32_t physindev)
+{
+ log->log_physindev = physindev;
+ log->ce_mask |= LOG_ATTR_PHYSINDEV;
+}
+
+uint32_t nfnl_log_get_physindev(const struct nfnl_log *log)
+{
+ return log->log_physindev;
+}
+
+void nfnl_log_set_physoutdev(struct nfnl_log *log, uint32_t physoutdev)
+{
+ log->log_physoutdev = physoutdev;
+ log->ce_mask |= LOG_ATTR_PHYSOUTDEV;
+}
+
+uint32_t nfnl_log_get_physoutdev(const struct nfnl_log *log)
+{
+ return log->log_physoutdev;
+}
+
+void nfnl_log_set_hwaddr(struct nfnl_log *log, uint8_t *hwaddr, int len)
+{
+ if (len > sizeof(log->log_hwaddr))
+ len = sizeof(log->log_hwaddr);
+ log->log_hwaddr_len = len;
+ memcpy(log->log_hwaddr, hwaddr, len);
+ log->ce_mask |= LOG_ATTR_HWADDR;
+}
+
+const uint8_t *nfnl_log_get_hwaddr(const struct nfnl_log *log, int *len)
+{
+ if (!(log->ce_mask & LOG_ATTR_HWADDR)) {
+ *len = 0;
+ return NULL;
+ }
+
+ *len = log->log_hwaddr_len;
+ return log->log_hwaddr;
+}
+
+int nfnl_log_set_payload(struct nfnl_log *log, uint8_t *payload, int len)
+{
+ free(log->log_payload);
+ log->log_payload = malloc(len);
+ if (!log->log_payload)
+ return nl_errno(ENOMEM);
+
+ memcpy(log->log_payload, payload, len);
+ log->log_payload_len = len;
+ log->ce_mask |= LOG_ATTR_PAYLOAD;
+ return 0;
+}
+
+const void *nfnl_log_get_payload(const struct nfnl_log *log, int *len)
+{
+ if (!(log->ce_mask & LOG_ATTR_PAYLOAD)) {
+ *len = 0;
+ return NULL;
+ }
+
+ *len = log->log_payload_len;
+ return log->log_payload;
+}
+
+int nfnl_log_set_prefix(struct nfnl_log *log, void *prefix)
+{
+ free(log->log_prefix);
+ log->log_prefix = strdup(prefix);
+ if (!log->log_prefix)
+ return nl_errno(ENOMEM);
+
+ log->ce_mask |= LOG_ATTR_PREFIX;
+ return 0;
+}
+
+const char *nfnl_log_get_prefix(const struct nfnl_log *log)
+{
+ return log->log_prefix;
+}
+
+void nfnl_log_set_uid(struct nfnl_log *log, uint32_t uid)
+{
+ log->log_uid = uid;
+ log->ce_mask |= LOG_ATTR_UID;
+}
+
+int nfnl_log_test_uid(const struct nfnl_log *log)
+{
+ return !!(log->ce_mask & LOG_ATTR_UID);
+}
+
+uint32_t nfnl_log_get_uid(const struct nfnl_log *log)
+{
+ return log->log_uid;
+}
+
+void nfnl_log_set_seq(struct nfnl_log *log, uint32_t seq)
+{
+ log->log_seq = seq;
+ log->ce_mask |= LOG_ATTR_SEQ;
+}
+
+int nfnl_log_test_seq(const struct nfnl_log *log)
+{
+ return !!(log->ce_mask & LOG_ATTR_SEQ);
+}
+
+uint32_t nfnl_log_get_seq(const struct nfnl_log *log)
+{
+ return log->log_seq;
+}
+
+void nfnl_log_set_seq_global(struct nfnl_log *log, uint32_t seq_global)
+{
+ log->log_seq_global = seq_global;
+ log->ce_mask |= LOG_ATTR_SEQ_GLOBAL;
+}
+
+int nfnl_log_test_seq_global(const struct nfnl_log *log)
+{
+ return !!(log->ce_mask & LOG_ATTR_SEQ_GLOBAL);
+}
+
+uint32_t nfnl_log_get_seq_global(const struct nfnl_log *log)
+{
+ return log->log_seq_global;
+}
+
+/** @} */
+
+struct nl_object_ops log_obj_ops = {
+ .oo_name = "netfilter/log",
+ .oo_size = sizeof(struct nfnl_log),
+ .oo_free_data = log_free_data,
+ .oo_clone = log_clone,
+ .oo_dump[NL_DUMP_BRIEF] = log_dump,
+ .oo_dump[NL_DUMP_FULL] = log_dump,
+ .oo_dump[NL_DUMP_STATS] = log_dump,
+};
+
+/** @} */
Index: libnl/src/nf-log.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/src/nf-log.c 2007-09-03 14:39:32.000000000 +1000
@@ -0,0 +1,142 @@
+/*
+ * src/nf-log.c Monitor netfilter log events
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
+ * Copyright (c) 2007 Secure Computing Corporation
+ */
+
+#include <sys/types.h>
+#include <linux/netfilter/nfnetlink_log.h>
+
+#include "utils.h"
+#include <netlink/netfilter/nfnl.h>
+#include <netlink/netfilter/log.h>
+
+static void obj_input(struct nl_object *obj, void *arg)
+{
+ struct nl_dump_params dp = {
+ .dp_type = NL_DUMP_STATS,
+ .dp_fd = stdout,
+ .dp_dump_msgtype = 1,
+ };
+
+ nl_object_dump(obj, &dp);
+}
+
+static int event_input(struct nl_msg *msg, void *arg)
+{
+ if (nl_msg_parse(msg, &obj_input, NULL) < 0)
+ fprintf(stderr, "<<EVENT>> Unknown message type\n");
+
+ /* Exit nl_recvmsgs_def() and return to the main select() */
+ return NL_EXIT;
+}
+
+int main(int argc, char *argv[])
+{
+ struct nl_handle *nfnlh;
+ struct nl_handle *rtnlh;
+ struct nl_cache *link_cache;
+ int err = 1;
+ int family, group;
+
+ if (nltool_init(argc, argv) < 0)
+ return -1;
+
+ nfnlh = nltool_alloc_handle();
+ if (nfnlh == NULL)
+ return -1;
+
+ nl_disable_sequence_check(nfnlh);
+
+ nl_socket_modify_cb(nfnlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
+
+ if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
+ printf("Usage: nf-log family group\n");
+ return 2;
+ }
+
+ if (nfnl_connect(nfnlh) < 0) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout;
+ }
+
+ family = nl_str2af(argv[1]);
+ if (family == AF_UNSPEC) {
+ fprintf(stderr, "Unknown family: %s\n", argv[1]);
+ goto errout;
+ }
+ if (nfnl_log_pf_unbind(nfnlh, family) < 0) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout;
+ }
+ if (nfnl_log_pf_bind(nfnlh, family) < 0) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout;
+ }
+
+ group = nl_str2af(argv[2]);
+ if (nfnl_log_bind(nfnlh, group) < 0) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout;
+ }
+
+ if (nfnl_log_set_mode(nfnlh, 0, NFULNL_COPY_PACKET, 0xffff) < 0) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout;
+ }
+
+ rtnlh = nltool_alloc_handle();
+ if (rtnlh == NULL) {
+ goto errout_close;
+ }
+
+ if (nl_connect(rtnlh, NETLINK_ROUTE) < 0) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout;
+ }
+
+ if ((link_cache = rtnl_link_alloc_cache(rtnlh)) == NULL) {
+ fprintf(stderr, "%s\n", nl_geterror());
+ goto errout_close;
+ }
+
+ nl_cache_mngt_provide(link_cache);
+
+ while (1) {
+ fd_set rfds;
+ int nffd, rtfd, maxfd, retval;
+
+ FD_ZERO(&rfds);
+
+ maxfd = nffd = nl_socket_get_fd(nfnlh);
+ FD_SET(nffd, &rfds);
+
+ rtfd = nl_socket_get_fd(rtnlh);
+ FD_SET(rtfd, &rfds);
+ if (maxfd < rtfd)
+ maxfd = rtfd;
+
+ /* wait for an incoming message on the netlink socket */
+ retval = select(maxfd+1, &rfds, NULL, NULL, NULL);
+
+ if (retval) {
+ if (FD_ISSET(nffd, &rfds))
+ nl_recvmsgs_def(nfnlh);
+ if (FD_ISSET(rtfd, &rfds))
+ nl_recvmsgs_def(rtnlh);
+ }
+ }
+
+ nl_close(rtnlh);
+errout_close:
+ nl_close(nfnlh);
+errout:
+ return err;
+}
Index: libnl/include/linux/netfilter/nfnetlink_log.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/include/linux/netfilter/nfnetlink_log.h 2007-09-03 14:32:21.000000000 +1000
@@ -0,0 +1,96 @@
+#ifndef _NFNETLINK_LOG_H
+#define _NFNETLINK_LOG_H
+
+/* This file describes the netlink messages (i.e. 'protocol packets'),
+ * and not any kind of function definitions. It is shared between kernel and
+ * userspace. Don't put kernel specific stuff in here */
+
+#ifndef aligned_be64
+#define aligned_be64 u_int64_t __attribute__((aligned(8)))
+#endif
+
+#include <linux/types.h>
+#include <linux/netfilter/nfnetlink.h>
+
+enum nfulnl_msg_types {
+ NFULNL_MSG_PACKET, /* packet from kernel to userspace */
+ NFULNL_MSG_CONFIG, /* connect to a particular queue */
+
+ NFULNL_MSG_MAX
+};
+
+struct nfulnl_msg_packet_hdr {
+ __be16 hw_protocol; /* hw protocol (network order) */
+ u_int8_t hook; /* netfilter hook */
+ u_int8_t _pad;
+};
+
+struct nfulnl_msg_packet_hw {
+ __be16 hw_addrlen;
+ u_int16_t _pad;
+ u_int8_t hw_addr[8];
+};
+
+struct nfulnl_msg_packet_timestamp {
+ aligned_be64 sec;
+ aligned_be64 usec;
+};
+
+enum nfulnl_attr_type {
+ NFULA_UNSPEC,
+ NFULA_PACKET_HDR,
+ NFULA_MARK, /* u_int32_t nfmark */
+ NFULA_TIMESTAMP, /* nfulnl_msg_packet_timestamp */
+ NFULA_IFINDEX_INDEV, /* u_int32_t ifindex */
+ NFULA_IFINDEX_OUTDEV, /* u_int32_t ifindex */
+ NFULA_IFINDEX_PHYSINDEV, /* u_int32_t ifindex */
+ NFULA_IFINDEX_PHYSOUTDEV, /* u_int32_t ifindex */
+ NFULA_HWADDR, /* nfulnl_msg_packet_hw */
+ NFULA_PAYLOAD, /* opaque data payload */
+ NFULA_PREFIX, /* string prefix */
+ NFULA_UID, /* user id of socket */
+ NFULA_SEQ, /* instance-local sequence number */
+ NFULA_SEQ_GLOBAL, /* global sequence number */
+
+ __NFULA_MAX
+};
+#define NFULA_MAX (__NFULA_MAX - 1)
+
+enum nfulnl_msg_config_cmds {
+ NFULNL_CFG_CMD_NONE,
+ NFULNL_CFG_CMD_BIND,
+ NFULNL_CFG_CMD_UNBIND,
+ NFULNL_CFG_CMD_PF_BIND,
+ NFULNL_CFG_CMD_PF_UNBIND,
+};
+
+struct nfulnl_msg_config_cmd {
+ u_int8_t command; /* nfulnl_msg_config_cmds */
+} __attribute__ ((packed));
+
+struct nfulnl_msg_config_mode {
+ __be32 copy_range;
+ u_int8_t copy_mode;
+ u_int8_t _pad;
+} __attribute__ ((packed));
+
+enum nfulnl_attr_config {
+ NFULA_CFG_UNSPEC,
+ NFULA_CFG_CMD, /* nfulnl_msg_config_cmd */
+ NFULA_CFG_MODE, /* nfulnl_msg_config_mode */
+ NFULA_CFG_NLBUFSIZ, /* u_int32_t buffer size */
+ NFULA_CFG_TIMEOUT, /* u_int32_t in 1/100 s */
+ NFULA_CFG_QTHRESH, /* u_int32_t */
+ NFULA_CFG_FLAGS, /* u_int16_t */
+ __NFULA_CFG_MAX
+};
+#define NFULA_CFG_MAX (__NFULA_CFG_MAX -1)
+
+#define NFULNL_COPY_NONE 0x00
+#define NFULNL_COPY_META 0x01
+#define NFULNL_COPY_PACKET 0x02
+
+#define NFULNL_CFG_F_SEQ 0x0001
+#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
+
+#endif /* _NFNETLINK_LOG_H */
next prev parent reply other threads:[~2007-09-03 5:12 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-03 5:09 netfilter support in libnl Philip Craig
2007-09-03 5:11 ` [PATCH 1/3] libnl: add netfilter support Philip Craig
2007-09-03 9:50 ` Patrick McHardy
2007-09-03 10:01 ` Thomas Graf
2007-09-03 10:06 ` Patrick McHardy
2007-09-03 10:15 ` Thomas Graf
2007-09-03 10:53 ` Patrick McHardy
2007-09-03 11:03 ` Thomas Graf
2007-09-03 11:13 ` Patrick McHardy
2007-09-04 1:18 ` Philip Craig
2007-09-03 10:09 ` Thomas Graf
2007-09-04 2:12 ` Philip Craig
2007-09-04 9:39 ` Thomas Graf
2007-09-04 11:36 ` Thomas Graf
2007-09-03 5:11 ` [PATCH 2/3] libnl: add netfilter conntrack support Philip Craig
2007-09-04 16:45 ` Thomas Graf
2007-09-03 5:12 ` Philip Craig [this message]
2007-09-04 16:48 ` [PATCH 3/3] libnl: add netfilter log support Thomas Graf
2007-09-03 9:30 ` netfilter support in libnl Patrick McHardy
2007-09-03 9:59 ` Thomas Graf
2007-09-03 10:05 ` Patrick McHardy
2007-09-03 10:16 ` Thomas Graf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46DB97C0.3060602@snapgear.com \
--to=philipc@snapgear.com \
--cc=netfilter-devel@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.