avatarTony

Summary

The provided web content offers an in-depth explanation of the traceroute command in Linux, detailing its purpose, functionality, execution flow, and practical usage, along with a demonstration and common options, complemented by a simple Python implementation.

Abstract

Traceroute is a command-line utility used across various operating systems to display the network route and measure the transit times across network paths for a packet to reach a target host. The command functions by sending packets with a TTL (Time to Live) value that increments with each hop, allowing it to trace the path taken by packets through the network. The web content explains the mechanics of how traceroute works, including how it handles TTL values, calculates latency, and interprets the results. It also provides a visual representation of the traceroute process, a real-world example showing the output of a traceroute command to google.com, and discusses scenarios where routers might not respond to traceroute requests. Additionally, the content lists common command-line options for customizing traceroute behavior, such as specifying IP version, setting the destination port, and limiting the number of hops. To illustrate the concept, a basic Python script is included to demonstrate how one might implement a simplified version of traceroute.

Opinions

  • The article implies that traceroute is an essential tool for network diagnostics, providing insights into network paths and potential bottlenecks.
  • It suggests that the TTL field in the IP packet header, though not originally intended for path tracing, is cleverly utilized by traceroute to map out the route to a destination.
  • The inclusion of a Python implementation indicates that the concepts behind traceroute can be understood and replicated by those with programming knowledge, emphasizing the educational value of such an exercise.
  • The mention of organizations blocking traceroute packets hints at a potential challenge when using the tool, acknowledging that not all network paths are equally transparent or accessible.
  • By providing examples of common options, the content encourages users to explore and utilize traceroute more effectively, catering to their specific needs and network environments.

DevOps in Linux — Traceroute

Traceroute command introduction

What is traceroute

traceroute is a widely used command-line utility available in almost all operating systems. It shows you the complete route to a destination address. It also shows the time is taken (or delays) between intermediate routers and prints the route that a packet takes to reach the host.

traceroute is super useful when you want to know about the route and about all the hops that a packet takes. The following diagram is an example of traceroute execution flow:

Pic from layerstack.com

How traceroute works

traceroute uses the TCP/IP suite of protocols, and sends User Datagram Protocol packets. It leverages a field in Internet Protocol (IP) packet headers that was never really intended for path or route tracing. The header contains the Time to Live (TTL) field, which contains an eight-bit integer value.

Pic from alexanderell.is

This is how it works:

  • User invokes the traceroute command and specifies a target host. If the host is specified in the form of a domain name, traceroute will attempt to resolve it.
  • traceroute then sends a data packet towards the target with the TTL value set to “1” (By default Windows tracert uses ICMP and Linux traceroute use UDP). The first router in the path will decrement the value by 1, which should trigger a TTL exceeded message that gets sent back to the host on which the traceroute program is running.
  • traceroute then increases the TTL value to “2”. That first router in the path will still decrement the value by 1, but because the TTL will no longer drop to zero right out of the gate the packet can live on for one more hop. Once the TTL value does hit zero (in this case, at the second router in the path), another TTL exceeded message should be generated and passed back to traceroute.
  • This process repeats itself, with traceroute increasing the TTL by 1 each time, until the destination is reached or an upper limit of hops (default 30) is hit.
  • When finished, traceroute prints all the hops in the path, along with the amount of time it took to each hop and back (this is known as the Round Trip Time).

The way how traceroute latency is calculated:

  • It timestamps the probe packet when sent
  • It timestamp the ICMP response when received
  • It then calculate the difference to determine round-trip time.

traceroute Demo

An example of traceroute run to google.com looks like:

$ traceroute google.com
traceroute to google.com (172.217.23.14), 30 hops max, 60 byte packets
 1  10.8.8.1 (10.8.8.1)  14.499 ms  15.335 ms  15.956 ms
 2  h37-220-13-49.host.redstation.co.uk (37.220.13.49)  17.811 ms  18.669 ms  19.346 ms
 3  92.zone.2.c.dc9.redstation.co.uk (185.20.96.137)  19.096 ms  19.757 ms  20.892 ms
 4  203.lc3.redstation.co.uk (185.5.3.221)  28.160 ms  28.415 ms  28.665 ms
 5  100.core1.the.as20860.net (62.128.218.33)  26.739 ms  27.840 ms  28.847 ms
 6  110.core2.thn.as20860.net (62.128.218.26)  29.112 ms  18.466 ms  19.835 ms
 7  be97.asr01.thn.as20860.net (62.128.222.205)  19.986 ms  20.488 ms  21.354 ms
 8  * * *
 9  216.239.48.143 (216.239.48.143)  24.364 ms 216.239.48.113 (216.239.48.113)  25.069 ms  25.592 ms
10  108.170.233.199 (108.170.233.199)  26.239 ms  27.369 ms  28.031 ms
11  lhr35s01-in-f14.1e100.net (172.217.23.14)  28.642 ms  29.311 ms  29.815 ms
  • First line shows the hostname and ip that is to be reached, the maximum number of hops to the host that traceroute will attempt and the size of the byte packets to be sent.
  • Each line below lists a hop to get to the destination. The hostname is given, followed by the ip of the hostname, followed by the roudtrip time that it takes for a packet to get to the host and back to the initiating computer. By default, traceroute sends 3 packets for each hosts.

Sometimes you might notice one or more lines of your traceroute output is listed only with an asterisk (*). This means that the program did not receive any response from the router at that hop.

Some organizations choose to block or discard the type of packets that traceroute relies on, either by blocking them with a firewall or configuring routers to discard the packets instead of replying. Traceroute traffic is also considered low-priority; a busy router may process standard data packets rather than reply to your traceroute request.

traceroute Common Options

$ traceroute -4 google.com ==> use IPv4
$ traceroute -6 google.com ==> use IPv6
$ traceroute -F google.com ==> Do not fragment packet
$ traceroute -f 10 google.com ==> Start from the 10th ttl hop
$ traceroute -g 10.12.13.14 google.com ==> Route the packet through the gate
$ $traceroute -m 5 google.com ==> Only max 5 hops
$ traceroute -n google.com ==> Skip resolve IPs to their domain names
$ traceroute -p 2022 google.com ==> Set destination port
$ traceroute -q 1 google.com ==> Limit number of probes per hop
$ traceroute -i eth2 google.com ==> Set interface to use
$ traceroute -w 1 google.com ==> Set probe response time to 1 second

Simple Python Implementation

Below is a simple Python version of traceroute

import socket
import argparse

DESTINATION_PORT = 33434
MESSAGE = 'test'

def trace_route(destination: str):
    # Get the destination ip address.
    destination_ip = socket.gethostbyname(destination)
    print(f'Tracing the route to {destination_ip}')
    # Prepare a socket to send UDP packets.
    sending_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sending_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # Prepare a socket to listen for ICMP messages.
    receiving_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
    # Show the ICMP header, since that's where the router address is.
    receiving_socket.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
    received_ip, current_hop = None, 1
    while received_ip != destination_ip:
        # Set the socket's TTL to the current hop so that the packet just
        # reaches it before being stopped.
        sending_socket.setsockopt(
            socket.IPPROTO_IP, socket.IP_TTL, current_hop)
        # Attempt to send a UDP packet to the destination ip.
        sending_socket.sendto(bytes(MESSAGE, 'utf-8'),
                              (destination_ip, DESTINATION_PORT))
        # Receive any incoming ICMP packet. We can ignore the first return
        # value from recvfrom, which would be the included data.
        _, addr = receiving_socket.recvfrom(1500)
        received_ip = addr[0]
        print(f'Current hop {current_hop}: ICMP message received from {received_ip}')
        current_hop = current_hop + 1

if __name__ == '__main__':
    my_parser = argparse.ArgumentParser()
    my_parser.add_argument('--dest', type=str, help='Destination host')
    args = my_parser.parse_args()
    dest_host = args.dest
    trace_route(dest_host)
Linux
DevOps
Programming
Cloud Computing
Recommended from ReadMedium