diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-05-06 13:50:45 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-05-06 13:55:36 +0200 |
commit | 8805831f27bc3ae5ad24cead76275645f106eac9 (patch) | |
tree | b562ae9393649a066f8fb9abba49ba278066259e /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-x | l4_tcp.c | 88 |
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); +} |