Project 2 - Traceroute
In this course project, you will develop a Python script that probes the route from the local machine to a given host address.
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
scapyfor custom packet generation. Aside from the
socketlibrary, no additional libraries are allowed to be used.
- The first line of the .py script must be the location of the Python3 interpreter:
- 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.herrorexceptions 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 = 0for 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.
First, ensure traceroute is installed in your Linux VM:
sudo apt install traceroute
Then, start Wireshark, capture a traceroute sequence to
18.104.22.168 (Google public DNS, a good example target), and stop capture.
wireshark & # Start capture traceroute 22.214.171.124 # 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 126.96.36.199 traceroute to 188.8.131.52 (184.108.40.206), 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 (220.127.116.11) 27.174 ms 27.114 ms 26.950 ms 4 18.104.22.168 (22.214.171.124) 24.998 ms 24.955 ms 29.011 ms 5 126.96.36.199 (188.8.131.52) 37.799 ms 37.757 ms 37.697 ms 6 184.108.40.206 (220.127.116.11) 39.278 ms 33.564 ms 34.166 ms 7 sffca22crs.ip.att.net (18.104.22.168) 39.221 ms 41.085 ms 41.049 ms 8 22.214.171.124 (126.96.36.199) 33.763 ms 33.119 ms 34.002 ms 9 188.8.131.52 (184.108.40.206) 34.262 ms 220.127.116.11 (18.104.22.168) 34.607 ms 22.214.171.124 (126.96.36.199) 36.855 ms 10 188.8.131.52 (184.108.40.206) 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 220.127.116.11 (18.104.22.168) 37.083 ms 22.214.171.124 (126.96.36.199) 37.862 ms dns.google (188.8.131.52) 33.201 ms
- Scapy Documentation
- The Packet Geek: Building Network Tools with Scapy
- How to do a reverse DNS lookup in Python
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.
Running the tool may generate an output similar to the following in a terminal in Ubuntu Linux.
$ sudo ./traceroute.py 184.108.40.206
traceroute to dns.google (220.127.116.11) 1. _gateway (172.16.196.2) 2. unifi (10.10.2.1) 3. 76-232-184-1.lightspeed.frokca.sbcglobal.net (18.104.22.168) 4. (22.214.171.124) 5. (126.96.36.199) 6. (188.8.131.52) 7. sffca22crs.ip.att.net (184.108.40.206) 8. (220.127.116.11) 9. (18.104.22.168) 10. * 11. (22.214.171.124) 12. dns.google (126.96.36.199) Reached target, ending traceroute
$ sudo ./traceroute.py cyberlab.pacific.edu
traceroute to ec2-54-148-163-48.us-west-2.compute.amazonaws.com (188.8.131.52) 1. _gateway (172.16.196.2) 2. unifi (10.10.2.1) 3. 76-232-184-1.lightspeed.frokca.sbcglobal.net (184.108.40.206) 4. (220.127.116.11) 5. (18.104.22.168) 6. (22.214.171.124) 7. (126.96.36.199) 8. cr83.sj2ca.ip.att.net (188.8.131.52) 9. (184.108.40.206) 10. * 11. * 12. * 13. * 14. * 15. * 16. * 17. * 18. * 19. * 20. *
$ sudo ./traceroute.py bogus.fakewebsite.fake
Error: Invalid hostname or IP address