diff options
Diffstat (limited to 'ip6t_MAP66.c')
-rw-r--r-- | ip6t_MAP66.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/ip6t_MAP66.c b/ip6t_MAP66.c index 6446927..ca0e559 100644 --- a/ip6t_MAP66.c +++ b/ip6t_MAP66.c @@ -126,17 +126,28 @@ static unsigned int MAP66_tg6( &hdr->saddr, &hdr->daddr); #endif + if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) { + pr_devel("MAP66: unwriteable, dropped\n"); + return NF_DROP; + } + hdr = ipv6_hdr(skb); + if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags)) { - pr_devel("MAP66 DST, check=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags)); + pr_devel("MAP66 DST, nocheck=%d, ip_summed=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags), skb->ip_summed); if (0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags) || !is_my_ipv6_addr(par->in, &hdr->daddr)) { - map16(&hdr->daddr, &info->pfix_dst_to, info->pfix_dst_len, info->pfix_dst_csum); + if (0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags)) { + memcpy(&hdr->daddr, &info->pfix_dst_to, sizeof(u_int16_t) * info->pfix_dst_len); + } + else { + map16(&hdr->daddr, &info->pfix_dst_to, info->pfix_dst_len, info->pfix_dst_csum); + } } } if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags)) { - pr_devel("MAP66 SRC, check=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & 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_NOCHECK & info->mapflags) && is_my_ipv6_addr(par->out, &hdr->saddr)) @@ -170,17 +181,27 @@ static bool MAP66_tg6_check( return false; } - if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags) && - (0 >= info->pfix_dst_len || 8 <= info->pfix_dst_len)) + if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags) && (0 >= info->pfix_dst_len || + 0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags) ? 8 : 7 < info->pfix_dst_len)) { - printk("MAP66: Unsupported --" IP6T_MAP66_DST_TO " prefix length /%d\n", 16 * info->pfix_dst_len); + if (8 == info->pfix_dst_len) { + printk("MAP66: --" IP6T_MAP66_DST_TO " prefix length /%d only possible with --unbalanced\n", 16 * info->pfix_dst_len); + } + else { + printk("MAP66: Unsupported --" IP6T_MAP66_DST_TO " prefix length /%d\n", 16 * info->pfix_dst_len); + } return false; } - if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags) && - (0 >= info->pfix_src_len || 8 <= info->pfix_src_len)) + if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags) && (0 >= info->pfix_src_len || + 0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags) ? 8 : 7 < info->pfix_src_len)) { - printk("MAP66: Unsupported --" IP6T_MAP66_SRC_TO " prefix length /%d\n", 16 * info->pfix_src_len); + if (8 == info->pfix_src_len) { + printk("MAP66: --" IP6T_MAP66_SRC_TO " prefix length /%d only possible with --unbalanced\n", 16 * info->pfix_src_len); + } + else { + printk("MAP66: Unsupported --" IP6T_MAP66_SRC_TO " prefix length /%d\n", 16 * info->pfix_src_len); + } return false; } return true; |