[PATCH libnetfilter_queue 01/32] src: Convert nfq_open() to use libmnl

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add copies of nfnl_handle, nfnl_subsys_handle & mnl_socket to
libnetfilter_queue.c. After calling mnl_socket_open() & mnl_socket_bind(),
it fills in the libnfnetlink structs as if nfnl_open() had been called.
The rest of the system still uses libnfnetlink functions but they keep
working.
Where possible, code is copied exactly from libnfnetlink. checkpatch
warns about space before tabs but these warnings are addressed in a
later commit.

Signed-off-by: Duncan Roe <duncan_roe@xxxxxxxxxxxxxxx>
---
 doxygen/doxygen.cfg.in   |  3 ++
 src/libnetfilter_queue.c | 88 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/doxygen/doxygen.cfg.in b/doxygen/doxygen.cfg.in
index 97174ff..6dd7017 100644
--- a/doxygen/doxygen.cfg.in
+++ b/doxygen/doxygen.cfg.in
@@ -13,6 +13,9 @@ EXCLUDE_SYMBOLS        = EXPORT_SYMBOL \
                          nfq_handle \
                          nfq_data \
                          nfq_q_handle \
+                         nfnl_handle \
+                         nfnl_subsys_handle \
+                         mnl_socket \
                          tcp_flag_word
 EXAMPLE_PATTERNS       =
 INPUT_FILTER           = "sed 's/EXPORT_SYMBOL//g'"
diff --git a/src/libnetfilter_queue.c b/src/libnetfilter_queue.c
index bf67a19..2aba68d 100644
--- a/src/libnetfilter_queue.c
+++ b/src/libnetfilter_queue.c
@@ -31,6 +31,7 @@
 #include <sys/socket.h>
 #include <linux/netfilter/nfnetlink_queue.h>
 
+#include <libmnl/libmnl.h>
 #include <libnfnetlink/libnfnetlink.h>
 #include <libnetfilter_queue/libnetfilter_queue.h>
 #include "internal.h"
@@ -134,11 +135,43 @@ gcc -g3 -ggdb -Wall -lmnl -lnetfilter_queue -o nf-queue nf-queue.c
  * burst
  */
 
+/* Copy of private libnfnetlink structures */
+
+#define NFNL_MAX_SUBSYS 16
+
+struct nfnl_subsys_handle {
+	struct nfnl_handle 	*nfnlh;
+	uint32_t		subscriptions;
+	uint8_t			subsys_id;
+	uint8_t			cb_count;
+	struct nfnl_callback 	*cb;	/* array of callbacks */
+};
+
+struct nfnl_handle {
+	int			fd;
+	struct sockaddr_nl	local;
+	struct sockaddr_nl	peer;
+	uint32_t		subscriptions;
+	uint32_t		seq;
+	uint32_t		dump;
+	uint32_t		rcv_buffer_size;	/* for nfnl_catch */
+	uint32_t		flags;
+	struct nlmsghdr 	*last_nlhdr;
+	struct nfnl_subsys_handle subsys[NFNL_MAX_SUBSYS+1];
+};
+
+/* Copy of private libmnl structure */
+struct mnl_socket {
+	int 			fd;
+	struct sockaddr_nl	addr;
+};
+
 struct nfq_handle
 {
 	struct nfnl_handle *nfnlh;
 	struct nfnl_subsys_handle *nfnlssh;
 	struct nfq_q_handle *qh_list;
+	struct mnl_socket *nl;
 };
 
 struct nfq_q_handle
@@ -383,20 +416,57 @@ int nfq_fd(struct nfq_handle *h)
 EXPORT_SYMBOL
 struct nfq_handle *nfq_open(void)
 {
-	struct nfnl_handle *nfnlh = nfnl_open();
-	struct nfq_handle *qh;
+	struct nfnl_callback pkt_cb = {
+		.call		= __nfq_rcv_pkt,
+		.attr_count	= NFQA_MAX,
+	};
+	struct nfq_handle *h = malloc(sizeof(*h));
 
-	if (!nfnlh)
+	if (!h)
 		return NULL;
+	memset(h, 0, sizeof(*h));
 
-	/* unset netlink sequence tracking by default */
-	nfnl_unset_sequence_tracking(nfnlh);
+	h->nfnlh = malloc(sizeof(*h->nfnlh));
+	if (!h->nfnlh)
+		goto err_free;
+	memset(h->nfnlh, 0, sizeof(*h->nfnlh));
+
+	h->nl = mnl_socket_open(NETLINK_NETFILTER);
+	if (!h->nl)
+		goto err_free2;
+
+	if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0)
+		goto err_close;
+
+	/* Fill in nfnl handle */
+	h->nfnlh->fd = h->nl->fd;
+	h->nfnlh->local = h->nl->addr;
+	h->nfnlh->peer.nl_family = AF_NETLINK;
+	//h->nfnlh->seq = time(NULL);
+	h->nfnlh->rcv_buffer_size = NFNL_BUFFSIZE;
+
+	/* Fill in nfnl subsys handle with code adapted from libnfnetlink */
+	h->nfnlssh = &h->nfnlh->subsys[NFNL_SUBSYS_QUEUE];
+	h->nfnlssh->cb = calloc(NFQNL_MSG_MAX, sizeof(*(h->nfnlssh->cb)));
+	if (!h->nfnlssh->cb)
+		goto err_close;
+
+	h->nfnlssh->nfnlh = h->nfnlh;
+	h->nfnlssh->cb_count = NFQNL_MSG_MAX;
+	h->nfnlssh->subscriptions = 0;
+	h->nfnlssh->subsys_id = NFNL_SUBSYS_QUEUE;
+	pkt_cb.data = h;
+	memcpy(&h->nfnlssh->cb[NFQNL_MSG_PACKET], &pkt_cb, sizeof(pkt_cb));
 
-	qh = nfq_open_nfnl(nfnlh);
-	if (!qh)
-		nfnl_close(nfnlh);
+	return h;
 
-	return qh;
+err_close:
+	mnl_socket_close(h->nl);
+err_free2:
+	free(h->nfnlh);
+err_free:
+	free(h);
+	return NULL;
 }
 
 /**
-- 
2.35.8





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux