From d11218815f421e392482b4e95135110bbbc4b274 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 8 Jul 2012 20:50:54 +0200 Subject: [PATCH 01/11] TARPIT: mark oldtcphdr const --- extensions/xt_TARPIT.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index db24f90..2c8dc61 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -54,7 +54,8 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, unsigned int mode) { - struct tcphdr _otcph, *oth, *tcph; + struct tcphdr _otcph, *tcph; + const struct tcphdr *oth; unsigned int addr_type = RTN_UNSPEC; struct sk_buff *nskb; const struct iphdr *oldhdr; From cbe58f55d0346f3068d7750cebb27191aaba429b Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Sun, 8 Jul 2012 11:11:20 -0700 Subject: [PATCH 02/11] TARPIT: move XTTARPIT_TARPIT mode processing to its own function Moves the XTTARPIT_TARPIT mode processing to its own function. Signed-off-by: Josh Hunt --- extensions/xt_TARPIT.c | 48 ++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index 2c8dc61..0e2a116 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -51,6 +51,33 @@ #include "compat_xtables.h" #include "xt_TARPIT.h" +static bool xttarpit_tarpit(struct tcphdr *tcph, const struct tcphdr *oth) +{ + /* No replies for RST, FIN or !SYN,!ACK */ + if (oth->rst || oth->fin || (!oth->syn && !oth->ack)) + return false; + tcph->seq = oth->ack ? oth->ack_seq : 0; + + /* Our SYN-ACKs must have a >0 window */ + tcph->window = (oth->syn && !oth->ack) ? htons(5) : 0; + if (oth->syn && oth->ack) { + tcph->rst = true; + tcph->ack_seq = false; + } else { + tcph->syn = oth->syn; + tcph->ack = true; + tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn); + } +#if 0 + /* Rate-limit replies to !SYN,ACKs */ + if (!oth->syn && oth->ack) + if (!xrlim_allow(rt_dst(ort), HZ)) + return false; +#endif + + return true; +} + static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, unsigned int mode) { @@ -118,27 +145,8 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, ((u_int8_t *)tcph)[13] = 0; if (mode == XTTARPIT_TARPIT) { - /* No replies for RST, FIN or !SYN,!ACK */ - if (oth->rst || oth->fin || (!oth->syn && !oth->ack)) + if (!xttarpit_tarpit(tcph, oth)) return; - tcph->seq = oth->ack ? oth->ack_seq : 0; - - /* Our SYN-ACKs must have a >0 window */ - tcph->window = (oth->syn && !oth->ack) ? htons(5) : 0; - if (oth->syn && oth->ack) { - tcph->rst = true; - tcph->ack_seq = false; - } else { - tcph->syn = oth->syn; - tcph->ack = true; - tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn); - } -#if 0 - /* Rate-limit replies to !SYN,ACKs */ - if (!oth->syn && oth->ack) - if (!xrlim_allow(rt_dst(ort), HZ)) - return; -#endif } else if (mode == XTTARPIT_HONEYPOT) { /* Do not answer any resets regardless of combination */ if (oth->rst || oth->seq == 0xDEADBEEF) From a9f383daf8a06d6249e11f311428debe9a961eea Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Sun, 8 Jul 2012 11:11:21 -0700 Subject: [PATCH 03/11] TARPIT: move XTTARPIT_HONEYPOT mode into its own function Moves XTTARPIT_HONEYPOT into its own function. Signed-off-by: Josh Hunt --- extensions/xt_TARPIT.c | 101 ++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index 0e2a116..93e5540 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -78,6 +78,60 @@ static bool xttarpit_tarpit(struct tcphdr *tcph, const struct tcphdr *oth) return true; } +static bool xttarpit_honeypot(struct tcphdr *tcph, const struct tcphdr *oth, + uint16_t payload) +{ + /* Do not answer any resets regardless of combination */ + if (oth->rst || oth->seq == 0xDEADBEEF) + return false; + /* Send a reset to scanners. They like that. */ + if (oth->syn && oth->ack) { + tcph->window = 0; + tcph->ack = false; + tcph->psh = true; + tcph->ack_seq = 0xdeadbeef; /* see if they ack it */ + tcph->seq = oth->ack_seq; + tcph->rst = true; + } + + /* SYN > SYN-ACK */ + if (oth->syn && !oth->ack) { + tcph->syn = true; + tcph->ack = true; + tcph->window = oth->window & + ((net_random() & 0x1f) - 0xf); + tcph->seq = htonl(net_random() & ~oth->seq); + tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn); + } + + /* ACK > ACK */ + if (oth->ack && (!(oth->fin || oth->syn))) { + tcph->syn = false; + tcph->ack = true; + tcph->window = oth->window & + ((net_random() & 0x1f) - 0xf); + tcph->ack_seq = payload > 100 ? + htonl(ntohl(oth->seq) + payload) : + oth->seq; + tcph->seq = oth->ack_seq; + } + + /* + * FIN > RST. + * We cannot terminate gracefully so just be abrupt. + */ + if (oth->fin) { + tcph->window = 0; + tcph->seq = oth->ack_seq; + tcph->ack_seq = oth->ack_seq; + tcph->fin = false; + tcph->ack = false; + tcph->rst = true; + } + + return true; +} + static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, unsigned int mode) { @@ -148,53 +202,8 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, if (!xttarpit_tarpit(tcph, oth)) return; } else if (mode == XTTARPIT_HONEYPOT) { - /* Do not answer any resets regardless of combination */ - if (oth->rst || oth->seq == 0xDEADBEEF) + if (!xttarpit_honeypot(tcph, oth, payload)) return; - /* Send a reset to scanners. They like that. */ - if (oth->syn && oth->ack) { - tcph->window = 0; - tcph->ack = false; - tcph->psh = true; - tcph->ack_seq = 0xdeadbeef; /* see if they ack it */ - tcph->seq = oth->ack_seq; - tcph->rst = true; - } - - /* SYN > SYN-ACK */ - if (oth->syn && !oth->ack) { - tcph->syn = true; - tcph->ack = true; - tcph->window = oth->window & - ((net_random() & 0x1f) - 0xf); - tcph->seq = htonl(net_random() & ~oth->seq); - tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn); - } - - /* ACK > ACK */ - if (oth->ack && (!(oth->fin || oth->syn))) { - tcph->syn = false; - tcph->ack = true; - tcph->window = oth->window & - ((net_random() & 0x1f) - 0xf); - tcph->ack_seq = payload > 100 ? - htonl(ntohl(oth->seq) + payload) : - oth->seq; - tcph->seq = oth->ack_seq; - } - - /* - * FIN > RST. - * We cannot terminate gracefully so just be abrupt. - */ - if (oth->fin) { - tcph->window = 0; - tcph->seq = oth->ack_seq; - tcph->ack_seq = oth->ack_seq; - tcph->fin = false; - tcph->ack = false; - tcph->rst = true; - } } else if (mode == XTTARPIT_RESET) { tcph->window = 0; tcph->ack = false; From 48fbc6783e1d6da18fb376333229f1052215471e Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Sun, 8 Jul 2012 11:11:22 -0700 Subject: [PATCH 04/11] TARPIT: move XTTARPIT_RESET to its own function Moves XTTARPIT_RESET into its own function. Signed-off-by: Josh Hunt --- extensions/xt_TARPIT.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index 93e5540..2499af2 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -132,6 +132,16 @@ static bool xttarpit_honeypot(struct tcphdr *tcph, const struct tcphdr *oth, return true; } +static void xttarpit_reset(struct tcphdr *tcph, const struct tcphdr *oth) +{ + tcph->window = 0; + tcph->ack = false; + tcph->syn = false; + tcph->rst = true; + tcph->seq = oth->ack_seq; + tcph->ack_seq = oth->seq; +} + static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, unsigned int mode) { @@ -205,12 +215,7 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, if (!xttarpit_honeypot(tcph, oth, payload)) return; } else if (mode == XTTARPIT_RESET) { - tcph->window = 0; - tcph->ack = false; - tcph->syn = false; - tcph->rst = true; - tcph->seq = oth->ack_seq; - tcph->ack_seq = oth->seq; + xttarpit_reset(tcph, oth); } /* Adjust TCP checksum */ From 4eb97c7a01046c705841d36785d394164f212615 Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Sun, 8 Jul 2012 11:11:23 -0700 Subject: [PATCH 05/11] TARPIT: make tarpit code generic Creates a generic function to perform the tcp header manipulation in. Done in preparation for IPv6 support. This allows us to share code between v4 and v6 processing. Signed-off-by: Josh Hunt --- extensions/xt_TARPIT.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index 2499af2..3b497aa 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -142,6 +142,26 @@ static void xttarpit_reset(struct tcphdr *tcph, const struct tcphdr *oth) tcph->ack_seq = oth->seq; } +static bool tarpit_generic(struct tcphdr *tcph, const struct tcphdr *oth, + uint16_t payload, unsigned int mode) +{ + switch(mode) { + case XTTARPIT_TARPIT: + if (!xttarpit_tarpit(tcph, oth)) + return false; + break; + case XTTARPIT_HONEYPOT: + if (!xttarpit_honeypot(tcph, oth, payload)) + return false; + break; + case XTTARPIT_RESET: + xttarpit_reset(tcph, oth); + break; + } + + return true; +} + static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, unsigned int mode) { @@ -208,15 +228,8 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, /* Reset flags */ ((u_int8_t *)tcph)[13] = 0; - if (mode == XTTARPIT_TARPIT) { - if (!xttarpit_tarpit(tcph, oth)) - return; - } else if (mode == XTTARPIT_HONEYPOT) { - if (!xttarpit_honeypot(tcph, oth, payload)) - return; - } else if (mode == XTTARPIT_RESET) { - xttarpit_reset(tcph, oth); - } + if (!tarpit_generic(tcph, oth, payload, mode)) + return; /* Adjust TCP checksum */ tcph->check = 0; From 7cd01e0b1487a88bd41fb5affa5fceecfd3ffc7c Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Sun, 8 Jul 2012 11:11:24 -0700 Subject: [PATCH 06/11] TARPIT: add IPv6 support This adds IPv6 support for the tarpit target. It performs the same functionality as the v4 version, but with IPv6 connections. Signed-off-by: Josh Hunt --- extensions/xt_TARPIT.c | 209 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 195 insertions(+), 14 deletions(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index 3b497aa..cdd0f5a 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -42,10 +42,15 @@ #include #include #include +#include #include #ifdef CONFIG_BRIDGE_NETFILTER # include #endif +#include +#include +#include +#include #include #include #include "compat_xtables.h" @@ -162,7 +167,7 @@ static bool tarpit_generic(struct tcphdr *tcph, const struct tcphdr *oth, return true; } -static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, +static void tarpit_tcp4(struct sk_buff *oldskb, unsigned int hook, unsigned int mode) { struct tcphdr _otcph, *tcph; @@ -293,8 +298,130 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook, kfree_skb(nskb); } +static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook, + unsigned int mode) +{ + struct sk_buff *nskb; + struct tcphdr *tcph, oth; + unsigned int otcplen; + int tcphoff; + const struct ipv6hdr *oip6h = ipv6_hdr(oldskb); + struct ipv6hdr *ip6h; + const uint8_t tclass = 0; + uint8_t proto; + uint16_t payload; + + proto = oip6h->nexthdr; + tcphoff = ipv6_skip_exthdr(oldskb, + (uint8_t *)(oip6h + 1) - oldskb->data, &proto); + + if (tcphoff < 0 || tcphoff > oldskb->len) { + pr_debug("Cannot get TCP header.\n"); + return; + } + + otcplen = oldskb->len - tcphoff; + + /* IP header checks: fragment, too short. */ + if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) { + pr_debug("proto(%d) != IPPROTO_TCP, " + "or too short. otcplen = %d\n", + proto, otcplen); + return; + } + + if (skb_copy_bits(oldskb, tcphoff, &oth, sizeof(struct tcphdr))) { + WARN_ON(1); + return; + } + + /* Check checksum. */ + if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP, + skb_checksum(oldskb, tcphoff, otcplen, 0))) { + pr_debug("TCP checksum is invalid\n"); + return; + } + + nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, + skb_tailroom(oldskb), GFP_ATOMIC); + if (nskb == NULL) { + if (net_ratelimit()) + pr_debug("cannot alloc skb\n"); + return; + } + + /* This packet will not be the same as the other: clear nf fields */ + nf_reset(nskb); + skb_nfmark(nskb) = 0; + skb_init_secmark(nskb); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + skb_shinfo(nskb)->gso_size = 0; + skb_shinfo(nskb)->gso_segs = 0; + skb_shinfo(nskb)->gso_type = 0; +#endif + + skb_put(nskb, sizeof(struct ipv6hdr)); + ip6h = ipv6_hdr(nskb); + *(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20)); + ip6h->nexthdr = IPPROTO_TCP; + ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); + ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); + + /* Adjust IP TTL */ + if (mode == XTTARPIT_HONEYPOT) + ip6h->hop_limit = 128; + else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + ip6h->hop_limit = ip6_dst_hoplimit(skb_dst(nskb)); +#else + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT); + if (ip6h->hop_limit < 0) + ip6h->hop_limit = ipv6_get_hoplimit((skb_dst(nskb))->dev). +#endif + + tcph = (struct tcphdr *)(skb_network_header(nskb) + + sizeof(struct ipv6hdr)); + + /* Truncate to length (no data) */ + skb_trim(nskb, sizeof(struct ipv6hdr) + sizeof(struct tcphdr)); + tcph->doff = sizeof(struct tcphdr)/4; + tcph->source = oth.dest; + tcph->dest = oth.source; + tcph->urg_ptr = 0; + /* Reset flags */ + ((uint8_t *)tcph)[13] = 0; + + payload = nskb->len - sizeof(struct ipv6hdr) - sizeof(struct tcphdr); + if (!tarpit_generic(&oth, tcph, payload, mode)) + return; + + ip6h->payload_len = htons(sizeof(struct tcphdr)); + tcph->check = 0; + + /* Adjust TCP checksum */ + tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr, + &ipv6_hdr(nskb)->daddr, sizeof(struct tcphdr), + IPPROTO_TCP, + csum_partial(tcph, sizeof(struct tcphdr), 0)); + + if (ip6_route_me_harder(nskb)) + goto free_nskb; + + nskb->ip_summed = CHECKSUM_NONE; + + nf_ct_attach(nskb, oldskb); + + NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, nskb, NULL, + skb_dst(nskb)->dev, dst_output); + return; + + free_nskb: + kfree_skb(nskb); +} + static unsigned int -tarpit_tg(struct sk_buff **pskb, const struct xt_action_param *par) +tarpit_tg4(struct sk_buff **pskb, const struct xt_action_param *par) { const struct sk_buff *skb = *pskb; const struct iphdr *iph = ip_hdr(skb); @@ -325,29 +452,82 @@ tarpit_tg(struct sk_buff **pskb, const struct xt_action_param *par) if (iph->frag_off & htons(IP_OFFSET)) return NF_DROP; - tarpit_tcp(*pskb, par->hooknum, info->variant); + tarpit_tcp4(*pskb, par->hooknum, info->variant); return NF_DROP; } -static struct xt_target tarpit_tg_reg __read_mostly = { - .name = "TARPIT", - .revision = 0, - .family = NFPROTO_IPV4, - .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD), - .proto = IPPROTO_TCP, - .target = tarpit_tg, - .targetsize = sizeof(struct xt_tarpit_tginfo), - .me = THIS_MODULE, +static unsigned int +tarpit_tg6(struct sk_buff **pskb, const struct xt_action_param *par) +{ + const struct sk_buff *skb = *pskb; + const struct ipv6hdr *iph = ipv6_hdr(skb); + const struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); + const struct xt_tarpit_tginfo *info = par->targinfo; + uint8_t proto; + + /* Do we have an input route cache entry? (Not in PREROUTING.) */ + if (rt == NULL) { + pr_debug("Dropping no input route cache entry\n"); + return NF_DROP; + } + + /* No replies to physical multicast/broadcast */ + /* skb != PACKET_OTHERHOST handled by ip_rcv() */ + if (skb->pkt_type != PACKET_HOST) { + pr_debug("type != PACKET_HOST"); + return NF_DROP; + } + + /* + * Our naive response construction does not deal with IP + * options, and probably should not try. + */ + proto = iph->nexthdr; + if (ipv6_skip_exthdr(skb, skb_network_header_len(skb), &proto) != + sizeof(struct ipv6hdr)) + return NF_DROP; + + if ((!(ipv6_addr_type(&iph->saddr) & IPV6_ADDR_UNICAST)) || + (!(ipv6_addr_type(&iph->daddr) & IPV6_ADDR_UNICAST))) { + pr_debug("addr is not unicast.\n"); + return NF_DROP; + } + + tarpit_tcp6(*pskb, par->hooknum, info->variant); + return NF_DROP; +} + +static struct xt_target tarpit_tg_reg[] __read_mostly = { + { + .name = "TARPIT", + .revision = 0, + .family = NFPROTO_IPV4, + .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD), + .proto = IPPROTO_TCP, + .target = tarpit_tg4, + .targetsize = sizeof(struct xt_tarpit_tginfo), + .me = THIS_MODULE, + }, + { + .name = "TARPIT", + .revision = 0, + .family = NFPROTO_IPV6, + .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD), + .proto = IPPROTO_TCP, + .target = tarpit_tg6, + .targetsize = sizeof(struct xt_tarpit_tginfo), + .me = THIS_MODULE, + }, }; static int __init tarpit_tg_init(void) { - return xt_register_target(&tarpit_tg_reg); + return xt_register_targets(tarpit_tg_reg, ARRAY_SIZE(tarpit_tg_reg)); } static void __exit tarpit_tg_exit(void) { - xt_unregister_target(&tarpit_tg_reg); + xt_unregister_targets(tarpit_tg_reg, ARRAY_SIZE(tarpit_tg_reg)); } module_init(tarpit_tg_init); @@ -356,3 +536,4 @@ MODULE_DESCRIPTION("Xtables: \"TARPIT\", capture and hold TCP connections"); MODULE_AUTHOR("Jan Engelhardt "); MODULE_LICENSE("GPL"); MODULE_ALIAS("ipt_TARPIT"); +MODULE_ALIAS("ip6t_TARPIT"); From e5093b61cd4145ba7da4efd143f8211ace4bbc96 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 9 Jul 2012 18:54:22 +0200 Subject: [PATCH 07/11] compat_xtables: add xtnu_ipv6_skip_exthdr --- extensions/compat_xtables.c | 8 ++++++++ extensions/compat_xtables.h | 1 + extensions/compat_xtnu.h | 2 ++ 3 files changed, 11 insertions(+) diff --git a/extensions/compat_xtables.c b/extensions/compat_xtables.c index 1a82a5c..9bd1b8d 100644 --- a/extensions/compat_xtables.c +++ b/extensions/compat_xtables.c @@ -613,6 +613,14 @@ void *HX_memmem(const void *space, size_t spacesize, } EXPORT_SYMBOL_GPL(HX_memmem); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) +int xtnu_ipv6_skip_exthdr(const struct sk_buff *skb, int start, + uint8_t *nexthdrp, __be16 *fragoffp) +{ + return ipv6_skip_exthdr(skb, start, nexthdrp); +} +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) int xtnu_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target, unsigned short *fragoff, int *fragflg) diff --git a/extensions/compat_xtables.h b/extensions/compat_xtables.h index 1af9536..a1caa51 100644 --- a/extensions/compat_xtables.h +++ b/extensions/compat_xtables.h @@ -96,6 +96,7 @@ # define nf_nat_ipv4_multi_range_compat nf_nat_multi_range_compat # define nf_nat_ipv4_range nf_nat_range # define NF_NAT_RANGE_MAP_IPS IP_NAT_RANGE_MAP_IPS +# define ipv6_skip_exthdr xtnu_ipv6_skip_exthdr #endif #if !defined(NIP6) && !defined(NIP6_FMT) diff --git a/extensions/compat_xtnu.h b/extensions/compat_xtnu.h index 147ad57..35819b0 100644 --- a/extensions/compat_xtnu.h +++ b/extensions/compat_xtnu.h @@ -162,6 +162,8 @@ extern void xtnu_csum_replace4(__u16 __bitwise *, __be32, __be32); extern void xtnu_proto_csum_replace4(__u16 __bitwise *, struct sk_buff *, __be32, __be32, bool); extern int xtnu_skb_linearize(struct sk_buff *); +extern int xtnu_ipv6_skip_exthdr(const struct sk_buff *, int, + uint8_t *, __be16 *); extern int xtnu_ipv6_find_hdr(const struct sk_buff *, unsigned int *, int, unsigned short *, int *); From 06b82c649da22f645e2852fe123c34aa81dea097 Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Mon, 9 Jul 2012 07:00:02 -0700 Subject: [PATCH 08/11] TARPIT: resolve build errors with newer kernels Adds fragment offset arg to ipv6_skip_exthdr() and also removes usage of ipv6_addr_copy() in favor or direct assignment. Signed-off-by: Josh Hunt --- extensions/xt_TARPIT.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/extensions/xt_TARPIT.c b/extensions/xt_TARPIT.c index cdd0f5a..ac69364 100644 --- a/extensions/xt_TARPIT.c +++ b/extensions/xt_TARPIT.c @@ -310,10 +310,11 @@ static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook, const uint8_t tclass = 0; uint8_t proto; uint16_t payload; + __be16 frag_off; proto = oip6h->nexthdr; tcphoff = ipv6_skip_exthdr(oldskb, - (uint8_t *)(oip6h + 1) - oldskb->data, &proto); + (uint8_t *)(oip6h + 1) - oldskb->data, &proto, &frag_off); if (tcphoff < 0 || tcphoff > oldskb->len) { pr_debug("Cannot get TCP header.\n"); @@ -365,8 +366,8 @@ static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook, ip6h = ipv6_hdr(nskb); *(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20)); ip6h->nexthdr = IPPROTO_TCP; - ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); - ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); + ip6h->saddr = oip6h->daddr; + ip6h->daddr = oip6h->saddr; /* Adjust IP TTL */ if (mode == XTTARPIT_HONEYPOT) @@ -464,6 +465,7 @@ tarpit_tg6(struct sk_buff **pskb, const struct xt_action_param *par) const struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); const struct xt_tarpit_tginfo *info = par->targinfo; uint8_t proto; + __be16 frag_off; /* Do we have an input route cache entry? (Not in PREROUTING.) */ if (rt == NULL) { @@ -483,8 +485,8 @@ tarpit_tg6(struct sk_buff **pskb, const struct xt_action_param *par) * options, and probably should not try. */ proto = iph->nexthdr; - if (ipv6_skip_exthdr(skb, skb_network_header_len(skb), &proto) != - sizeof(struct ipv6hdr)) + if (ipv6_skip_exthdr(skb, skb_network_header_len(skb), &proto, + &frag_off) != sizeof(struct ipv6hdr)) return NF_DROP; if ((!(ipv6_addr_type(&iph->saddr) & IPV6_ADDR_UNICAST)) || From af940bcbae7ff6334f6d5e3a059c0c124e0a2e77 Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Sun, 8 Jul 2012 11:11:25 -0700 Subject: [PATCH 09/11] TARPIT: enable IPv6 userspace support Signed-off-by: Josh Hunt --- extensions/libxt_TARPIT.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/libxt_TARPIT.c b/extensions/libxt_TARPIT.c index 59c190f..6b65b09 100644 --- a/extensions/libxt_TARPIT.c +++ b/extensions/libxt_TARPIT.c @@ -106,7 +106,7 @@ static void tarpit_tg_save(const void *ip, static struct xtables_target tarpit_tg_reg = { .version = XTABLES_VERSION, .name = "TARPIT", - .family = NFPROTO_IPV4, + .family = NFPROTO_UNSPEC, .size = XT_ALIGN(sizeof(struct xt_tarpit_tginfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_tarpit_tginfo)), .help = tarpit_tg_help, From f9aca7621ca7eb15c6e04be20f1e9baaeb795f00 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 9 Jul 2012 19:06:22 +0200 Subject: [PATCH 10/11] compat_xtables: avoid compile abort on <= 2.6.37 --- extensions/compat_xtables.c | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/compat_xtables.c b/extensions/compat_xtables.c index 9bd1b8d..b79a891 100644 --- a/extensions/compat_xtables.c +++ b/extensions/compat_xtables.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) # include From 8d5b7c5b7dde77b3f31a09a6e10da134a0339ead Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 9 Jul 2012 19:07:24 +0200 Subject: [PATCH 11/11] doc: changelog entry for IPv6 TARPIT --- doc/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/changelog.txt b/doc/changelog.txt index 46b4662..9b2940e 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,6 +1,8 @@ HEAD ==== +Enhancements: +- TARPIT gained IPv6 support v1.43 (2012-06-30)