[181] in linux-net channel archive

home help back first fref pref prev next nref lref last post

ICMP redirects in 1.2.4

daemon@ATHENA.MIT.EDU (Peter Belding)
Fri Apr 7 04:51:14 1995

Date: Thu, 6 Apr 1995 22:18:24 -0700 (PDT)
From: Peter Belding <pbelding@qualcomm.com>
To: linux-net@vger.rutgers.edu
cc: Linus.Torvalds@cs.Helsinki.FI, Alan Cox <gw4pts@gw4pts.ampr.org>
In-Reply-To: <m0rwwBD-000KjHC@monad.swb.de>

In 1.2.4, ICMP redirects are sent only if the source and destination of 
an offending packet are on the same network.  I don't believe this is 
correct.  According to RFC1009 "Requirements for Internet Gateways",

      A gateway will generate an ICMP Redirect if and only if the
      destination IP address is reachable from the gateway (as
      determined by the routing algorithm) and the next-hop gateway is
      on the same (sub-)network as the source host.  

I think that if the receiving interface and source host are on the same 
network and the next-hop gateway is accessed via the receiving interface, 
then the above is true.

The following patch steals some ideas from 4.4BSD.  ICMP redirects are
only sent if 1) a packet would be forwarded out the interface it was
received, 2) the source host and receiving interface are on the same
network, and 3) the route which send the offending packet back out the
receiving interface was not itself created by an ICMP redirect. 

ICMP redirects are only processed if the new gateway and the receiving 
interface are on the same network.

These changes compile but are otherwise untested as my linux box isn't in
the position of playing router.  If some kind soul could test this and let
me know if I've done something stupid, it would be much appreciated. 

-Peter

--- icmp.c.save	Thu Apr  6 19:58:33 1995
+++ icmp.c	Thu Apr  6 20:03:46 1995
@@ -30,6 +30,7 @@
  *		Alan Cox	:	Tightened up icmp_send().
  *		Alan Cox	:	Multicasts.
  *		Stefan Becker   :       ICMP redirects in icmp_send().
+ *		Peter Belding	:	More restrictive handling of ICMP redirects
  *
  * 
  *
@@ -374,12 +375,15 @@
 			 *	comes from the old gateway..
 			 *	And make sure it's an ok host address
 			 *	(not some confused thing sending our
-			 *	address)
+			 *	address).  Check that the new gateway is
+			 *	on the same network as the receiving device.
 			 */
 			rt = ip_rt_route(ip, NULL, NULL);
 			if (!rt)
 				break;
-			if (rt->rt_gateway != source || ip_chk_addr(icmph->un.gateway))
+			if (rt->rt_gateway != source  ||
+				(icmph->un.gateway&dev->pa_mask!=dev->pa_addr&dev->pa_mask) ||
+				ip_chk_addr(icmph->un.gateway))
 				break;
 			printk("redirect from %s\n", in_ntoa(source));
 			ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY),
--- ip.c.save	Thu Apr  6 19:59:51 1995
+++ ip.c	Thu Apr  6 20:20:47 1995
@@ -69,6 +69,8 @@
  *		Bjorn Ekwall	:	Moved ip_fast_csum to ip.h (inline!)
  *		Stefan Becker   :       Send out ICMP HOST REDIRECT
  *		Alan Cox	:	Only send ICMP_REDIRECT if src/dest are the same net.
+ *		Peter Belding	:	No, if src/receiving device are on the same net
+ *					and if route wasn't created by a ICMP_REDIRECT itself.
  *  
  *
  * To Fix:
@@ -1365,12 +1367,17 @@
 	 *	In IP you never have to forward a frame on the interface that it 
 	 *	arrived upon. We now generate an ICMP HOST REDIRECT giving the route
 	 *	we calculated.
+	 *	Redirects are only sent when 1) the source address and the address of
+	 *	the receiving device are on the same network, and 2) the route that
+	 *	caused the frame to be forwarded out the same interface was not itself
+	 *	the result of an ICMP redirect.
 	 */
 #ifdef CONFIG_IP_NO_ICMP_REDIRECT
 	if (dev == dev2)
 		return;
 #else
-	if (dev == dev2 && (iph->saddr&dev->pa_mask) == (iph->daddr & dev->pa_mask))
+	if (dev == dev2 && (iph->saddr&dev->pa_mask) == (dev->pa_addr & dev->pa_mask)
+	    && (rt->rt_flags&(RTF_DYNAMIC|RTF_MODIFIED) == 0))
 		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
 #endif		
 




home help back first fref pref prev next nref lref last post