Commit b803d5f5 authored by Patrick McHardy's avatar Patrick McHardy

[NETFILTER]: Fix invalid tcp/udp checksums within NATed icmp errors

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent d70bfc85
......@@ -18,7 +18,7 @@ struct ip_nat_protocol
/* Do a packet translation according to the ip_nat_proto_manip
* and manip type. Return true if succeeded. */
int (*manip_pkt)(struct sk_buff **pskb,
unsigned int hdroff,
unsigned int iphdroff,
const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype);
......
......@@ -687,7 +687,7 @@ manip_pkt(u_int16_t proto,
iph = (void *)(*pskb)->data + iphdroff;
/* Manipulate protcol part. */
if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff + iph->ihl*4,
if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff,
manip, maniptype))
return 0;
......
......@@ -53,11 +53,13 @@ icmp_unique_tuple(struct ip_conntrack_tuple *tuple,
static int
icmp_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff,
unsigned int iphdroff,
const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype)
{
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct icmphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
return 0;
......
......@@ -84,11 +84,13 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
static int
tcp_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff,
unsigned int iphdroff,
const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype)
{
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct tcphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
u_int32_t oldip;
u_int16_t *portptr, oldport;
int hdrsize = 8; /* TCP connection tracking guarantees this much */
......@@ -106,11 +108,11 @@ tcp_manip_pkt(struct sk_buff **pskb,
if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */
oldip = (*pskb)->nh.iph->saddr;
oldip = iph->saddr;
portptr = &hdr->source;
} else {
/* Get rid of dst ip and dst pt */
oldip = (*pskb)->nh.iph->daddr;
oldip = iph->daddr;
portptr = &hdr->dest;
}
......
......@@ -83,11 +83,13 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
static int
udp_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff,
unsigned int iphdroff,
const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype)
{
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct udphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
u_int32_t oldip;
u_int16_t *portptr;
......@@ -97,11 +99,11 @@ udp_manip_pkt(struct sk_buff **pskb,
hdr = (void *)(*pskb)->data + hdroff;
if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */
oldip = (*pskb)->nh.iph->saddr;
oldip = iph->saddr;
portptr = &hdr->source;
} else {
/* Get rid of dst ip and dst pt */
oldip = (*pskb)->nh.iph->daddr;
oldip = iph->daddr;
portptr = &hdr->dest;
}
if (hdr->check) /* 0 is a special case meaning no checksum */
......
......@@ -39,7 +39,7 @@ static int unknown_unique_tuple(struct ip_conntrack_tuple *tuple,
static int
unknown_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff,
unsigned int iphdroff,
const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment