ICMP, UDP, TCP and IP. Oh my!
Traceroutes work by manipulating a field in an IP packet called Time-To-Live. Despite sounding a bit like a James Bond film title, the time to live field simply tells the device a packet is passing through how many more systems (or hops) a packet can pass through before being dropped. This is to ensure that packets don't just simply run around the Internet forever clogging it up.
The Time-To-Live (also referred to as TTL) field is decremented as it passes through each network hop. When it reaches zero, a router will drop the packet being sent through it and send an ICMP Time-To-Live exceeded message back to the source.
We can (ab)use this in order to determine both the route to a particular host or network and the time it takes for a message to be sent and a response to be received by using a traceroute implementation. There are two main forms of traceroute, an ICMP traceroute used by Windows, and the UDP traceroute used pretty much everywhere else. If you were hoping for a nice clean set of standards, the water here is as clear as SNMP is simple (i.e. not very once you look under the hood).
ICMP (Windows) Traceroute
Let's assume that Alice wants to send a traceroute to Bob. She fires up the Windows tracert.exe to do the job. Alice sends 3 ICMP echo (type 8) messages to Bob, each with a TTL of one. When the packet hits the first router, the TTL will decrement to 0 and the first router will drop the packet and send an ICMP Time-To-Live exceeded message (ICMP Type 11) back to Alice. This tells the tracert program that Bob's system hasn't yet been reached, and that the traceroute process needs to continue. Alice knows when the message was sent, so by comparing the time at the point the original ICMP message was sent, and when the TTL exceeded message was received, Alice can calculate the Round-Trip-Time (RTT) between her computer and the router.
Alice then sends 3 ICMP echo messages to Bob with a TTL of two. The packet passes through the first router and the TTL is decremented to one. The packet is then passed to the second router where the TTL is decremented and it duly expires. The router on the second hop sends an ICMP TTL Exceeded message to Alice, who calculates the RTT.
Alice then sends packets with TTL of 3, and the cycle continues until either an ICMP echo reply message is received from Bob's computer, or the maximum number of hops have been reached (30 by default on Windows systems). The maximum number of hops is set with the ``-h`` flag.
As well as the windows tracert.exe, we can also conduct a Windows-style ICMP traceroute using the traceroute command used in most Unix-like operating systems. While it's best to check the man page, in most cases the -I switch is used to specify ICMP. The screenshot below shows an example ICMP traceroute.
An ICMP traceroute from an OSX system to a Linux system
So far, so good, but there's a problem. Because Alice sends ICMP Echo request messages to Bob, all of the intermediary routers are expected to respond with an ICMP TTL Exceeded message. The problem is that the RFC responsible for ICMP (RFC 792) very specifically points out that systems shouldn't send ICMP error messages in response to ICMP packets. On page 1 it says:
To avoid the infinite regress of messages about messages etc., no ICMP messages are sent about ICMP messages.In the early days of the Internet this meant that a lot of routers wouldn't send the TTL exceeded messages. So a workaround was found, by a man named Van Jacobson.
Jacobson's plan was simple. Instead of sending 3 ICMP messages he'd send 3 UDP datagrams. That way any intermediary device could send an ICMP error message if the TTL expired without breaking RFC 792. The only problem was that being a stateless protocol, if a blank UDP datagram was sent to a target system and reached it, there's a high likelihood that the target host wouldn't respond and that the program might think the traceroute hasn't finished, so the traceroute tool would just keep going until it reaches it's maximum hop count. [caption id="attachment_219" align="aligncenter" width="619"]![A UDP traceroute encounters host-based filtering at the final hop.](images/udp-traceroute.png)
A UDP traceroute encounters host-based filtering at the final hop.
To solve this, Van Jacobson looked at the IANA ports list, and noticed that ports 33434-33534 weren't assigned to anything. He opted for those ports and the rest was history, except for those of us who use host based firewalls. For that, we have something else.
UDP traceroute was great except in situations where filtering was in place. Because all traceroutes ultimately work using ICMP TTL Exceeded messages, it doesn't really matter what protocol's used above IP as long as we know how it will react once the packet reaches the actual host. The most common of these other types of traceroute is a TCP traceroute.
A TCP traceroute is exactly the same as any other classic traceroute except that a TCP packet is used instead of UDP or ICMP. Typically this will be a TCP packet with a SYN flag set, and it's normal to use commonly open ports such as 25, 80 or 443 but any combination of flags or ports can be used providing that you can get a reliable response back once the target is reached.
A TCP Traceroute using hping3
Because TCP ports tend to be forwarded when behind firewalls, TCP traceroutes are sometimes very useful for mapping out DMZ and even internal networks by counting the extra hops to the final target, whereas ICMP traceroutes tend to go just to the Internet-facing IP address.
Join our newsletter
Subscribe now and get our latest blog posts, videos, tips and tricks every Thursday.