[LIBNL 08/09]: Support conntrack add/delete/query requests

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

 



commit 5d2b826674d411f99e571fd35ad5722fed077e5e
Author: Patrick McHardy <kaber@xxxxxxxxx>
Date:   Fri Jan 18 17:53:14 2008 +0100

    [LIBNL]: Support conntrack add/delete/query requests
    
    Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>

diff --git a/include/netlink/netfilter/ct.h b/include/netlink/netfilter/ct.h
index 965b869..f554017 100644
--- a/include/netlink/netfilter/ct.h
+++ b/include/netlink/netfilter/ct.h
@@ -39,6 +39,15 @@ extern void		nfnl_ct_put(struct nfnl_ct *);
 
 extern int		nfnl_ct_dump_request(struct nl_handle *);
 
+extern struct nl_msg *	nfnl_ct_build_add_request(const struct nfnl_ct *, int);
+extern int		nfnl_ct_add(struct nl_handle *, const struct nfnl_ct *, int);
+
+extern struct nl_msg *	nfnl_ct_build_delete_request(const struct nfnl_ct *, int);
+extern int		nfnl_ct_delete(struct nl_handle *, const struct nfnl_ct *, int);
+
+extern struct nl_msg *	nfnl_ct_build_query_request(const struct nfnl_ct *, int);
+extern int		nfnl_ct_query(struct nl_handle *, const struct nfnl_ct *, int);
+
 extern void		nfnl_ct_set_family(struct nfnl_ct *, uint8_t);
 extern uint8_t		nfnl_ct_get_family(const struct nfnl_ct *);
 
diff --git a/lib/netfilter/ct.c b/lib/netfilter/ct.c
index e9df924..e16a606 100644
--- a/lib/netfilter/ct.c
+++ b/lib/netfilter/ct.c
@@ -9,6 +9,7 @@
  * Copyright (c) 2003-2006 Thomas Graf <tgraf@xxxxxxx>
  * Copyright (c) 2007 Philip Craig <philipc@xxxxxxxxxxxx>
  * Copyright (c) 2007 Secure Computing Corporation
+ * Copyright (c= 2008 Patrick McHardy <kaber@xxxxxxxxx>
  */
 
 /**
@@ -388,6 +389,158 @@ static int ct_request_update(struct nl_cache *c, struct nl_handle *h)
 	return nfnl_ct_dump_request(h);
 }
 
+static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
+			       int repl)
+{
+	struct nlattr *tuple, *ip, *proto;
+	struct nl_addr *addr;
+	int family;
+
+	family = nfnl_ct_get_family(ct);
+
+	tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG);
+	if (!tuple)
+		goto nla_put_failure;
+
+	ip = nla_nest_start(msg, CTA_TUPLE_IP);
+	if (!ip)
+		goto nla_put_failure;
+
+	addr = nfnl_ct_get_src(ct, repl);
+	if (addr)
+		NLA_PUT_ADDR(msg,
+			     family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC,
+			     addr);
+
+	addr = nfnl_ct_get_dst(ct, repl);
+	if (addr)
+		NLA_PUT_ADDR(msg,
+			     family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST,
+			     addr);
+
+	nla_nest_end(msg, ip);
+
+	proto = nla_nest_start(msg, CTA_TUPLE_PROTO);
+	if (!proto)
+		goto nla_put_failure;
+
+	if (nfnl_ct_test_proto(ct))
+		NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct));
+
+	if (nfnl_ct_test_src_port(ct, repl))
+		NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT,
+			    nfnl_ct_get_src_port(ct, repl));
+
+	if (nfnl_ct_test_dst_port(ct, repl))
+		NLA_PUT_U16(msg, CTA_PROTO_DST_PORT,
+			    nfnl_ct_get_dst_port(ct, repl));
+
+	if (nfnl_ct_test_icmp_id(ct, repl))
+		NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
+			    nfnl_ct_get_icmp_id(ct, repl));
+
+	if (nfnl_ct_test_icmp_type(ct, repl))
+		NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
+			    nfnl_ct_get_icmp_type(ct, repl));
+
+	if (nfnl_ct_test_icmp_code(ct, repl))
+		NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE,
+			    nfnl_ct_get_icmp_code(ct, repl));
+
+	nla_nest_end(msg, proto);
+
+	nla_nest_end(msg, tuple);
+	return 0;
+
+nla_put_failure:
+	return -1;
+}
+
+static struct nl_msg *nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags)
+{
+	struct nl_msg *msg;
+
+	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags,
+				   nfnl_ct_get_family(ct), 0);
+	if (msg == NULL)
+		return NULL;
+
+	if (nfnl_ct_build_tuple(msg, ct, 0) < 0)
+		goto err_out;
+
+	return msg;
+
+err_out:
+	nlmsg_free(msg);
+	return NULL;
+}
+
+struct nl_msg *nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags)
+{
+	return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags);
+}
+
+int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
+{
+	struct nl_msg *msg;
+	int err;
+
+	msg = nfnl_ct_build_add_request(ct, flags);
+	if (msg == NULL)
+		return nl_errno(ENOMEM);
+
+	err = nl_send_auto_complete(h, msg);
+	nlmsg_free(msg);
+	if (err < 0)
+		return err;
+
+	return nl_wait_for_ack(h);
+}
+
+struct nl_msg *nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags)
+{
+	return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags);
+}
+
+int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
+{
+	struct nl_msg *msg;
+	int err;
+
+	msg = nfnl_ct_build_delete_request(ct, flags);
+	if (msg == NULL)
+		return nl_errno(ENOMEM);
+
+	err = nl_send_auto_complete(h, msg);
+	nlmsg_free(msg);
+	if (err < 0)
+		return err;
+
+	return nl_wait_for_ack(h);
+}
+
+struct nl_msg *nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags)
+{
+	return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags);
+}
+
+int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
+{
+	struct nl_msg *msg;
+	int err;
+
+	msg = nfnl_ct_build_query_request(ct, flags);
+	if (msg == NULL)
+		return nl_errno(ENOMEM);
+
+	err = nl_send_auto_complete(h, msg);
+	nlmsg_free(msg);
+	if (err < 0)
+		return err;
+
+	return nl_wait_for_ack(h);
+}
+
 /**
  * @name Cache Management
  * @{
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux