summaryrefslogtreecommitdiffstats
path: root/ip6t_MAP66.c
diff options
context:
space:
mode:
Diffstat (limited to 'ip6t_MAP66.c')
-rw-r--r--ip6t_MAP66.c79
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;
}