Subject: bin/2701: traceroute may never time out
To: None <gnats-bugs@NetBSD.ORG>
From: Havard Eidnes <he@runit.sintef.no>
List: netbsd-bugs
Date: 08/16/1996 14:10:34
>Number: 2701
>Category: bin
>Synopsis: traceroute may never time out
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Aug 16 08:35:02 1996
>Last-Modified:
>Originator: Havard Eidnes
>Organization:
SINTEF RUNIT
>Release: 1.1
>Environment:
i386, NetBSD 1.1
System: NetBSD vader.runit.sintef.no 1.1 NetBSD 1.1 (VADER) #1: Mon Jan 15 20:46:37 MET 1996 root@vader.runit.sintef.no:/usr/src/sys/arch/i386/compile/VADER i386
>Description:
Since a raw IP socket will receive all ICMP messages addressed
to a host, traceroute may never time out and proceed if a probe
packet or a response to a probe packet is lost and there is other
ICMP traffic to the host running traceroute.
Verbose print of packets returns bogus data because inet_ntoa()
returns it's value in a static area, and it's used twice in a
call to Printf().
>How-To-Repeat:
Start a continous ping to any other host. Run traceroute over
a path where some packet loss can be expected. Observe traceroute
hanging when there is a packet loss.
Turn on -v and see that the source and dest are the same in the
extra ICMP packets captured and displayed.
>Fix:
The termination condition in traceroute for giving a timeout is too
simplistic, work around this.
The offending Printf() needs to be split in two.
*** traceroute.c 1996/08/13 14:11:27 1.1
--- traceroute.c 1996/08/16 11:57:03
***************
*** 494,497 ****
--- 494,506 ----
while (cc = wait_for_reply(s, &from)) {
(void) gettimeofday(&t2, &tz);
+ /* Since we'll be receiving all ICMP
+ messages to this host above, we may
+ never end up with cc=0, so we need
+ an additional termination check. */
+ if (t2.tv_sec - t1.tv_sec > waittime) {
+ Printf(" *");
+ (void) fflush(stdout);
+ break;
+ }
if ((i = packet_ok(packet, cc, &from, seq))) {
if (from.sin_addr.s_addr != lastaddr) {
***************
*** 697,702 ****
u_long *lp = (u_long *)&icp->icmp_ip;
! Printf("\n%d bytes from %s to %s", cc,
! inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst));
Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
icp->icmp_code);
--- 706,711 ----
u_long *lp = (u_long *)&icp->icmp_ip;
! Printf("\n%d bytes from %s ", cc, inet_ntoa(from->sin_addr));
! Printf("to %s", inet_ntoa(ip->ip_dst));
Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
icp->icmp_code);
>Audit-Trail:
>Unformatted: