diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 2ada033..27c3938 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -399,9 +399,9 @@ out: read_unlock(&ipgre_lock); return; #else - struct iphdr *iph = (struct iphdr*)dp; + struct iphdr *iph = (struct iphdr*)skb->data; struct iphdr *eiph; - __be16 *p = (__be16*)(dp+(iph->ihl<<2)); + __be16 *p = (__be16*)(skb->data + (iph->ihl<<2)); const int type = icmp_hdr(skb)->type; const int code = icmp_hdr(skb)->code; int rel_type = 0; @@ -413,7 +413,9 @@ out: struct sk_buff *skb2; struct flowi fl; struct rtable *rt; - + + int len = skb->len; + if (p[1] != htons(ETH_P_IP)) return; @@ -430,7 +432,7 @@ out: } if (len < grehlen + sizeof(struct iphdr)) return; - eiph = (struct iphdr*)(dp + grehlen); + eiph = (struct iphdr*)(skb->data + grehlen); switch (type) { default: diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 149111f..4474f41 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -338,7 +338,7 @@ out: read_unlock(&ipip_lock); return err; #else - struct iphdr *iph = (struct iphdr*)dp; + struct iphdr *iph = (struct iphdr*)skb->data; int hlen = iph->ihl<<2; struct iphdr *eiph; const int type = icmp_hdr(skb)->type; @@ -351,9 +351,11 @@ out: struct flowi fl; struct rtable *rt; + int len = skb->len; + if (len < hlen + sizeof(struct iphdr)) return 0; - eiph = (struct iphdr*)(dp + hlen); + eiph = (struct iphdr*)(skb->data + hlen); switch (type) { default: @@ -414,10 +416,10 @@ out: /* Try to guess incoming interface */ memset(&fl, 0, sizeof(fl)); - fl.fl4_daddr = eiph->saddr; + fl.fl4_dst = eiph->saddr; fl.fl4_tos = RT_TOS(eiph->tos); fl.proto = IPPROTO_IPIP; - if (ip_route_output_key(dev_net(skb->dev), &rt, &key)) { + if (ip_route_output_key(dev_net(skb->dev), &rt, &fl)) { kfree_skb(skb2); return 0; } @@ -427,7 +429,7 @@ out: if (rt->rt_flags&RTCF_LOCAL) { ip_rt_put(rt); rt = NULL; - fl.fl4_daddr = eiph->daddr; + fl.fl4_dst = eiph->daddr; fl.fl4_src = eiph->saddr; fl.fl4_tos = eiph->tos; if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) || diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 5a6fab9..c347c67 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -463,7 +463,7 @@ out: read_unlock(&ipip6_lock); return err; #else - struct iphdr *iph = (struct iphdr*)dp; + struct iphdr *iph = (struct iphdr*)skb->data; int hlen = iph->ihl<<2; struct ipv6hdr *iph6; const int type = icmp_hdr(skb)->type; @@ -473,17 +473,19 @@ out: int rel_info = 0; struct sk_buff *skb2; struct rt6_info *rt6i; - + + int len = skb->len; + if (len < hlen + sizeof(struct ipv6hdr)) - return; - iph6 = (struct ipv6hdr*)(dp + hlen); + return 0; + iph6 = (struct ipv6hdr*)(skb->data + hlen); switch (type) { default: - return; + return 0; case ICMP_PARAMETERPROB: if (icmp_hdr(skb)->un.gateway < hlen) - return; + return 0; /* So... This guy found something strange INSIDE encapsulated packet. Well, he is fool, but what can we do ? @@ -497,10 +499,10 @@ out: case ICMP_SR_FAILED: case ICMP_PORT_UNREACH: /* Impossible event. */ - return; + return 0; case ICMP_FRAG_NEEDED: /* Too complicated case ... */ - return; + return 0; default: /* All others are translated to HOST_UNREACH. rfc2003 contains "deep thoughts" about NET_UNREACH, @@ -513,7 +515,7 @@ out: break; case ICMP_TIME_EXCEEDED: if (code != ICMP_EXC_TTL) - return; + return 0; rel_type = ICMPV6_TIME_EXCEED; rel_code = ICMPV6_EXC_HOPLIMIT; break;