From: Philip Craig <philipc@snapgear.com>
To: Netfilter Developer Mailing List <netfilter-devel@lists.netfilter.org>
Subject: [PATCH 1/3] libnl: add netfilter support
Date: Mon, 03 Sep 2007 15:11:18 +1000 [thread overview]
Message-ID: <46DB9776.8020209@snapgear.com> (raw)
In-Reply-To: <46DB9716.1020400@snapgear.com>
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: nfnl.patch --]
[-- Type: text/x-diff, Size: 13989 bytes --]
---
include/linux/netfilter/nfnetlink.h | 106 +++++++++++++++
include/netlink/netfilter/nfnl.h | 44 ++++++
include/netlink/netlink.h | 1
lib/Makefile | 2
lib/attr.c | 3
lib/netfilter/nfnl.c | 246 ++++++++++++++++++++++++++++++++++++
6 files changed, 401 insertions(+), 1 deletion(-)
Index: libnl/lib/Makefile
===================================================================
--- libnl.orig/lib/Makefile 2007-09-03 14:24:29.000000000 +1000
+++ libnl/lib/Makefile 2007-09-03 14:24:45.000000000 +1000
@@ -25,6 +25,8 @@ CIN += $(wildcard route/cls/*.c)
CIN += $(wildcard genl/*.c)
# fib lookup
CIN += $(wildcard fib_lookup/*.c)
+# Netfilter
+CIN += $(wildcard netfilter/*.c)
DEPS := $(CIN:%.c=%.d)
OBJ := $(CIN:%.c=%.o)
Index: libnl/lib/attr.c
===================================================================
--- libnl.orig/lib/attr.c 2007-09-03 14:24:29.000000000 +1000
+++ libnl/lib/attr.c 2007-09-03 14:24:45.000000000 +1000
@@ -261,7 +261,8 @@ int nla_parse(struct nlattr *tb[], int m
memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
nla_for_each_attr(nla, head, len, rem) {
- uint16_t type = nla->nla_type;
+ /* Ignore NFNL_NFA_NEST bit, hope nothing else uses it */
+ uint16_t type = nla->nla_type & 0x7fff;
if (type == 0) {
fprintf(stderr, "Illegal nla->nla_type == 0\n");
Index: libnl/include/netlink/netfilter/nfnl.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/include/netlink/netfilter/nfnl.h 2007-09-03 14:24:45.000000000 +1000
@@ -0,0 +1,44 @@
+/*
+ * netlink/nfnl/nfnl.h Netfilter Netlink
+ *
+ * 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_NFNL_H_
+#define NETLINK_NFNL_H_
+
+#include <netlink/netlink.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NFNL_HDRLEN NLMSG_ALIGN(sizeof(struct nfgenmsg))
+#define NFNLMSG_TYPE(subsys, subtype) (((subsys) << 8) | (subtype))
+
+extern int nfnl_connect(struct nl_handle *);
+
+extern uint8_t nfnlmsg_subsys(struct nlmsghdr *);
+extern uint8_t nfnlmsg_subtype(struct nlmsghdr *);
+extern uint8_t nfnlmsg_family(struct nlmsghdr *);
+extern uint16_t nfnlmsg_res_id(struct nlmsghdr *);
+
+extern int nfnl_send_simple(struct nl_handle *, uint8_t, uint8_t,
+ int, uint8_t, uint16_t);
+extern struct nl_msg * nfnlmsg_alloc_simple(uint8_t, uint8_t, int,
+ uint8_t, uint16_t);
+extern int nfnlmsg_put(struct nl_msg *, uint32_t, uint32_t,
+ uint8_t, uint8_t, int, uint8_t, uint16_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: libnl/lib/netfilter/nfnl.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/lib/netfilter/nfnl.c 2007-09-03 14:24:45.000000000 +1000
@@ -0,0 +1,246 @@
+/*
+ * lib/netfilter/nfnl.c Netfilter Netlink
+ *
+ * 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 nlfam
+ * @defgroup nfnl Netfilter Netlink
+ *
+ * @par Message Format
+ * @code
+ * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
+ * +----------------------------+- - -+- - - - - - - - - - -+- - -+
+ * | Header | Pad | Payload | Pad |
+ * | struct nlmsghdr | | | |
+ * +----------------------------+- - -+- - - - - - - - - - -+- - -+
+ * @endcode
+ * @code
+ * <-------- NFNL_HDRLEN --------->
+ * +--------------------------+- - -+------------+
+ * | Netfilter Netlink Header | Pad | Attributes |
+ * | struct nfgenmsg | | |
+ * +--------------------------+- - -+------------+
+ * nfnlmsg_attrdata(nfg, hdrlen)-----^
+ * @endcode
+ *
+ * @par 1) Creating a new netfilter netlink message
+ * @code
+ * struct nl_msg *msg;
+ *
+ * // Create a new empty netlink message
+ * msg = nlmsg_alloc();
+ *
+ * // Append the netlink and netfilter netlink message header
+ * hdr = nfnlmsg_put(msg, PID, SEQ, SUBSYS, TYPE, NLM_F_ECHO,
+ * FAMILY, RES_ID);
+ *
+ * // Append the attributes.
+ * nla_put_u32(msg, 1, 0x10);
+ *
+ * // Message is ready to be sent.
+ * nl_send_auto_complete(nl_handle, msg);
+ *
+ * // All done? Free the message.
+ * nlmsg_free(msg);
+ * @endcode
+ *
+ * @par 2) Sending of trivial messages
+ * @code
+ * // For trivial messages not requiring any subsys specific header or
+ * // attributes, nfnl_send_simple() may be used to send messages directly.
+ * nfnl_send_simple(nl_handle, SUBSYS, TYPE, 0, FAMILY, RES_ID);
+ * @endcode
+ * @{
+ */
+
+#include <netlink-local.h>
+#include <netlink/netlink.h>
+#include <netlink/netfilter/nfnl.h>
+
+/**
+ * @name Socket Creating
+ * @{
+ */
+
+/**
+ * Create and connect netfilter netlink socket.
+ * @arg handle Netlink handle.
+ *
+ * Creates a NETLINK_NETFILTER netlink socket, binds the socket and
+ * issues a connection attempt.
+ *
+ * @see nl_connect()
+ *
+ * @return 0 on success or a negative error code.
+ */
+int nfnl_connect(struct nl_handle *handle)
+{
+ return nl_connect(handle, NETLINK_NETFILTER);
+}
+
+/** @} */
+
+/**
+ * @name Sending
+ * @{
+ */
+
+/**
+ * Send trivial netfilter netlink message
+ * @arg handle Netlink handle.
+ * @arg subsys_id nfnetlink subsystem
+ * @arg type nfnetlink message type
+ * @arg flags message flags
+ * @arg family nfnetlink address family
+ * @arg res_id nfnetlink resource id
+ *
+ * @return Newly allocated netlink message or NULL.
+ */
+int nfnl_send_simple(struct nl_handle *handle, uint8_t subsys_id, uint8_t type,
+ int flags, uint8_t family, uint16_t res_id)
+{
+ struct nfgenmsg hdr = {
+ .nfgen_family = family,
+ .version = NFNETLINK_V0,
+ .res_id = htons(res_id),
+ };
+
+ return nl_send_simple(handle, NFNLMSG_TYPE(subsys_id, type), flags,
+ &hdr, sizeof(hdr));
+}
+
+/** @} */
+
+/**
+ * @name Message Parsing
+ * @{
+ */
+
+/**
+ * Get netfilter subsystem id from message
+ * @arg nlh netlink messsage header
+ */
+uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh)
+{
+ return NFNL_SUBSYS_ID(nlh->nlmsg_type);
+}
+
+/**
+ * Get netfilter message type from message
+ * @arg nlh netlink messsage header
+ */
+uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh)
+{
+ return NFNL_MSG_TYPE(nlh->nlmsg_type);
+}
+
+/**
+ * Get netfilter family from message
+ * @arg nlh netlink messsage header
+ */
+uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
+{
+ struct nfgenmsg *nfg = nlmsg_data(nlh);
+
+ return nfg->nfgen_family;
+}
+
+/**
+ * Get netfilter resource id from message
+ * @arg nlh netlink messsage header
+ */
+uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh)
+{
+ struct nfgenmsg *nfg = nlmsg_data(nlh);
+
+ return ntohs(nfg->res_id);
+}
+
+/** @} */
+
+/**
+ * @name Message Building
+ * @{
+ */
+
+static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id)
+{
+ struct nfgenmsg *nfg;
+
+ nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO);
+ if (nfg == NULL)
+ return nl_errno(ENOMEM);
+
+ nfg->nfgen_family = family;
+ nfg->version = NFNETLINK_V0;
+ nfg->res_id = htons(res_id);
+ NL_DBG(2, "msg %p: Added nfnetlink header family=%d res_id=%d\n",
+ msg, family, res_id);
+ return 0;
+}
+
+/**
+ * Allocate a new netfilter netlink message
+ * @arg subsys_id nfnetlink subsystem
+ * @arg type nfnetlink message type
+ * @arg flags message flags
+ * @arg family nfnetlink address family
+ * @arg res_id nfnetlink resource id
+ *
+ * @return Newly allocated netlink message or NULL.
+ */
+struct nl_msg *nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags,
+ uint8_t family, uint16_t res_id)
+{
+ struct nl_msg *msg;
+
+ msg = nlmsg_alloc_simple(NFNLMSG_TYPE(subsys_id, type), flags);
+ if (msg == NULL)
+ return NULL;
+
+ if (nfnlmsg_append(msg, family, res_id) < 0)
+ goto nla_put_failure;
+
+ return msg;
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return NULL;
+}
+
+/**
+ * Add netlink and netfilter netlink headers to netlink message
+ * @arg msg netlink message
+ * @arg pid netlink process id
+ * @arg seq sequence number of message
+ * @arg subsys_id nfnetlink subsystem
+ * @arg type nfnetlink message type
+ * @arg flags message flags
+ * @arg family nfnetlink address family
+ * @arg res_id nfnetlink resource id
+ */
+int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq,
+ uint8_t subsys_id, uint8_t type, int flags, uint8_t family,
+ uint16_t res_id)
+{
+ struct nlmsghdr *nlh;
+
+ nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags);
+ if (nlh == NULL)
+ return nl_get_errno();
+
+ return nfnlmsg_append(msg, family, res_id);
+}
+
+/** @} */
+
+/** @} */
Index: libnl/include/netlink/netlink.h
===================================================================
--- libnl.orig/include/netlink/netlink.h 2007-09-03 14:24:29.000000000 +1000
+++ libnl/include/netlink/netlink.h 2007-09-03 14:24:45.000000000 +1000
@@ -25,6 +25,7 @@
#include <linux/rtnetlink.h>
#include <linux/genetlink.h>
#include <linux/ip_mp_alg.h>
+#include <linux/netfilter/nfnetlink.h>
#include <netlink/types.h>
#include <netlink/handlers.h>
#include <netlink/socket.h>
Index: libnl/include/linux/netfilter/nfnetlink.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libnl/include/linux/netfilter/nfnetlink.h 2007-09-03 14:24:45.000000000 +1000
@@ -0,0 +1,106 @@
+#ifndef _NFNETLINK_H
+#define _NFNETLINK_H
+#include <linux/types.h>
+
+#ifndef __KERNEL__
+/* nfnetlink groups: Up to 32 maximum - backwards compatibility for userspace */
+#define NF_NETLINK_CONNTRACK_NEW 0x00000001
+#define NF_NETLINK_CONNTRACK_UPDATE 0x00000002
+#define NF_NETLINK_CONNTRACK_DESTROY 0x00000004
+#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
+#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
+#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
+#endif
+
+enum nfnetlink_groups {
+ NFNLGRP_NONE,
+#define NFNLGRP_NONE NFNLGRP_NONE
+ NFNLGRP_CONNTRACK_NEW,
+#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
+ NFNLGRP_CONNTRACK_UPDATE,
+#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
+ NFNLGRP_CONNTRACK_DESTROY,
+#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
+ NFNLGRP_CONNTRACK_EXP_NEW,
+#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
+ NFNLGRP_CONNTRACK_EXP_UPDATE,
+#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
+ NFNLGRP_CONNTRACK_EXP_DESTROY,
+#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
+ __NFNLGRP_MAX,
+};
+#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
+
+/* Generic structure for encapsulation optional netfilter information.
+ * It is reminiscent of sockaddr, but with sa_family replaced
+ * with attribute type.
+ * ! This should someday be put somewhere generic as now rtnetlink and
+ * ! nfnetlink use the same attributes methods. - J. Schulist.
+ */
+
+struct nfattr
+{
+ u_int16_t nfa_len;
+ u_int16_t nfa_type; /* we use 15 bits for the type, and the highest
+ * bit to indicate whether the payload is nested */
+};
+
+/* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from
+ * rtnetlink.h, it's time to put this in a generic file */
+
+#define NFNL_NFA_NEST 0x8000
+#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff)
+
+#define NFA_ALIGNTO 4
+#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
+#define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \
+ && (nfa)->nfa_len <= (len))
+#define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len), \
+ (struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len)))
+#define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len))
+#define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len))
+#define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0)))
+#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
+#define NFA_NEST(skb, type) \
+({ struct nfattr *__start = (struct nfattr *)skb_tail_pointer(skb); \
+ NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \
+ __start; })
+#define NFA_NEST_END(skb, start) \
+({ (start)->nfa_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+ (skb)->len; })
+#define NFA_NEST_CANCEL(skb, start) \
+({ if (start) \
+ skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
+ -1; })
+
+/* General form of address family dependent message.
+ */
+struct nfgenmsg {
+ u_int8_t nfgen_family; /* AF_xxx */
+ u_int8_t version; /* nfnetlink version */
+ __be16 res_id; /* resource id */
+};
+
+#define NFNETLINK_V0 0
+
+#define NFM_NFA(n) ((struct nfattr *)(((char *)(n)) \
+ + NLMSG_ALIGN(sizeof(struct nfgenmsg))))
+#define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg))
+
+/* netfilter netlink message types are split in two pieces:
+ * 8 bit subsystem, 8bit operation.
+ */
+
+#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
+#define NFNL_MSG_TYPE(x) (x & 0x00ff)
+
+/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
+ * won't work anymore */
+#define NFNL_SUBSYS_NONE 0
+#define NFNL_SUBSYS_CTNETLINK 1
+#define NFNL_SUBSYS_CTNETLINK_EXP 2
+#define NFNL_SUBSYS_QUEUE 3
+#define NFNL_SUBSYS_ULOG 4
+#define NFNL_SUBSYS_COUNT 5
+
+#endif /* _NFNETLINK_H */
next prev parent reply other threads:[~2007-09-03 5:11 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 ` Philip Craig [this message]
2007-09-03 9:50 ` [PATCH 1/3] libnl: add netfilter support 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 ` [PATCH 3/3] libnl: add netfilter log support Philip Craig
2007-09-04 16:48 ` 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=46DB9776.8020209@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 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).