Project 2 - Traceroute
Table of Contents
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 utilizescapy
for custom packet generation. Aside from thesocket
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 thesocket.gethostbyaddr()
function in Python to do the translation from IP address to hostname, and catch anysocket.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
- Scapy Documentation
- The Packet Geek: Building Network Tools with Scapy
- How to do a reverse DNS lookup in Python
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