[comp.protocols.tcp-ip] IP options...

jgh@root.co.uk (Jeremy G Harris) (09/08/87)

Are there any known problems in the 4.3 code dealing with IP options?
I can't understand it....

Specifically, in routine ip_dooptoptions, file ip_input.c:

1) Strict source route with record
    appears to record an address for the receiving
    interface rather than the transmitting one.
2) Record route
    appears to route the datagram based on a garbage address,
    bouncing an ICMP "source route failed" if this fails   or
    recording an address for the bogus transmitting interface
    if it succeeds.


Are these bugs or have I missed something?
Has anybody fixed them?
Does anybody use IP options anyway?
Do I have an out-of-date RFC?


Thanks in antici... . .  . pation,
Jeremy


Reference: RFC 791: IP protocol spec.  Sept '81   pp. 20,21
		"... address as known in the environment into which
		     this datagram is being forwarded"

                   (identical wording in two places)

-- 
Jeremy Harris			jgh@root.co.uk

karels%okeeffe@UCBVAX.BERKELEY.EDU (Mike Karels) (09/09/87)

As a matter of fact, there are a few oddities in the IP options code
in 4.3.  Of the two you mentioned, one is a bug (record route used
a garbage address which coincidentally works on machines with default
routes).  You appear to have misunderstood the code for source route,
though; look for the call to ip_rtaddr, which locates the outgoing
interface address.  The other bug of any interest was in IP timestamp
handling.  Here is a set of diffs to fix the record route bug and
several other minor things.

		Mike

*** /nbsd/usr/src/sys/netinet/ip_input.c	Thu Jun  5 00:28:15 1986
--- ./ip_input.c	Wed Sep  9 11:33:47 1987
***************
*** 5,7 ****
   *
!  *	@(#)ip_input.c	7.1 (Berkeley) 6/5/86
   */
--- 5,7 ----
   *
!  *	@(#)ip_input.c	7.6.1.1 (Berkeley) 9/9/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|RTF_MODIFIED)) == 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 ----

zwang@CS.UCL.AC.UK (Zheng Wang) (09/12/87)

What will happen if a packet with a source route option goes through 
a unix 4.2 gateway ?  Will the gateway strip the option out after
updating ?

Zheng.
zwang@uk.ac.ucl.cc

vjs@sgi.UUCP (09/13/87)

In article <8709092006.AA09597@okeeffe.Berkeley.EDU>, karels%okeeffe@UCBVAX.BERKELEY.EDU (Mike Karels) writes:

> + 	 * 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|RTF_MODIFIED)) == 0 &&
> + 	    satosin(&ipforward_rt.ro_rt->rt_dst)->sin_addr.s_addr != 0 &&
>   	    ipsendredirects && ip->ip_hl == (sizeof(struct ip) >> 2)) {

I have been faithfully following the 4.3 fixes posted here and in the
'official' news group.  However, RTF_MODIFIED does not seem to be
defined in my source.  If I have missed something, would someone 
please give me a pointer to it?  Else, might there be fixes pending to
#define it and to set it?

Thank you
Vernon Schryver
Silicon Graphics, Inc
vjs@sgi.com   or   {decwrl,pyramid,sun,ucbvax,allegra}!sgi!vjs

karels%okeeffe@UCBVAX.BERKELEY.EDU (Mike Karels) (09/15/87)

Oops.  I created a special version of the ip_input.c file with the fixes
I wanted to send but without post-4.3 changes that wouldn't work with
everyone else's system, but I missed one change (RTF_MODIFIED wasn't
in 4.3).  For those who have been trying to install the change I sent
out last week, here it is again in a form that should work with 4.3.

		Mike

*** /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 ----

loverso@encore.UUCP (John LoVerso) (09/17/87)

In article <6211@sgi.SGI.COM> vjs@rhyolite.SGI.COM (Vernon Schryver) writes:
> I have been faithfully following the 4.3 fixes posted here and in the
> 'official' news group.  However, RTF_MODIFIED does not seem to be
> defined in my source.

To my knowledge, they've never been released outside of Berkeley other
than in the Tahoe-Beta release of 4.3BSD.  In there, RTF_MODIFIED is
defined to mean the route came in via a redirect.  Here are the
diffs to net/route.[ch].  With all the various versions of the 4.3 TCP/IP
code I've seen, this is just about all that I've ever seen changed in net/.
BTW, I'm only posting this since I haven't seen a reply from Mike Karels yet,
and without this, his ip_input.c changes aren't much good.

John

*** /source/BSD4.3/sys/net/route.h	Thu Jun  5 02:43:05 1986
--- route.h	Thu Jan 15 18:09:44 1987
***************
*** 4,8 ****
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)route.h	7.1 (Berkeley) 6/4/86
   */
  
--- 4,8 ----
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)route.h	7.2 (Berkeley) 1/15/87
   */
  
***************
*** 46,49 ****
--- 46,50 ----
  #define	RTF_HOST	0x4		/* host entry (net otherwise) */
  #define	RTF_DYNAMIC	0x10		/* created dynamically (by redirect) */
+ #define	RTF_MODIFIED	0x20		/* modified dynamically (by redirect) */
  
  /*
*** /source/BSD4.3/sys/net/route.c	Thu Jun  5 02:42:47 1986
--- route.c	Thu Jan 15 18:09:44 1987
***************
*** 4,8 ****
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)route.c	7.1 (Berkeley) 6/4/86
   */
  
--- 4,8 ----
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)route.c	7.2 (Berkeley) 1/15/87
   */
  
***************
*** 176,181 ****
  			 */
  			rt->rt_gateway = *gateway;
  		}
- 		rtstat.rts_newgateway++;
  	} else
  		rtstat.rts_badredirect++;
--- 176,182 ----
  			 */
  			rt->rt_gateway = *gateway;
+ 			rt->rt_flags |= RTF_MODIFIED;
+ 			rtstat.rts_newgateway++;
  		}
  	} else
  		rtstat.rts_badredirect++;

philipp@CLOUSO.CRIM.CA ("Philip A. Prindeville") (04/25/89)

I remember hearing on this list several months ago a discussion
about the semantics of interpreting loose/strict source and
record route options, and a possible document that was to come
of this.  Does anyone have a pointer to said document?
(As I remember, it was precipitated because a few implementa-
tions didn't do The Right Thing.)

Also, I was wondering if certain IP options are implicitly
(ie. the RFC doesn't explicitly say) mutually-exclusive,
such as loose and strict source and record routing, or
timestamping and record routes...  Actually it would seem
silly to have more than one of these in a packet.  Is it
an error to have more than one of these?

Lastly (for now), if one has a timestamp area that isn't
a multiple of 4 (or 8) bytes long, and the overflow field
overflows, should the Parameter Error message point to the
length or overflow field?

Please reply directly.

Thanks,

-Philip

pprindev@wellflt.UUCP (Philip Prindeville) (05/20/89)

I remember some discussion about a set of tools for network
diagnostics that included the ability to specify (in symbolic
form) sets of options from the command level.  VJ comes to
mind, as does the name "traceroute".  Can someone send me
some pointers on how to find this (where to ftp it from)?

Thanks,

-Philip