summaryrefslogtreecommitdiffstats
path: root/l4_tcp.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 /l4_tcp.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 'l4_tcp.c')
-rwxr-xr-xl4_tcp.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/l4_tcp.c b/l4_tcp.c
new file mode 100755
index 0000000..f27c85d
--- /dev/null
+++ b/l4_tcp.c
@@ -0,0 +1,88 @@
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include "proto.h"
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+
+#define PRINT_CMP(...)
+
+static void l4_tcp_ct_build_tuple(const uint8_t *pkt, struct nf_conntrack *ct)
+{
+ const struct tcphdr *tcph = (const struct tcphdr *)pkt;
+
+ nfct_set_attr_u8(ct, ATTR_ORIG_L4PROTO, IPPROTO_TCP);
+ nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_TCP);
+ nfct_set_attr_u16(ct, ATTR_ORIG_PORT_SRC, tcph->source);
+ nfct_set_attr_u16(ct, ATTR_ORIG_PORT_DST, tcph->dest);
+ nfct_set_attr_u16(ct, ATTR_REPL_PORT_SRC, tcph->dest);
+ nfct_set_attr_u16(ct, ATTR_REPL_PORT_DST, tcph->source);
+}
+
+static int l4_tcp_ct_cmp_tuple_orig(const uint8_t *pkt, struct nf_conntrack *ct)
+{
+ const struct tcphdr *tcph = (const struct tcphdr *)pkt;
+
+ PRINT_CMP("cmp_orig tcph->source: %u == %u\n",
+ tcph->source, nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
+ PRINT_CMP("cmp_orig tcph->dest: %u == %u\n",
+ tcph->dest, nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
+
+ if (tcph->source == nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) &&
+ tcph->dest == nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST))
+ return 1;
+
+ return 0;
+}
+
+static int
+l4_tcp_ct_cmp_tuple_repl(const uint8_t *pkt, struct nf_conntrack *ct)
+{
+ const struct tcphdr *tcph = (const struct tcphdr *)pkt;
+
+ PRINT_CMP("cmp_repl tcph->source: %u == %u\n",
+ tcph->source, nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC));
+ PRINT_CMP("cmp_repl tcph->dest: %u == %u\n",
+ tcph->dest, nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST));
+
+ if (tcph->source == nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC) &&
+ tcph->dest == nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST))
+ return 1;
+
+ return 0;
+}
+
+static int
+l4_tcp_ct_cmp_port(struct nf_conntrack *ct, uint16_t port)
+{
+ PRINT_CMP("cmp_port src: %u == %u\n",
+ port, nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
+ PRINT_CMP("cmp_port dst: %u == %u\n",
+ port, nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
+
+ if (port == nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) ||
+ port == nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST))
+ return 1;
+
+ return 0;
+}
+
+static int l4_tcp_pkt_no_data(const uint8_t *pkt)
+{
+ const struct tcphdr *tcph = (const struct tcphdr *)pkt;
+ return tcph->syn || tcph->fin || tcph->rst || !tcph->psh;
+}
+
+static struct cthelper_proto_l4_helper tcp = {
+ .l4protonum = IPPROTO_TCP,
+ .l4ct_build = l4_tcp_ct_build_tuple,
+ .l4ct_cmp_orig = l4_tcp_ct_cmp_tuple_orig,
+ .l4ct_cmp_repl = l4_tcp_ct_cmp_tuple_repl,
+ .l4ct_cmp_port = l4_tcp_ct_cmp_port,
+ .l4pkt_no_data = l4_tcp_pkt_no_data,
+};
+
+void l4_tcp_init(void)
+{
+ cthelper_proto_l4_helper_register(&tcp);
+}