Subject: bug in traceroute mtu-discovery
To: None <gnats-bugs@gnats.netbsd.org>
From: Johan Danielsson <joda@pdc.kth.se>
List: tech-net
Date: 06/15/1999 21:47:28
>Submitter-Id:	net
>Originator:	Johan Danielsson
>Organization:
>Confidential:	no
>Synopsis:	bug in traceroute mtu-discovery
>Severity:	serious
>Priority:	high
>Category:	bin
>Class:		sw-bug
>Release:	<NetBSD-current source date>
>Environment:
	<machine, os, target, libraries (multiple lines)>
System: NetBSD blubb.pdc.kth.se 1.4C NetBSD 1.4C (BLUBB+CARDBUS) #61: Thu Jun 10 11:00:19 PDT 1999 joda@blubb.pdc.kth.se:/usr/misc/src/netbsd/netbsd-current/src/sys/arch/i386/compile/BLUBB+CARDBUS i386


>Description:

I've always wondered why I could only get traceroute -P to work with
some machines. It turns out that traceroute doesn't recalculate the
UDP data length when it gets a EMSGSIZE from sendto, as can be seen in
this tcpdump output:

20:16:14.852654 193.10.159.47.46728 > 130.237.232.119.33438: udp 17886 (DF) [ttl 1]
                         4500 05dc b68c 4000 0111 f1e5 c10a 9f2f
                         82ed e877 b688 829e 45e6 c987 0402 0000
                         7ea6 6637 b0f3 0c00 0000 0000 0000 0000
                         0000 0000 0000 0000 0000 0000 0000 0000
                         0000 0000 0000 0000 0000 0000

The IP-length is 1500 (05DC), but the UDP-length is 17894 (45E6). Some
machines (BSD-based I guess) apparently discards such packets, while
other (Solaris is one example) thinks everything is cool and froody.

Traceroute also doesn't print what MTU it finally managed to use.

>How-To-Repeat:

traceroute -P to any BSD-based machine.

>Fix:

This simple patch makes this work for me, but it
might not be the most elegant solution.

--- traceroute.c	1999/06/06 03:09:59	1.1.1.3
+++ traceroute.c	1999/06/15 19:42:32
@@ -1101,6 +1101,8 @@
 
 			if (errno == EMSGSIZE) {
 				packlen = *mtuptr++;
+		outudp->uh_ulen =
+		    htons((u_short)(packlen - (sizeof(*outip) + optlen)));
 #ifdef _NoLongerLooksUgly_
                 		Printf("\nmessage too big, "
 				    "trying new MTU = %d ", packlen);