diff options
-rw-r--r-- | ip6t_MAP66.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/ip6t_MAP66.c b/ip6t_MAP66.c index ca0e559..b00c818 100644 --- a/ip6t_MAP66.c +++ b/ip6t_MAP66.c @@ -126,10 +126,22 @@ static unsigned int MAP66_tg6( &hdr->saddr, &hdr->daddr); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + if (skb_cloned(skb) && !skb->sk) { + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC); + if (!nskb) { + pr_devel("MAP66: cannot copy, dropped\n"); + return NF_DROP; + } + kfree_skb(skb); + skb = nskb; + } +#else if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) { pr_devel("MAP66: unwriteable, dropped\n"); return NF_DROP; } +#endif hdr = ipv6_hdr(skb); if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags)) { @@ -148,7 +160,12 @@ static unsigned int MAP66_tg6( if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags)) { pr_devel("MAP66 SRC, nocheck=%d, ip_summed=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags), skb->ip_summed); - map16(&hdr->saddr, &info->pfix_src_to, info->pfix_src_len, info->pfix_src_csum); + if (0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags)) { + memcpy(&hdr->saddr, &info->pfix_src_to, sizeof(u_int16_t) * info->pfix_src_len); + } + else { + map16(&hdr->saddr, &info->pfix_src_to, info->pfix_src_len, info->pfix_src_csum); + } if (0 == (IP6T_MAP66_OPT_NOCHECK & info->mapflags) && is_my_ipv6_addr(par->out, &hdr->saddr)) { |