traceroute

Updated: April 19, 2023

Print the route packets take to network host

Syntax:

traceroute [-aDdeFInrSvX] [-A as_server] [-f first_ttl] [-g gateway]
           [-i iface] [-M first_ttl] [-m max_ttl] [-P proto]
           [-p port] [-q nqueries] [-s src_addr] [-t tos]
           [-w wait_time] [-z pausemsec] host [packetsize]

Runs on:

QNX Neutrino

Options:

-A as_server
Turn on AS lookups and use the given server instead of the default.
-a
Turn on AS lookups for each hop encountered.
-D
When an ICMP response to our probe datagram is received, print the differences between the transmitted packet and the packet quoted by the ICMP response. A key showing the location of fields within the transmitted packet is printed, followed by the original packet in hex, followed by the quoted packet in hex. Bytes that are unchanged in the quoted packet are shown as underscores. Note that the IP checksum and the TTL of the quoted packet aren't expected to match. By default, only one probe per hop is sent with this option.
-d
Turn on socket-level debugging.
-e
(QNX Neutrino 7.0 or later) Firewall evasion mode. Use fixed destination ports for UDP and TCP probes. The destination port doesn't increment with each packet sent.
-F
Set the “don't fragment” bit.
-f first_ttl
Set the initial time-to-live used in the first outgoing probe packet.
-g gateway
Specify a loose source route gateway (8 maximum).
-I
Use ICMP ECHO instead of UDP datagrams (a synonym for -P icmp).
-i iface
Specify a network interface to obtain the source IP address for outgoing probe packets. This is normally useful only on a multi-homed host. (See -s for an alternative way to do this.)
-M first_ttl
(QNX Neutrino 7.0 or later) Set the initial time-to-live value used in outgoing probe packets. The default is 1, i.e., start with the first hop.
-m max_ttl
Set the maximum TTL (maximum number of hops) used in outgoing probe packets. The default is the value of the net.inet.ip.ttl sysctl (the same default as is used for TCP connections).
-n
Print hop addresses numerically only. By default, addresses are printed both symbolically and numerically. This option saves a nameserver address-to-name lookup for each gateway found on the path.
-P proto
(QNX Neutrino 7.0 or later) Send packets of the specified IP protocol. The currently supported protocols are UDP, TCP, GRE and ICMP. Other protocols may also be specified (either by name or by number), though traceroute doesn't implement any special knowledge of their packet formats. This option is useful for determining which router along a path may be blocking packets based on IP protocol number.
-p port
The base UDP port number to be used in probes (default is 33434). The traceroute utility hopes that nothing is listening on UDP ports base to base + nhops -1 at the destination host (so an ICMP PORT_UNREACHABLE message is returned to terminate the route tracing). If something is listening on a port in the default range, you can use this option to pick an unused port range.
-q nqueries
The number of probes per hop (default is three probes).
-r
Bypass the normal routing tables and send directly to a host on an attached network. If the host isn't on a directly attached network, an error is returned. You can use this option to “ping” a local host through an interface that has no route through it (for example, after the interface was dropped by routed).
-S
(QNX Neutrino 7.0 or later) Print a summary of how many probes weren't answered for each hop.
-s src_addr
Use the specified IP address (which usually is given as an IP number, not a hostname) as the source address in outgoing probe packets. On multi-homed hosts (those with more than one IP address), you can use this option to force the source address to be something other than the IP address of the interface that the probe packet is sent on. If the IP address isn't one of this machine's interface addresses, an error is returned and nothing is sent (see the -i flag for another way to do this).
-t tos
The type-of-service (TOS) to be used in probe packets (default is zero). The value must be a decimal integer in the range 0 to 255. You can use this option to see if different TOSs result in different paths.

Not all TOS values are legal or meaningful. You should find the values -t 16 (low delay) and -t 8 (high throughput) useful.

-v
Be verbose. Received ICMP packets other than TIME_EXCEEDED and UNREACHABLEs are listed.
-w wait_time
The time (in seconds) to wait for a response to a probe (default is 5).
-x
Toggle checksums. Normally, this prevents traceroute from calculating checksums. In some cases, the operating system can overwrite parts of the outgoing packet but not recalculate the checksum (so in some cases the default is to not calculate checksums and using -x causes them to be calculated). Note that checksums are usually required for the last hop when using ICMP ECHO probes (-I).
-z pausemsec
Set the time (in milliseconds) to pause between probes (default 0). Some systems such as Solaris and routers such as Ciscos rate limit ICMP messages. A good value to use with this is 500 (e.g. 1/2 second).
host
The destination hostname or IP number.
packetsize
The probe datagram length (default is 40 bytes).

Description:

The Internet is a large and complex aggregation of network hardware, connected together by gateways. Tracing the route your packets follow—or finding the gateway that's discarding your packets—can be difficult. The traceroute utility uses the IP protocol “time-to-live” field and attempts to elicit an ICMP TIME_EXCEEDED response from each gateway along the path to a host.

This utility attempts to trace the route an IP packet follows to an Internet host, by launching UDP probe packets with a small ttl (time to live) and then listening for an ICMP TIME_EXCEEDED reply from a gateway. Probes are started with a TTL of one and increase by one until an ICMP PORT_UNREACHABLE—which means you got to the host—is encountered or a maximum is reached. By default, this maximum is 30 hops; you can change it with the -m option.

Three probes (you can change the number with the -q option) are sent at each TTL setting and a line is printed showing the TTL, the address of the gateway, and the roundtrip time of each probe. If the answers come from different gateways, the address of each responding system is printed. If there's no response within a 5-second timeout interval (which you can change with the -w option), a * is printed for that probe.

Since the destination host shouldn't process the UDP probe packets, the destination port is set to an unlikely value. If someone on the destination is using that value, you can change it with -p.

Note: This utility needs to have the setuid (“set user ID”) bit set in its permissions. If you use mkefs, mketfs, mkifs, or mkqnx6fs on a Windows host to include this utility in an image, use the perms attribute to specify its permissions explicitly, and the uid and gid attributes to set the ownership correctly.

Here's a sample use and output:

% traceroute nis.nsf.net.
traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms

Note that lines 2 and 3 are the same. This is due to a buggy kernel on the second hop system (lbl-csam.arpa), that forwards packets with a zero TTL (a bug in the distributed version of 4.3 BSD). Note that you have to guess what path the packets are taking cross-country since the NSFNet (129.140) doesn't supply address-to-name translations for its NSSs.

This example is more interesting:

% traceroute allspice.lcs.mit.edu.
traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
12  * * *
13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
14  * * *
15  * * *
16  * * *
17  * * *
18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms

The gateways that are 12, 14, 15, 16, and 17 hops away either don't send ICMP “time exceeded” messages or send the messages with a TTL that's too small to reach you.

Gateways 14 to 17 are running the MIT C Gateway code that doesn't send “time exceeded”s. The silent gateway 12 may be the result of a bug in the 4.[23] BSD network code (and its derivatives): versions 4.3 or earlier send an unreachable message using whatever TTL remains in the original datagram. Since for gateways the remaining TTL is zero, the ICMP time exceeded is guaranteed to not make it back to you. The behavior of this bug is slightly more interesting when it appears on the destination system:

1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
7  * * *
8  * * *
9  * * *
10  * * *
11  * * *
12  * * *
13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !

Notice that there are 12 “gateways” (13 is the final destination) and that exactly the last half of them are missing. What's really happening is that rip (a Sun-3 running Sun OS3.5) is using the TTL from your arriving datagram as the TTL in its ICMP reply. So, the reply timeouts on the return path (with no notice sent to anyone since ICMPs aren't sent for ICMPs) until you probe with a TTL that's at least twice the path length. That is, rip is really only 7 hops away. A reply that returns with a TTL of 1 is a clue that this problem exists.

The traceroute utility prints a ! after the time if the TTL is less than or equal to 1. Since vendors ship a lot of obsolete (DECs Ultrix, Sun3.x) or nonstandard (HPUX) software, expect to see this problem frequently and/or take care when picking the target host of your probes. Other possible annotations after the time are:

!F
Fragmentation needed.
!H
Host unreachable.
!N
Network unreachable.
!N
ICMP unreachable code N.
!P
Protocol unreachable.
!S
Source route failed.
!X
Communication prohibited by the administrator.

Neither !S nor !F should ever occur—the associated gateway is broken if you see one. If almost all the probes result in some kind of unreachable, traceroute gives up and exits.

Intended for use in network testing, measurement, and management, traceroute should be used primarily for manual fault isolation. Because of the load it could impose on the network, you shouldn't use traceroute during normal operations or from automated scripts.

Files:

The traceroute utility requires the libsocket.so shared library.

Contributing author:

Implemented by Van Jacobson from a suggestion by Steve Deering. Debugged by others with suggestions and fixes from C. Philip Wood, Tim Seaver, and Ken Adelman.