diff options
Diffstat (limited to 'ip6t_MAP66.c')
-rw-r--r-- | ip6t_MAP66.c | 79 |
1 files changed, 31 insertions, 48 deletions
diff --git a/ip6t_MAP66.c b/ip6t_MAP66.c index ea04c7d..b863c1c 100644 --- a/ip6t_MAP66.c +++ b/ip6t_MAP66.c @@ -39,38 +39,25 @@ static inline u_int16_t csum16(const u_int16_t *buf, int len) return csum; } -/* Perform checksum neutral mapping */ -static void map16( - struct in6_addr* addr, - const struct in6_addr* to, - int len_to, - u_int16_t csum_to) -{ - csum_to = add16( - *((u_int16_t*)addr + len_to), - add16(csum16((const u_int16_t *)addr, len_to), csum_to) - ); - if (csum_to == 0xffff) csum_to = 0x0000; - *((u_int16_t *)addr + len_to) = csum_to; - memcpy(addr, to, sizeof(u_int16_t) * len_to); -} - /* Perform mapping with csum update, see RFC 1624 */ -static void map_csum( - struct in6_addr* addr, - const struct in6_addr* to, - int len_to, - u_int16_t csum_to, - u_int16_t* csum_transport) +static void map16( + u_int16_t *dest, + const u_int16_t *source, + int len, + u_int16_t csum, + u_int16_t* pcsum) { - *csum_transport = ~add16( + if (NULL == pcsum) { + pcsum = dest + len; + } + *pcsum = ~add16( add16( - ~(*csum_transport), - ~csum16((u_int16_t *)addr, len_to) + ~(*pcsum), + ~csum16(dest, len) ), - ~csum_to + csum ); - memcpy(addr, to, len_to * 2); + memcpy(dest, source, len * sizeof(u_int16_t)); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) @@ -146,7 +133,7 @@ static unsigned int MAP66_tg6( struct sk_buff *skb, const struct xt_target_param *par) { - u_int16_t* csum_transport = NULL; + u_int16_t* pcsum = NULL; struct ipv6hdr *hdr = ipv6_hdr(skb); const struct ip6t_MAP66_info *info = par->targinfo; @@ -192,21 +179,21 @@ static unsigned int MAP66_tg6( } switch(nexthdr) { case IPPROTO_TCP: - csum_transport = &((struct tcphdr*)transport)->check; + pcsum = &((struct tcphdr*)transport)->check; break; case IPPROTO_UDP: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) case IPPROTO_UDPLITE: #endif - csum_transport = &((struct udphdr*)transport)->check; + pcsum = &((struct udphdr*)transport)->check; break; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) case IPPROTO_DCCP: - csum_transport = &((struct dccp_hdr*)transport)->dccph_checksum; + pcsum = &((struct dccp_hdr*)transport)->dccph_checksum; break; #endif case IPPROTO_ICMPV6: - csum_transport = &((struct icmp6hdr*)transport)->icmp6_cksum; + pcsum = &((struct icmp6hdr*)transport)->icmp6_cksum; break; default: pr_devel("MAP66: Unsupported protocol %d dropped\n", nexthdr); @@ -218,22 +205,14 @@ static unsigned int MAP66_tg6( if (0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags) || !is_my_ipv6_addr( NF_INET_PRE_ROUTING == par->hooknum ? par->in : par->out, &hdr->daddr)) { - if (0 != (IP6T_MAP66_OPT_CSUM & info->mapflags)) { - map_csum(&hdr->daddr, &info->pfix_dst_to, info->pfix_dst_len, info->pfix_dst_csum, csum_transport); - } - else { - map16(&hdr->daddr, &info->pfix_dst_to, info->pfix_dst_len, info->pfix_dst_csum); - } + map16((u_int16_t *)&hdr->daddr, (u_int16_t *)&info->pfix_dst_to, + info->pfix_dst_len, info->pfix_dst_csum, pcsum); } } if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags)) { - if (0 != (IP6T_MAP66_OPT_CSUM & info->mapflags)) { - map_csum(&hdr->saddr, &info->pfix_src_to, info->pfix_src_len, info->pfix_src_csum, csum_transport); - } - else { - map16(&hdr->saddr, &info->pfix_src_to, info->pfix_src_len, info->pfix_src_csum); - } + map16((u_int16_t *)&hdr->saddr, (u_int16_t *)&info->pfix_src_to, + info->pfix_src_len, info->pfix_src_csum, pcsum); if (0 == (IP6T_MAP66_OPT_NOCHECK & info->mapflags) && is_my_ipv6_addr( NF_INET_PRE_ROUTING == par->hooknum ? par->in : par->out, &hdr->saddr)) { @@ -263,10 +242,12 @@ static bool MAP66_tg6_check( (0 != (IP6T_MAP66_OPT_CSUM & info->mapflags) ? 8 : 7) < info->pfix_dst_len)) { if (8 == info->pfix_dst_len) { - printk("MAP66: --" IP6T_MAP66_DST_TO " prefix length /%d only possible with --csum\n", 16 * info->pfix_dst_len); + printk("MAP66: --" IP6T_MAP66_DST_TO " prefix length /%d only " + "possible with --csum\n", 16 * info->pfix_dst_len); } else { - printk("MAP66: Unsupported --" IP6T_MAP66_DST_TO " prefix length /%d\n", 16 * info->pfix_dst_len); + printk("MAP66: Unsupported --" IP6T_MAP66_DST_TO " prefix " + "length /%d\n", 16 * info->pfix_dst_len); } return false; } @@ -275,10 +256,12 @@ static bool MAP66_tg6_check( (0 != (IP6T_MAP66_OPT_CSUM & info->mapflags) ? 8 : 7) < info->pfix_src_len)) { if (8 == info->pfix_src_len) { - printk("MAP66: --" IP6T_MAP66_SRC_TO " prefix length /%d only possible with --csum\n", 16 * info->pfix_src_len); + printk("MAP66: --" IP6T_MAP66_SRC_TO " prefix length /%d only " + "possible with --csum\n", 16 * info->pfix_src_len); } else { - printk("MAP66: Unsupported --" IP6T_MAP66_SRC_TO " prefix length /%d\n", 16 * info->pfix_src_len); + printk("MAP66: Unsupported --" IP6T_MAP66_SRC_TO " prefix " + "length /%d\n", 16 * info->pfix_src_len); } return false; } |