[comp.bugs.4bsd.ucb-fixes] V1.37

bostic@OKEEFFE.BERKELEY.EDU.UUCP (09/18/87)

Subject: IP options
Index: sys/netinet/ip_input.c 4.3BSD

Description:
	There are a few oddities in the IP options code in 4.3BSD.  The
	record route option looked up a garbage address and would drop
	the packet if it failed.  The other bug of interest was in the IP
	timestamp handling.  Here is a set of diffs to fix the record
	route bug and several other minor things.

Repeat-By:
	Use a 4.3BSD gateway to forward packets with a record route option.
	Note that the packets are either dropped or have the wrong route
	address.
Fix:
	Apply the following patch.

*** /nbsd/usr/src.4.3/sys/netinet/ip_input.c	Thu Jun  5 00:28:15 1986
--- ip_input.c	Mon Sep 14 14:59:07 1987
***************
*** 5,7 ****
   *
!  *	@(#)ip_input.c	7.1 (Berkeley) 6/5/86
   */
--- 5,7 ----
   *
!  *	@(#)ip_input.c	7.6.1.2 (Berkeley) 9/14/87
   */
***************
*** 302,304 ****
  	if (fp == 0) {
! 		if ((t = m_get(M_WAIT, MT_FTABLE)) == NULL)
  			goto dropfrag;
--- 302,304 ----
  	if (fp == 0) {
! 		if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
  			goto dropfrag;
***************
*** 490,491 ****
--- 490,492 ----
  
+ extern struct in_ifaddr *ifptoia();
  struct in_ifaddr *ip_rtaddr();
***************
*** 595,597 ****
  				break;
! 			bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
  			    sizeof(ipaddr.sin_addr));
--- 596,598 ----
  				break;
! 			bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
  			    sizeof(ipaddr.sin_addr));
***************
*** 602,604 ****
  				type = ICMP_UNREACH;
! 				code = ICMP_UNREACH_SRCFAIL;
  				goto bad;
--- 603,605 ----
  				type = ICMP_UNREACH;
! 				code = ICMP_UNREACH_HOST;
  				goto bad;
***************
*** 620,622 ****
  			}
! 			sin = (struct in_addr *)(cp+cp[IPOPT_OFFSET]-1);
  			switch (ipt->ipt_flg) {
--- 621,623 ----
  			}
! 			sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
  			switch (ipt->ipt_flg) {
***************
*** 630,636 ****
  					goto bad;
! 				if (in_ifaddr == 0)
! 					goto bad;	/* ??? */
! 				bcopy((caddr_t)&IA_SIN(in_ifaddr)->sin_addr,
  				    (caddr_t)sin, sizeof(struct in_addr));
! 				sin++;
  				break;
--- 631,636 ----
  					goto bad;
! 				ia = ifptoia(ifp);
! 				bcopy((caddr_t)&IA_SIN(ia)->sin_addr,
  				    (caddr_t)sin, sizeof(struct in_addr));
! 				ipt->ipt_ptr += sizeof(struct in_addr);
  				break;
***************
*** 638,639 ****
--- 638,642 ----
  			case IPOPT_TS_PRESPEC:
+ 				if (ipt->ipt_ptr + sizeof(n_time) +
+ 				    sizeof(struct in_addr) > ipt->ipt_len)
+ 					goto bad;
  				bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
***************
*** 642,646 ****
  					continue;
- 				if (ipt->ipt_ptr + sizeof(n_time) +
- 				    sizeof(struct in_addr) > ipt->ipt_len)
- 					goto bad;
  				ipt->ipt_ptr += sizeof(struct in_addr);
--- 645,646 ----
***************
*** 652,654 ****
  			ntime = iptime();
! 			bcopy((caddr_t)&ntime, (caddr_t)sin, sizeof(n_time));
  			ipt->ipt_ptr += sizeof(n_time);
--- 652,655 ----
  			ntime = iptime();
! 			bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
! 			    sizeof(n_time));
  			ipt->ipt_ptr += sizeof(n_time);
***************
*** 731,733 ****
  		return ((struct mbuf *)0);
! 	m = m_get(M_WAIT, MT_SOOPTS);
  	m->m_len = ip_nhops * sizeof(struct in_addr) + IPOPT_OFFSET + 1 + 1;
--- 732,736 ----
  		return ((struct mbuf *)0);
! 	m = m_get(M_DONTWAIT, MT_SOOPTS);
! 	if (m == 0)
! 		return ((struct mbuf *)0);
  	m->m_len = ip_nhops * sizeof(struct in_addr) + IPOPT_OFFSET + 1 + 1;
***************
*** 841,843 ****
  	}
! 	if (ip->ip_ttl < IPTTLDEC) {
  		type = ICMP_TIMXCEED, code = ICMP_TIMXCEED_INTRANS;
--- 844,846 ----
  	}
! 	if (ip->ip_ttl <= IPTTLDEC) {
  		type = ICMP_TIMXCEED, code = ICMP_TIMXCEED_INTRANS;
***************
*** 870,873 ****
--- 873,881 ----
  	 * and if packet was not source routed (or has any options).
+ 	 * Also, don't send redirect if forwarding using a default route
+ 	 * or a route modfied by a redirect.
  	 */
+ #define	satosin(sa)	((struct sockaddr_in *)(sa))
  	if (ipforward_rt.ro_rt && ipforward_rt.ro_rt->rt_ifp == ifp &&
+ 	    (ipforward_rt.ro_rt->rt_flags & RTF_DYNAMIC) == 0 &&
+ 	    satosin(&ipforward_rt.ro_rt->rt_dst)->sin_addr.s_addr != 0 &&
  	    ipsendredirects && ip->ip_hl == (sizeof(struct ip) >> 2)) {
***************
*** 874,876 ****
  		struct in_ifaddr *ia;
- 		extern struct in_ifaddr *ifptoia();
  		u_long src = ntohl(ip->ip_src.s_addr);
--- 882,883 ----