Print the route packets take to network host
traceroute [ -DFPI ] [ -f first_ttl ] [ -g gateway ] [ -i iface ] [-l] [-m max_ttl] [-n] [-p port] [-q nqueries] [-r] [-s src_addr] [-t tos] [-v] [-s src_addr] [-t tos] [-v] [-w wait_time] [-x] host [packetsize]
Not all TOS values are legal or meaningful. You should find the values -t 16 (low delay) and -t 8 (high throughput) useful.
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.
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:
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.
The traceroute utility requires the libsocket.so shared library.
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.