patch-2.4.19 linux-2.4.19/net/ipv6/ndisc.c

Next file: linux-2.4.19/net/ipv6/netfilter/ip6_queue.c
Previous file: linux-2.4.19/net/ipv6/addrconf.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/net/ipv6/ndisc.c linux-2.4.19/net/ipv6/ndisc.c
@@ -356,7 +356,7 @@
 	ipv6_addr_copy(&msg->target, solicited_addr);
 
 	if (inc_opt)
-		ndisc_fill_option((void*)&msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
 
 	/* checksum */
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(solicited_addr, daddr, len, 
@@ -417,7 +417,7 @@
 	ipv6_addr_copy(&msg->target, solicit);
 
 	if (send_llinfo)
-		ndisc_fill_option((void*)&msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
 
 	/* checksum */
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
@@ -567,6 +567,11 @@
 			printk(KERN_WARNING "ICMP RA: source address is not linklocal\n");
 		return;
 	}
+	if (optlen < 0) {
+		if (net_ratelimit())
+			printk(KERN_WARNING "ICMP RA: packet too short\n");
+		return;
+	}
 
 	/*
 	 *	set the RA_RECV flag in the interface
@@ -923,7 +928,7 @@
 	u8 *opt;
 
 	opt = skb->h.raw;
-	opt += sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
+	opt += sizeof(struct nd_msg);
 	opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_SOURCE_LL_ADDR);
 
 	return neigh_event_ns(&nd_tbl, opt, saddr, skb->dev);
@@ -931,12 +936,11 @@
 
 static __inline__ int ndisc_recv_na(struct neighbour *neigh, struct sk_buff *skb)
 {
-	struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
 	u8 *opt;
+	struct nd_msg *msg = (struct nd_msg*) skb->h.raw;
 
-	opt = skb->h.raw;
-	opt += sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
-	opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_TARGET_LL_ADDR);
+	opt = ndisc_find_option(msg->opt, skb->dev->addr_len+2,
+				skb->tail - msg->opt, ND_OPT_TARGET_LL_ADDR);
 
 	return neigh_update(neigh, opt,
 			    msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
@@ -957,7 +961,6 @@
 	struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
 	struct neighbour *neigh;
 	struct inet6_ifaddr *ifp;
-	unsigned int payload_len;
 
 	__skb_push(skb, skb->data-skb->h.raw);
 
@@ -980,11 +983,9 @@
 	 *	(Some checking in ndisc_find_option)
 	 */
 
-	payload_len = ntohs(skb->nh.ipv6h->payload_len);
 	switch (msg->icmph.icmp6_type) {
 	case NDISC_NEIGHBOUR_SOLICITATION:
-		/* XXX: import nd_neighbor_solicit from glibc netinet/icmp6.h */
-		if (payload_len < 8+16) {
+		if (skb->len < sizeof(struct nd_msg)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "ICMP NS: packet too short\n");
 			return 0;
@@ -1064,12 +1065,13 @@
 
 				neigh = ndisc_recv_ns(saddr, skb);
 
-				if (neigh) {
+				if (neigh || !dev->hard_header) {
 					ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
 						      ifp->idev->cnf.forwarding, 1, 
 						      ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, 
 						      1);
-					neigh_release(neigh);
+					if (neigh)
+						neigh_release(neigh);
 				}
 			}
 			in6_ifa_put(ifp);
@@ -1113,8 +1115,7 @@
 		return 0;
 
 	case NDISC_NEIGHBOUR_ADVERTISEMENT:
-		/* XXX: import nd_neighbor_advert from glibc netinet/icmp6.h */
-		if (payload_len < 16+8 ) {
+		if (skb->len < sizeof(struct nd_msg)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "ICMP NA: packet too short\n");
 			return 0;
@@ -1175,35 +1176,12 @@
 		break;
 
 	case NDISC_ROUTER_ADVERTISEMENT:
-		/* XXX: import nd_router_advert from glibc netinet/icmp6.h */
-		if (payload_len < 8+4+4) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP RA: packet too short\n");
-			return 0;
-		}
 		ndisc_router_discovery(skb);
 		break;
 
 	case NDISC_REDIRECT:
-		/* XXX: import nd_redirect from glibc netinet/icmp6.h */
-		if (payload_len < 8+16+16) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP redirect: packet too short\n");
-			return 0;
-		}
 		ndisc_redirect_rcv(skb);
 		break;
-
-	case NDISC_ROUTER_SOLICITATION:
-		/* No RS support in the kernel, but we do some required checks */
-
-		/* XXX: import nd_router_solicit from glibc netinet/icmp6.h */
-		if (payload_len < 8) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP RS: packet too short\n");
-			return 0;
-		}
-		break;
 	};
 
 	return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)