summaryrefslogtreecommitdiffstats
path: root/l3_ipv4.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-05-06 13:50:45 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-05-06 13:55:36 +0200
commit8805831f27bc3ae5ad24cead76275645f106eac9 (patch)
treeb562ae9393649a066f8fb9abba49ba278066259e /l3_ipv4.c
initial import
This tree contains the tests for conntrackd's user-space helper infrastructure. They use to live in the conntrack-tools tree. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'l3_ipv4.c')
-rwxr-xr-xl3_ipv4.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/l3_ipv4.c b/l3_ipv4.c
new file mode 100755
index 0000000..8edfd2e
--- /dev/null
+++ b/l3_ipv4.c
@@ -0,0 +1,86 @@
+#include <stdlib.h>
+#include <netinet/ip.h>
+#include <linux/if_ether.h>
+
+#include "proto.h"
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+
+#define PRINT_CMP(...)
+
+static void
+l3_ipv4_ct_build_tuple(const uint8_t *pkt, struct nf_conntrack *ct)
+{
+ const struct iphdr *iph = (const struct iphdr *)pkt;
+
+ nfct_set_attr_u16(ct, ATTR_ORIG_L3PROTO, AF_INET);
+ nfct_set_attr_u16(ct, ATTR_REPL_L3PROTO, AF_INET);
+ nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_SRC, iph->saddr);
+ nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_DST, iph->daddr);
+ nfct_set_attr_u32(ct, ATTR_REPL_IPV4_SRC, iph->daddr);
+ nfct_set_attr_u32(ct, ATTR_REPL_IPV4_DST, iph->saddr);
+}
+
+static int
+l3_ipv4_ct_cmp_tuple_orig(const uint8_t *pkt, struct nf_conntrack *ct)
+{
+ const struct iphdr *iph = (const struct iphdr *)pkt;
+
+ PRINT_CMP("cmp_orig iph->saddr: %x == %x\n",
+ iph->saddr, nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC));
+ PRINT_CMP("cmp_orig iph->daddr: %x == %x\n",
+ iph->daddr, nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST));
+
+ if (iph->saddr == nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC) &&
+ iph->daddr == nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST))
+ return 1;
+
+ return 0;
+}
+
+static int
+l3_ipv4_ct_cmp_tuple_repl(const uint8_t *pkt, struct nf_conntrack *ct)
+{
+ const struct iphdr *iph = (const struct iphdr *)pkt;
+
+ PRINT_CMP("cmp_repl iph->saddr: %x == %x\n",
+ iph->saddr, nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC));
+ PRINT_CMP("cmp_repl iph->daddr: %x == %x\n",
+ iph->daddr, nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST));
+
+ if (iph->saddr == nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC) &&
+ iph->daddr == nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST))
+ return 1;
+
+ return 0;
+}
+
+static int l3_ipv4_pkt_l4proto_num(const uint8_t *pkt)
+{
+ const struct iphdr *iph = (const struct iphdr *)pkt;
+
+ return iph->protocol;
+}
+
+static int l3_ipv4_pkt_l3hdr_len(const uint8_t *pkt)
+{
+ const struct iphdr *iph = (const struct iphdr *)pkt;
+
+ return iph->ihl << 2;
+}
+
+static struct cthelper_proto_l2l3_helper ipv4 = {
+ .l2protonum = ETH_P_IP,
+ .l3protonum = AF_INET,
+ .l2hdr_len = ETH_HLEN,
+ .l3ct_build = l3_ipv4_ct_build_tuple,
+ .l3ct_cmp_orig = l3_ipv4_ct_cmp_tuple_orig,
+ .l3ct_cmp_repl = l3_ipv4_ct_cmp_tuple_repl,
+ .l3pkt_hdr_len = l3_ipv4_pkt_l3hdr_len,
+ .l4pkt_proto = l3_ipv4_pkt_l4proto_num,
+};
+
+void l2l3_ipv4_init(void)
+{
+ cthelper_proto_l2l3_helper_register(&ipv4);
+}