Project 2 - Traceroute

Project Objectives

In this course project, you will develop a Python script that probes the route from the local machine to a given host address.

Description

The traceroute program identifies the IP addresses of all intermediary machines in between the source and destination. A UDP-based traceroute program is discussed in the class. In this project, you will implement such a tool with the following features.

  • The tool must be implemented in python3 and utilize scapy for custom packet generation. Aside from the socket library, no additional libraries are allowed to be used.
  • The first line of the .py script must be the location of the Python3 interpreter: #!/bin/env python3
  • Input argument: The tool should accept a single argument - the hostname or IP address of the destination host.
  • Max hops: Your tool must be able to identify all IP addresses in the path with the distance less that or equal to 20 hops. (In contrast, the default limit for traceroute in Linux is 30 hops.)
  • Max probes: Your tool must attempt for only one probe for a node at a certain distance. (In contrast, the traceroute tool in Linux sends three probes for a specific distance by default.)
  • Destination port number: Your tool should pick a random destination port number in the range [33434,33464] for each probe. For example, the first probe may have the destination port number 33458, the second probe may have the destination port number 33442, etc.
    • This is different from traceroute in Linux, which begins all traceroutes with destination port number 33434 and increments by 1 for each probe. That is, the first probe has destination port number 33434, the second probe has destination port number 33435, etc.
  • Source port number: Your tool should pick a random high number for the source UDP port for each probe. (The port fields are two bytes each in size, so don't pick a random number higher than 216 or 65535!)
  • The tool must report each discovered IP address and hostname in the path along with the distance from the source. If the address is unknown for a distance, use *, similar to the Linux tool. For hostname, you can use the socket.gethostbyaddr() function in Python to do the translation from IP address to hostname, and catch any socket.herror exceptions and ignore them for machines that do not have a discoverable hostname.
    • The Linux-based tool reports the host name in addition to the discovered IP address whenever possible. This is out of scope of this project.
  • Your tool must stop sending probes as soon as it receives an ICMP Port Unreachable message from the target.
  • It is desirable to eliminate verbosity of Scapy within the tool. You may use conf.verb = 0 for this purpose.
  • It is desirable to report the discovered IP addresses along the path to the target in real-time fashion (similar to Linux-based tool), rather than computing a whole list of addresses up to the target and reporting them in a single burst.
  • At the top of the script file, briefly describe how your tool works.

As a rule of thumb, if your traceroute program output differs from the Linux-based tool to a great extent, then you are probably doing something wrong. Compare the traffic generated by your tool versus the traffic from the Linux-based tool. That may help you to tune your probing packets appropriately.

Getting Started

First, ensure traceroute is installed in your Linux VM:

sudo apt install traceroute

Then, start Wireshark, capture a traceroute sequence to 8.8.8.8 (Google public DNS, a good example target), and stop capture.

wireshark &
# Start capture
traceroute 8.8.8.8
# Stop capture

Model your code against the traceroute behavior you see in Wireshark and follow the project requirements above.

Note that your traceroute from the standard Linux utility should look something like this. If you don't see network hops, and instead see line after line of * * *, then you have a networking problem in your VM that should be solved before writing your Python code. (Switching from NAT to Bridged mode in your virtual machine may help).

$ traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  _gateway (172.16.196.2)  2.277 ms  2.158 ms  2.052 ms
 2  unifi (10.10.2.1)  1.973 ms  1.760 ms  0.383 ms
 3  76-232-184-1.lightspeed.frokca.sbcglobal.net (76.232.184.1)  27.174 ms  27.114 ms  26.950 ms
 4  71.147.234.65 (71.147.234.65)  24.998 ms  24.955 ms  29.011 ms
 5  12.122.160.194 (12.122.160.194)  37.799 ms  37.757 ms  37.697 ms
 6  12.122.2.78 (12.122.2.78)  39.278 ms  33.564 ms  34.166 ms
 7  sffca22crs.ip.att.net (12.122.3.70)  39.221 ms  41.085 ms  41.049 ms
 8  12.122.163.61 (12.122.163.61)  33.763 ms  33.119 ms  34.002 ms
 9  12.255.10.236 (12.255.10.236)  34.262 ms 12.255.10.230 (12.255.10.230)  34.607 ms 12.255.10.236 (12.255.10.236)  36.855 ms
10  108.170.242.81 (108.170.242.81)  36.859 ms 10.252.52.126 (10.252.52.126)  37.488 ms 10.252.237.62 (10.252.237.62)  37.745 ms
11  72.14.235.1 (72.14.235.1)  37.083 ms 209.85.247.55 (209.85.247.55)  37.862 ms dns.google (8.8.8.8)  33.201 ms

Resources

Deliverables

Submit a single Python script that implements traceroute to the Canvas CMS Project 2 assignment.

If using PyCharm, do not submit your venv environment. Before submitting, test to ensure you can run your program outside of PyCharm on the command line.

Sample Output

Running the tool may generate an output similar to the following in a terminal in Ubuntu Linux.

$ sudo ./traceroute.py 8.8.8.8
traceroute to dns.google (8.8.8.8)
1.  _gateway (172.16.196.2)
2.  unifi (10.10.2.1)
3.  76-232-184-1.lightspeed.frokca.sbcglobal.net (76.232.184.1)
4.  (71.147.234.65)
5.  (12.122.160.194)
6.  (12.122.2.78)
7.  sffca22crs.ip.att.net (12.122.3.70)
8.  (12.122.163.61)
9.  (12.255.10.236)
10. *
11. (72.14.239.97)
12. dns.google (8.8.8.8)
Reached target, ending traceroute
$ sudo ./traceroute.py cyberlab.pacific.edu
traceroute to ec2-54-148-163-48.us-west-2.compute.amazonaws.com (54.148.163.48)
1.  _gateway (172.16.196.2)
2.  unifi (10.10.2.1)
3.  76-232-184-1.lightspeed.frokca.sbcglobal.net (76.232.184.1)
4.  (71.147.234.65)
5.  (12.122.160.194)
6.  (12.122.2.78)
7.  (12.122.163.34)
8.  cr83.sj2ca.ip.att.net (12.122.158.9)
9.  (12.94.42.186)
10. *
11. *
12. *
13. *
14. *
15. *
16. *
17. *
18. *
19. *
20. *
$ sudo ./traceroute.py bogus.fakewebsite.fake
Error: Invalid hostname or IP address