diff options
Diffstat (limited to 'net/ipv4/netfilter/ip_nat_proto_udp.c')
-rw-r--r-- | net/ipv4/netfilter/ip_nat_proto_udp.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c index 3c492530863c1..c669e3b5f5d0d 100644 --- a/net/ipv4/netfilter/ip_nat_proto_udp.c +++ b/net/ipv4/netfilter/ip_nat_proto_udp.c @@ -84,34 +84,40 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple, static int udp_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff, - const struct ip_conntrack_manip *manip, + const struct ip_conntrack_tuple *tuple, enum ip_nat_manip_type maniptype) { struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff); struct udphdr *hdr; unsigned int hdroff = iphdroff + iph->ihl*4; - u32 oldip, oldsrc = iph->saddr, olddst = iph->daddr; - u16 *portptr; + u32 oldip, newip; + u16 *portptr, newport; if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr))) return 0; - hdr = (void *)(*pskb)->data + hdroff; + iph = (struct iphdr *)((*pskb)->data + iphdroff); + hdr = (struct udphdr *)((*pskb)->data + hdroff); + if (maniptype == IP_NAT_MANIP_SRC) { /* Get rid of src ip and src pt */ - oldip = oldsrc; + oldip = iph->saddr; + newip = tuple->src.ip; + newport = tuple->src.u.udp.port; portptr = &hdr->source; } else { /* Get rid of dst ip and dst pt */ - oldip = olddst; + oldip = iph->daddr; + newip = tuple->dst.ip; + newport = tuple->dst.u.udp.port; portptr = &hdr->dest; } if (hdr->check) /* 0 is a special case meaning no checksum */ - hdr->check = ip_nat_cheat_check(~oldip, manip->ip, + hdr->check = ip_nat_cheat_check(~oldip, newip, ip_nat_cheat_check(*portptr ^ 0xFFFF, - manip->u.udp.port, + newport, hdr->check)); - *portptr = manip->u.udp.port; + *portptr = newport; return 1; } |