How does traceroute work?
Lately I’ve been reading Interconnections by Radia Perlman (great lastname!). It’s an old, but still relevant book which describes how low-level networking technologies work, such as ethernet. The book contains many insights and anecdotes. On page 236 I came across this gem:
The traceroute utility is a clever hack designed to force each router along the path, in turn, to return an error report. It works by setting the TTL first to 1 (causing the first router to send an error report back to the source) and then setting it to 2 (causing the next router to send an error report) and so forth until the packet reaches the destination.
I had never considered how
traceroute worked before, and by reading that paragraph, I instantly understood. The Time To Live (TTL) field in an IP header was intended to hold the number of seconds for which the IP packet is valid, after which it can be dropped. In practice, it is used as a decrementing hop count, whereby every router that forwards the packet reduces the TTL value by one. IPv6 packets have the “hop limit” header field which is better named and serves the same purpose.
When a router decrements a packet’s hop count value to zero, it sends an ICMP time exceeded error message back to the source IP address in the packet, otherwise it forwards the packet onward.
Modern versions of the
traceroute program don’t just send one packet at a time though. To speed things up it sends several packets with varying hop counts at once, so the program doesn’t have to wait for each router to respond before issuing the next packet.
Do protocols matter?
traceroute program installed on my computer sends UDP datagrams by default, but can also be configured to send TCP or ICMP messages instead. All of these rely on the same principle of setting the hop count to a small number, and awaiting an ICMP time exceeded error message.
However some routers may block certain ports by firewall, hence using TCP on port 80, an ICMP echo request (ping) or UDP on port 53 (DNS) might be more likely to succeed than a UDP datagram on a random unused port.
Traceroute with Perl
The module Net::Traceroute::PurePerl implements the traceroute functionality in Perl. I installed the module from CPAN and ran it on the Perl.com domain using this one liner:
$ sudo $(which perl) -MNet::Traceroute::PurePerl -wE \ 'my $n=Net::Traceroute::PurePerl->new(host=>"perl.com");$n->traceroute();$n->pretty_print'
Because the script opens a raw socket, it needed to be run with root privileges. I use a locally-managed perl, so the subcommand
$(which perl) ensured my local perl was run instead of the system one. This is the output I got:
traceroute to perl.com (18.104.22.168), 30 hops max, 40 byte packets 1 192.168.1.1 1.98 ms 2.02 ms 1.96 ms 2 * * * 3 22.214.171.124 14.25 ms 15.03 ms 15.43 ms 4 126.96.36.199 21.36 ms 16.54 ms 16.77 ms 5 188.8.131.52 21.44 ms 5 184.108.40.206 21.68 ms 10.39 ms 6 220.127.116.11 12.58 ms 15.19 ms 14.55 ms 7 18.104.22.168 16.93 ms 13.88 ms 20.49 ms 8 22.214.171.124 14.68 ms 18.87 ms 13.28 ms 9 126.96.36.199 12.37 ms 9 188.8.131.52 19.20 ms 18.18 ms 10 184.108.40.206 32.09 ms 10 220.127.116.11 14.15 ms 10 18.104.22.168 14.30 ms 11 22.214.171.124 30.80 ms 11 126.96.36.199 30.87 ms 11 188.8.131.52 33.32 ms 12 184.108.40.206 42.33 ms 44.74 ms 12 220.127.116.11 41.91 ms 13 18.104.22.168 62.53 ms 13 22.214.171.124 60.21 ms 60.57 ms 14 126.96.36.199 72.04 ms 71.75 ms 14 188.8.131.52 70.90 ms 15 184.108.40.206 81.26 ms 81.30 ms 90.29 ms 16 220.127.116.11 80.39 ms 16 18.104.22.168 82.34 ms 83.04 ms 17 22.214.171.124 83.23 ms 91.67 ms 82.39 ms 18 126.96.36.199 83.17 ms 72.52 ms 77.83 ms
The first entry is my wifi router. I’m guessing the second is my modem, which did not respond (hence the asterisks). You can see the succession of IP addresses for each router (technically, interface) that responded to the packets. The 18th entry is the last hop because Perl.com (188.8.131.52) sits on the same network (184.108.40.206/18).
Net::Traceroute::PurePerl currently lacks IPv6 support, and hasn’t been updated in a while. The documentation lists IPv6 as a todo item, so if you’re interested in traceroute programming, this might be a good opportunity to send a patch. If the author doesn’t respond, you can always fork the distribution!
Something wrong with this article? Help us out by opening an issue or pull request on GitHub