🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.bugs.4bsd
Article #509

erroneous ICMP error messages in 4.3

#509
From: Charles Hedrick
Date: Wed, 21 Jan 1987 04:11
146 lines
5064 bytes
Our network is being flooded by ICMP unreachable messages.  We have
systems that use the new broadcast address of all ones.
Unfortunately, 4.3 recognizes this address only in certain parts of
the code.  Suppose a machine sends a broadcast packet to a UDP port
that we don't have a server on.  ip_input recognizes all ones, and
passes it to udp_usrreq.  udp sees that there is no port, and then
sends ICMP port unreachable.  It should not do this in response to
broadcast messages.  There is an attempt to test for this, but it
calls in_broadcast.  This only tests for the default broadcast
address.  The test should be for all legal broadcast addresses.  Since
similar code appears in several places, I have added a routine
in_any_broadcast.  This extends in_broadcast to include the same set
of addresses that ip_input tests for.  Here are the changes.

WARNING: I have not tested these changes.  I'm about to go to a
conference and don't have time to test a new kernel.  These should
be close enough to show what needs to be done.

*** in.c.HOLD	Thu Nov 20 13:38:42 1986
--- in.c	Tue Jan 20 22:36:46 1987
***************
*** 456,458
  	UNLOCKSEM(&ip_lock);
  	return (0);
  }

--- 456,493 -----
  	UNLOCKSEM(&ip_lock);
  	return (0);
  }
+ 
+ /*
+  * Return 1 if the address is any of the possible broadcast addresses.
+  * in_broadcast is used to recognize things that we intend as broadcasts.
+  * So it only looks at broadaddr on each net.  This one is used to test
+  * incoming addresses, so it must allow any of the various standards.
+  */
+ in_any_broadcast(in)
+ 	struct in_addr in;
+ {
+ 	register struct in_ifaddr *ia;
+ 
+ 	/*
+ 	 * Look through the list of addresses for a match
+ 	 * with a broadcast address.
+ 	 */
+ 	if (in.s_addr == 0 || in.s_addr == 0xffffffff)
+ 	  return(1);
+ 	SPINLOCK(&ip_lock);
+ 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
+ 	  if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
+ 	    if (((struct sockaddr_in *)&ia->ia_broadaddr)->sin_addr.s_addr ==
+ 		in.s_addr)
+ 	      goto isbroad;
+ 	    if (ia->ia_subnet == ntohl(in.s_addr))
+ 	      goto isbroad;
+ 	    if (ia->ia_net == ntohl(in.s_addr))
+ 	      goto isbroad;
+ 	  }
+ 	UNLOCKSEM(&ip_lock);
+ 	return (0);
+ isbroad:		
+ 	UNLOCKSEM(&ip_lock);
+ 	return (1);
+ }
*** ip_input.c.HOLD	Sat Jan 10 06:46:57 1987
--- ip_input.c	Tue Jan 20 22:39:57 1987
***************
*** 1003,1009
  		break;
  	}
  sendicmp:
! 	if (in_broadcast(ip->ip_dst)) {
  		m_freem(dtom(ip));
  		return;
  	}

--- 1003,1010 -----
  		break;
  	}
  sendicmp:
! /* 48 - change in_broadcast to in_any_broadcast */
! 	if (in_any_broadcast(ip->ip_dst)) {
  		m_freem(dtom(ip));
  		return;
  	}
*** tcp_input.c.HOLD	Fri Jan  2 22:09:03 1987
--- tcp_input.c	Tue Jan 20 22:41:08 1987
***************
*** 439,445
  			goto dropwithreset;
  		if ((tiflags & TH_SYN) == 0)
  			goto drop;
! 		if (in_broadcast(ti->ti_dst))
  			goto drop;
  		am = m_get(M_DONTWAIT, MT_SONAME);
  		if (am == NULL)

--- 439,446 -----
  			goto dropwithreset;
  		if ((tiflags & TH_SYN) == 0)
  			goto drop;
! /* 48 - use in_any_broadcast, so we recognize -1, 0, etc. */
! 		if (in_any_broadcast(ti->ti_dst))
  			goto drop;
  		am = m_get(M_DONTWAIT, MT_SONAME);
  		if (am == NULL)
***************
*** 1020,1025
  	 * Make ACK acceptable to originator of segment.
  	 * Don't bother to respond if destination was broadcast.
  	 */
  	if ((tiflags & TH_RST) || in_broadcast(ti->ti_dst))
  		goto drop;
  	if (tiflags & TH_ACK)

--- 1021,1027 -----
  	 * Make ACK acceptable to originator of segment.
  	 * Don't bother to respond if destination was broadcast.
  	 */
+ /* 48 - use in_any_broadcast, to recognize 0 and -1 */
  	if ((tiflags & TH_RST) || in_broadcast(ti->ti_dst))
  		goto drop;
  	if (tiflags & TH_ACK)
*** udp_usrreq.c.HOLD	Fri Jan  2 22:31:21 1987
--- udp_usrreq.c	Tue Jan 20 22:41:51 1987
***************
*** 120,126
  	if (inp == 0) {
  		UNLOCKSEM(&udb.pcb_lock);
  		/* don't send ICMP response for broadcast packet */
! 		if (in_broadcast(ui->ui_dst))
  			goto bad;
  		*(struct ip *)ui = ip;
  		icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT,

--- 120,127 -----
  	if (inp == 0) {
  		UNLOCKSEM(&udb.pcb_lock);
  		/* don't send ICMP response for broadcast packet */
! /* 48 - recognize all broadcast addresses */
! 		if (in_any_broadcast(ui->ui_dst))
  			goto bad;
  		*(struct ip *)ui = ip;
  		icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT,
Technical Details
Message-ID: <8516@topaz.RUTGERS.EDU>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rutgers!topaz!hedrick

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rutgers!topaz!hedrick
From: hedrick@topaz.RUTGERS.EDU (Charles Hedrick)
Newsgroups: comp.bugs.4bsd
Subject: erroneous ICMP error messages in 4.3
Message-ID: <8516@topaz.RUTGERS.EDU>
Date: Tue, 20-Jan-87 23:11:57 EST
Article-I.D.: topaz.8516
Posted: Tue Jan 20 23:11:57 1987
Date-Received: Wed, 21-Jan-87 06:40:57 EST
Organization: Rutgers Univ., New Brunswick, N.J.
Lines: 146