Analyzing Traceroute with Packet Captures on Linux and Windows
Introduction
Traceroute probes each Router in the path to the target IP address by making every Router in the path reply with a ICMP Time Exceeded (Type 11) – time to live exceeded intransit (Code 0) as the time-to-leave (TTL field in the IP header) expires in transit.
- On Linux, traceroute makes use of UDP datagrams with Destination ranging from port 33434 to 33534
- The Linux implementation the Traceroute knows it has finally reached the target IP by receiving an ICMP Destination Unreachable (Type 3) – PortUnreachable packet (Code 3)
- On Windows, traceroute makes use of ICMP echo request (Type 8 – Code 0) to accomplish this
- On Windows implementation the Traceroute knows it has finally reached the target IP by receiving an **ICMP echo reply (Type 0 – Code 0)implementation the Traceroute knows it has finally reached the target IP by receiving an
To see the ICMP Type and Code numbers, refer to RFC792 - INTERNET CONTROL MESSAGE PROTOCOL
Testbed
- VM running Linux Ubuntu 21.04 Hirsute Hippo
- VM running Windows 10 Enterprise
ICMP messages relevant to Traceroute
- ICMP Time Exceeded (Type 11) – time to live exceeded in transit (Code 0)
- ICMP Destination Unreachable (Type 3) – Port Unreachable packet (Code 3)
- ICMP echo request (Type 8 – Code 0)
- ICMP echo reply (Type 0 – Code 0)
Linux traceroute
Linux implementation of Traceroute receiving ICMP TTL exceeded in transit message from every Router in the path |
Linux implementation of Traceroute receiving ICMP Port Unreachable message from the last node in the path |
First, let’s see the available parameters the traceroute utility has on my Linux Ubuntu. My Ubuntu fresh install was very explicit about indicating me I needed to perform sudo apt install traceroute
to get it installed.
It seems you can get two different versions of the traceroute binary in Linux.
1
2
3
4
5
user@ubuntuVM01:~$ traceroute
Command 'traceroute' not found, but can be installed with:
sudo apt install inetutils-traceroute # version 2:2.4-3ubuntu1, or
sudo apt install traceroute # version 1:2.1.5-1
user@ubuntuVM01:~$
apt install traceroute
traceroute
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
user@ubuntuVM01:~$ traceroute
Usage:
traceroute [ -46dFITnreAUDV ] [ -f first_ttl ] [ -g gate,... ] [ -i device ] [ -m max_ttl ] [ -N squeries ] [ -p port ] [ -t tos ] [ -l flow_label ] [ -w MAX,HERE,NEAR ] [ -q nqueries ] [ -s src_addr ] [ -z sendwait ] [ --fwmark=num ] host [ packetlen ]
Options:
-4 Use IPv4
-6 Use IPv6
-d --debug Enable socket level debugging
-F --dont-fragment Do not fragment packets
-f first_ttl --first=first_ttl
Start from the first_ttl hop (instead from 1)
-g gate,... --gateway=gate,...
Route packets through the specified gateway
(maximum 8 for IPv4 and 127 for IPv6)
-I --icmp Use ICMP ECHO for tracerouting
-T --tcp Use TCP SYN for tracerouting (default port is 80)
-i device --interface=device
Specify a network interface to operate with
-m max_ttl --max-hops=max_ttl
Set the max number of hops (max TTL to be
reached). Default is 30
-N squeries --sim-queries=squeries
Set the number of probes to be tried
simultaneously (default is 16)
-n Do not resolve IP addresses to their domain names
-p port --port=port Set the destination port to use. It is either
initial udp port value for "default" method
(incremented by each probe, default is 33434), or
initial seq for "icmp" (incremented as well,
default from 1), or some constant destination
port for other methods (with default of 80 for
"tcp", 53 for "udp", etc.)
-t tos --tos=tos Set the TOS (IPv4 type of service) or TC (IPv6
traffic class) value for outgoing packets
-l flow_label --flowlabel=flow_label
Use specified flow_label for IPv6 packets
-w MAX,HERE,NEAR --wait=MAX,HERE,NEAR
Wait for a probe no more than HERE (default 3)
times longer than a response from the same hop,
or no more than NEAR (default 10) times than some
next hop, or MAX (default 5.0) seconds (float
point values allowed too)
-q nqueries --queries=nqueries
Set the number of probes per each hop. Default is
3
-r Bypass the normal routing and send directly to a
host on an attached network
-s src_addr --source=src_addr
Use source src_addr for outgoing packets
-z sendwait --sendwait=sendwait
Minimal time interval between probes (default 0).
If the value is more than 10, then it specifies a
number in milliseconds, else it is a number of
seconds (float point values allowed too)
-e --extensions Show ICMP extensions (if present), including MPLS
-A --as-path-lookups Perform AS path lookups in routing registries and
print results directly after the corresponding
addresses
-M name --module=name Use specified module (either builtin or external)
for traceroute operations. Most methods have
their shortcuts (`-I' means `-M icmp' etc.)
-O OPTS,... --options=OPTS,...
Use module-specific option OPTS for the
traceroute module. Several OPTS allowed,
separated by comma. If OPTS is "help", print info
about available options
--sport=num Use source port num for outgoing packets. Implies
`-N 1'
--fwmark=num Set firewall mark for outgoing packets
-U --udp Use UDP to particular port for tracerouting
(instead of increasing the port per each probe),
default port is 53
-UL Use UDPLITE for tracerouting (default dest port
is 53)
-D --dccp Use DCCP Request for tracerouting (default port
is 33434)
-P prot --protocol=prot Use raw packet of protocol prot for tracerouting
--mtu Discover MTU along the path being traced. Implies
`-F -N 1'
--back Guess the number of hops in the backward path and
print if it differs
-V --version Print version info and exit
--help Read this help and exit
Arguments:
+ host The host to traceroute to
packetlen The full packet length (default is the length of an IP
header plus 40). Can be ignored or increased to a minimal
allowed value
user@ubuntuVM01:~$
apt install inetutils-traceroute
inetutils-traceroute
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
user@ubuntuVM01:~$ traceroute
traceroute: missing host operand
Try 'traceroute --help' or 'traceroute --usage' for more information.
user@ubuntuVM01:~$
user@ubuntuVM01:~$ traceroute --usage
Usage: traceroute [-I?V] [-f NUM] [-g GATES] [-m NUM] [-M METHOD] [-p PORT]
[-q NUM] [-t NUM] [-w NUM] [--first-hop=NUM] [--gateways=GATES]
[--icmp] [--max-hop=NUM] [--type=METHOD] [--port=PORT]
[--tries=NUM] [--resolve-hostnames] [--tos=NUM] [--wait=NUM]
[--help] [--usage] [--version] HOST
user@ubuntuVM01:~$
user@ubuntuVM01:~$ traceroute --help
Usage: traceroute [OPTION...] HOST
Print the route packets trace to network host.
-f, --first-hop=NUM set initial hop distance, i.e., time-to-live
-g, --gateways=GATES list of gateways for loose source routing
-I, --icmp use ICMP ECHO as probe
-m, --max-hop=NUM set maximal hop count (default: 64)
-M, --type=METHOD use METHOD (`icmp' or `udp') for traceroute
operations, defaulting to `udp'
-p, --port=PORT use destination PORT port (default: 33434)
-q, --tries=NUM send NUM probe packets per hop (default: 3)
--resolve-hostnames resolve hostnames
-t, --tos=NUM set type of service (TOS) to NUM
-w, --wait=NUM wait NUM seconds for response (default: 3)
-?, --help give this help list
--usage give a short usage message
-V, --version print program version
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
Report bugs to <bug-inetutils@gnu.org>.
user@ubuntuVM01:~$
I will be using the first traceroute
binary, the one which was installed with apt install traceroute
.
While preparing the screenshots for this post, I quickly noticed I should perform the traceroute command adding some of the optional parameters
-n
makes the traceroute always show the IP address of all Routers as opposed to the domain namez 1
adds delay to the probes so the Wireshark capture can show the packets in the correct order-q 1
sends a single probe instead of the three ones per hop which is the default
The traceroute is to to destination 8.8.8.8 which is a well known DNS server provided by Google and a common way to confirm Internet IP connectivity is working.
Going to the Wireshark capture I have running in parallel to the traceroute
exeuction above, I have used the following filter in Wireshark to avoid other packets to disturb the flow fo the traffic created by the traceroute
command. Doing this the capture looks “cleaner” in the screenshot.
1
((udp.port >= 33434 and udp.port <= 33534) or (icmp)) and ip.ttl < 10
We clearly see from the Wireshark capture that we are sending UDP datagrams from this Linux machine with private IP address of 192.168.0.234 to the destination IP on the traceroute of 8.8.8.8
Focusing on the very first entry in the traceroute command (partial output below)
1
2
3
user@ubuntuVM01:~$ traceroute 8.8.8.8 -n -z 1 -q 1
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
1 192.168.0.1 4.269 ms
We see the UDP packet with TTL = 1 in the IP header and the UDP Destination Port of 33434
Next packet is an expected ICMP Time Exceeded (Type 11) – time to live exceeded in transit (Code 0) as observed in the below packet capture. This is an indication to the traceroute utility that we should add the IP Source to our traceroute output
The process repeats itself by increasing the TTL by 1 (and the UDP Destination Port as well). I added an additional column on the Wireshark capture to clearly see this behavior
Interesting enough, looking at the 7th time the traceroute sends a probe, we see it does not receive an yresponse as appreciated in the Wireshark capture above. This can be correlated with the 7th entr yin the traceroute, which is missing only showing an *
1
2
3
4
5
6
7
8
9
10
11
user@ubuntuVM01:~$ traceroute 8.8.8.8 -n -z 1 -q 1
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
1 192.168.0.1 4.269 ms
2 84.116.254.140 17.070 ms
3 84.116.253.129 20.324 ms
4 84.116.133.29 21.067 ms
5 84.116.138.73 22.080 ms
6 72.14.203.234 20.972 ms
7 *
8 8.8.8.8 24.669 ms
user@ubuntuVM01:~$
Finally, the ICMP Destination Unreachable (Type 3) – Port Unreachable packet (Code 3) is letting traceroute
know it has reached the target IP. This method makes sense as there may be some mechanisms in the network like NAT (Network Address Translations) that may blur the path to the target IP.
Windows traceroute
Windows implementation of Traceroute receiving ICMP TTL exceeded in transit message from every Router in the path |
Windows implementation of Traceroute receiving ICMP echp reply message from the lastnode in the path |
In a similar way, let’s first look at the traceroute parameters available on the Windows platform. We must call the binary tracert
as opposed to traceroute
…
1
2
3
4
5
C:\Users\user>traceroute
'traceroute' is not recognized as an internal or external command,
operable program or batch file.
C:\Users\user>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
C:\Users\user>tracert
Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout]
[-R] [-S srcaddr] [-4] [-6] target_name
Options:
-d Do not resolve addresses to hostnames.
-h maximum_hops Maximum number of hops to search for target.
-j host-list Loose source route along host-list (IPv4-only).
-w timeout Wait timeout milliseconds for each reply.
-R Trace round-trip path (IPv6-only).
-S srcaddr Source address to use (IPv6-only).
-4 Force using IPv4.
-6 Force using IPv6.
C:\Users\user>
There is no parameter on the Windows traceroute command to send only a single probe, but I included the -d
parameter to make traceroute always show the IP address of all Routers in the path as opposed to the domain name
1
>tracert -d 8.8.8.8
In this case, we see from the Wireshark capture that we are sending ICMP echo requests from the Windows machine with source IP address 192.168.0.24 to the destination IP 8.8.8.8
In this case the filter used in Wireshark is simply:
1
icmp
The very first entry in the traceroute command (partial output below) shows 3 probes sent with TTL = 1 which were replied by 192.168.0.1
1
2
3
4
5
C:\Users\hecserra>tracert -d 8.8.8.8
Tracing route to 8.8.8.8 over a maximum of 30 hops
1 4 ms 3 ms 4 ms 192.168.0.1
...
1
2
3
4
5
6
7
8
9
10
11
12
C:\Users\hecserra>tracert -d 8.8.8.8
Tracing route to 8.8.8.8 over a maximum of 30 hops
1 4 ms 3 ms 4 ms 192.168.0.1
2 15 ms 18 ms 17 ms 84.116.254.140
3 19 ms 27 ms 22 ms 84.116.253.129
4 21 ms 20 ms 21 ms 84.116.133.29
5 20 ms 19 ms 24 ms 84.116.138.73
6 21 ms 23 ms 20 ms 72.14.203.234
7 29 ms 24 ms 25 ms 142.250.227.17
8 28 ms 20 ms 20 ms 209.85.252.117
9 26 ms 27 ms 28 ms 8.8.8.8
Trace complete.
We can see in the following screenshot the ICMP echo request (Type 8 – Code 0) generated by Windows and initiating the traceroute
In the next screenshot, we the ICMP Time Exceeded (Type 11) – time to live exceeded in transit (Code 0) generate by the nodes in the path
Lastly, in Windows, the traceroute completes when receiving ICMP echo reply (Type 0 – Code 0) from the destionation. This behavior differs from Linux.