Open In App

Traceroute Implementation on Python

Last Updated : 16 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In Network information discovery, the traceroute tool is a fundamental utility in a Linux environment. Although the tool is already developed for the command line utility, we can still make our own Traceroute tool using Python language. We will explore the fundamentals of ICMP (Internet Control Message Protocol) and utilize Python’s socket programming. So in this article, we will see the detailed implementation of the Traceroute tool in Python Language.

What is Traceroute?

Traceroute is a command-line utility in Linux that provides a detailed analysis of the route data packets take from the source to a specified destination on a network. By sending a series of Internet Control Message Protocol (ICMP) or User Datagram Protocol (UDP) packets with increasing Time-to-Live (TTL) values, Traceroute reveals the successive network hops, or routers, that the packets traverse. As each packet reaches its TTL limit, an ICMP “Time Exceeded” message is sent back, allowing Traceroute to identify and display the IP addresses and response times of each intermediary node. This information is invaluable for diagnosing network issues, assessing latency, and understanding the specific path data follows across the Internet.

Why to use the Traceroute Tool?

A Traceroute tool is a valuable network diagnostic tool that helps to understand the actual path through which the data is passed from source to destination. Some of the reasons to use the Traceroute tool are stated below.

  1. Identify Network Hops: Traceroute reveals the path that packets take from the source to the destination. It displays the IP addresses of each router or hop along the route.
  2. Diagnose Latency Issues: By showing the round-trip time for each hop, traceroute helps identify where latency or delays occur. This information is crucial for diagnosing slow network connections.
  3. Detect Packet Loss: Traceroute can identify routers or links where packet loss is occurring. This is important for understanding and resolving issues that may impact the reliability of a network connection.
  4. Verify Routing Paths: It allows you to verify whether the packets are taking the expected path to the destination. Unexpected routes could indicate routing misconfigurations or network issues.

Working of Traceroute Tool

The working Traceroute Tool can be broken down into 7 different steps which are listed and described below:

  1. Initialization: Traceroute begins by sending a packet to the destination with a Time-to-Live (TTL) set to 1.
  2. Packet Transmission: The packet is sent to the destination. The first router encountered decrements the bto 0, discards the packet, and sends an ICMP Time Exceeded message back to the source.
  3. First Set of Results: The source records the round-trip time for the first hop and the IP address of the first router. Another packet is sent with a TTL of 2.
  4. Iterative Process: Steps 2 and 3 are repeated, increasing the TTL with each iteration. This reveals successive routers along the network path.
  5. Destination Reached: When a packet reaches the destination, the destination sends an ICMP Echo Reply back to the source.
  6. Recording Information: Round-trip time and IP addresses are recorded for each hop along the route.
  7. Output Presentation: Traceroute compiles and displays the recorded information, presenting the route to the destination with associated round-trip times.

Prerequisites:

  1. Linux Environment: This tutorial assumes you are working in a Linux environment. The provided instructions and script are tailored for Linux systems.
  2. Terminal Access: You should have access to a terminal or command-line interface on your Linux system. Most Linux distributions provide this by default.
  3. Python Installed: The provided script in the tutorial uses Python. Python is commonly pre-installed on many Linux distributions.

Creating the Python Script

In this section, we will develop the Python Script for Traceroute. We will break down the script into multiple steps to ease the understanding of implementation.

Step 1: Importing Libraries

Python3




# Importing Libraries
import socket
import struct
import time
from scapy.all import *
import argparse


Firstly, we need to import all the essential libraries required for various functionalities. Below are the libraries that we will be using for Traceroute implementation.

  1. socket: For DNS resolution.
  2. struct: For packing and unpacking binary data.
  3. time: For time-related functions.
  4. scapy: A Packet manipulation library.
  5. argparse: For parsing command-line arguments.

Step 2: Developing Traceroute Function

Python3




# Traceroute Function
def traceroute(destination, max_hops=30, timeout=2):
    destination_ip = socket.gethostbyname(destination)
    port = 33434
    ttl = 1
 
    while True:
        # Creating the IP and UDP headers
        ip_packet = IP(dst=destination, ttl=ttl)
        udp_packet = UDP(dport=port)
 
        # Combining the headers
        packet = ip_packet / udp_packet
 
        # Sending the packet and receive a reply
        reply = sr1(packet, timeout=timeout, verbose=0)
 
        if reply is None:
            # No reply, print * for timeout
            print(f"{ttl}\t*")
        elif reply.type == 3:
            # Destination reached, print the details
            print(f"{ttl}\t{reply.src}")
            break
        else:
            # Printing the IP address of the intermediate hop
            print(f"{ttl}\t{reply.src}")
 
        ttl += 1
 
        if ttl > max_hops:
            break


Here, the traceroute function performs the below operations:

  1. destination_ip = socket.gethostbyname(destination): Resolves the destination host to its IP address using DNS.
  2. port = 33434: This is the default destination port for traceroute. The choice of this port is arbitrary but commonly used.
  3. The function then enters a loop, incrementing the TTL for each iteration, and sends UDP packets to the destination using Scapy.
  4. The script interprets the responses and prints information about each hop or timeout.
  5. The script increments the TTL for each iteration and breaks out of the loop when the destination is reached or the TTL exceeds the specified maximum hops.

Step 3: Main Function with Argument Parsing

In this step, we will develop the main function with the input argument passing to the script.

Python3




# Main Function
def main():
   #Argument Passing
    parser = argparse.ArgumentParser(description="Traceroute implementation in Python.")
    parser.add_argument("destination", help="Destination host or IP address.")
    parser.add_argument("-m", "--max-hops", type=int, default=30, help="Maximum number of hops (default: 30).")
    parser.add_argument("-t", "--timeout", type=int, default=2, help="Timeout for each packet in seconds (default: 2).")
 
    args = parser.parse_args()
    # Printing Information
    print(f"Traceroute to {args.destination} (max hops: {args.max_hops}, timeout: {args.timeout} seconds):")
    # Calling Traceroute Function
    traceroute(args.destination, max_hops=args.max_hops, timeout=args.timeout)


The main function performs the below operations:

  1. Argument Parsing: This part utilizes the argparse library to parse command-line arguments. It defines three arguments: destination (the target host or IP address), max-hops (maximum number of hops), and timeout (timeout for each packet).
  2. Printing Information: The script prints a user-friendly message indicating the destination, maximum hops, and timeout values.
  3. Calling Traceroute Function: It then calls the traceroute function with the provided arguments.

Step 4: Script Execution

The below code snippet executes the main function when the script is run directly.

Python3




# Script Execution
if __name__ == "__main__":
    main()


Here, we are checking if the script is being run directly (not imported as a module) using if __name__ == "__main__":. If true, it executes the main function, initiating the traceroute.

Steps to create and execute Python Script

Step 1: Open the terminal window using the keyboard shortcut “Ctrl + Alt + T“.

Opening Terminal

Opening Terminal

Step 2: Using any text editor like Vim, vi, or Nano, open a new blank file in the text editor.

nano tracerouteTool.py

Creating File using nano editor

Creating File using Nano editor

Step 3: We need to write the script below in the created file tracerouteTool.py.

Python3




import socket
import struct
import time
from scapy.all import *
import argparse
 
def traceroute(destination, max_hops=30, timeout=2):
    destination_ip = socket.gethostbyname(destination)
    port = 33434
    ttl = 1
 
    while True:
        # Create the IP and UDP headers
        ip_packet = IP(dst=destination, ttl=ttl)
        udp_packet = UDP(dport=port)
 
        # Combine the headers
        packet = ip_packet / udp_packet
 
        # Send the packet and receive a reply
        reply = sr1(packet, timeout=timeout, verbose=0)
 
        if reply is None:
            # No reply, print * for timeout
            print(f"{ttl}\t*")
        elif reply.type == 3:
            # Destination reached, print the details
            print(f"{ttl}\t{reply.src}")
            break
        else:
            # Print the IP address of the intermediate hop
            print(f"{ttl}\t{reply.src}")
 
        ttl += 1
 
        if ttl > max_hops:
            break
 
def main():
    parser = argparse.ArgumentParser(description="Traceroute implementation in Python.")
    parser.add_argument("destination", help="Destination host or IP address.")
    parser.add_argument("-m", "--max-hops", type=int, default=30, help="Maximum number of hops (default: 30).")
    parser.add_argument("-t", "--timeout", type=int, default=2, help="Timeout for each packet in seconds (default: 2).")
 
    args = parser.parse_args()
 
    print(f"Traceroute to {args.destination} (max hops: {args.max_hops}, timeout: {args.timeout} seconds):")
    traceroute(args.destination, max_hops=args.max_hops, timeout=args.timeout)
 
if __name__ == "__main__":
    main()



Writing Python Code

Writing Python Code

Step 4: Install the scapy package by executing the below pip command in the terminal command:

pip install scapy

Installing scapy package

Installing scapy package

Step 5: Now, execute the created script by running the the command with the command line input.

Output

Output

Explanation:

  • In the above command, it executes a Python script named tracerouteTool.py with the argument geeksforgeeks.org and the maximum hops set to 10 (-m 10).
  • The script simulates a traceroute to ‘geeksforgeeks.org‘, displaying the route with each hop, round-trip time, and corresponding IP address.
  • The output displays the network path taken to reach the destination IP address (34.218.62.116) in a maximum of 10 hops.

Frequently Asked Questions (FAQs)

Q1. Why does Traceroute use UDP?

Answer:

Traceroute uses UDP (User Datagram Protocol) by default because it doesn’t establish a connection like TCP. UDP allows the traceroute program to send packets without waiting for acknowledgment, which is essential for the quick and lightweight probing of network hops.

Q2. What is the use of port 33434 in Traceroute?

Answer:

Port 33434 is the default starting port for the UDP packets in a traceroute. The choice of this port is somewhat arbitrary but commonly used. As the packets traverse the network, the destination port is incremented with each hop, providing a distinctive identifier for each packet.

Q3. Why does Traceroute increment the Time-to-Live (TTL) field?

Answer:

The Time-to-Live (TTL) field in the IP header is used to limit the lifetime of a packet. In traceroute, the TTL is initially set to 1, and with each hop, it is incremented. Routers along the path decrement the TTL, and when it reaches 0, the router discards the packet and sends an ICMP Time Exceeded message back. This process helps identify each hop in the route.

Q4. How does Traceroute handle firewalls?

Answer:

Traceroute may encounter firewalls that block ICMP Time Exceeded messages or UDP packets. In such cases, it might not receive the expected responses. Firewalls can affect the accuracy of traceroute results, and some networks intentionally block or limit ICMP traffic for security reasons.

Q5. What are common issues causing incomplete Traceroute results?

Answer:

Incomplete traceroute results can be caused by various factors, including firewalls, routers that don’t decrement TTL, or routers configured not to generate ICMP Time Exceeded messages. Additionally, some networks prioritize certain types of traffic, affecting the responsiveness of traceroute probes.

Conclusion

In conclusion, the provided Python script offers a custom implementation of the traceroute functionality. It consists of raw sockets and ICMP/UDP protocols to simulate the traceroute process, showcasing the network path to a specified destination, ‘geeksforgeeks.org‘ in the above example. The script displays standard traceroute output format, presenting a detailed view of each hop, round-trip times, and corresponding IP addresses along the route. By combining Python’s socket and struct modules, the script provides a practical and informative tool for network diagnostics and analysis, contributing to the understanding of data packet traversal through different routers in a network.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads