Python Programming Assignment 4: Traceroute
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
Python Programming Assignment 4: Traceroute
In this assignment you will continue to build your understanding of IP, ICMP, and Traceroute using Python socket programming. Although published before the ICMP Pinger Python lab is due, I would highly recommend finishing that assignment before beginning this one as some of the core components and learnings are borrowed from there – e.g. the checksum and header creation is not provided, but can be referenced from the ICMP pinger.
Traceroute is a computer networking diagnostic tool which allows a user to trace the route from a host running the traceroute program to any other host in the world. Traceroute is implemented with ICMP messages. It works by sending ICMP echo (ICMP type ‘8’) messages to the same destination with increasing value of the time-to-live (TTL) field. The routers along the traceroute path return ICMP Time Exceeded (ICMP type ‘11’ ) when the TTL field become zero. The final destination sends an ICMP reply (ICMP type ’0’ ) messages on receiving the ICMP echo request. The IP addresses of the routers which send replies can be extracted from the received packets. The round-trip time between the sending host and a router is determined by setting a timer at the sending host.
Your task is to develop your own Traceroute application in python using ICMP. Your application will use ICMP but, in order to keep it simple, will not exactly follow the official specification in
RFC 1739
Code
Skeleton code has been provided below. Your job is to fill in the code blocks between #Code Start and #Code End. Between each start and end, it may require one or more lines of code to complete this piece.
Additional Notes
1. The checksum from ICMP pinger can be used in this lab
2. For raw socket programming you will likely need root access. If you face issues, try running with sudo
3. Not all websites accept ICMP traffic, so try with different hosts
4. Don’t be afraid to reference back to the ICMP pinger lab!
What to submit
Run your code against 3 different hosts, at least 1 of which is in another country. Submit your code and screenshots of the output from each of the 3 runs.
from socket import *
import os
import sys
import struct
import time
import select
import binascii
ICMP_ECHO_REQUEST = 8
MAX HOPS = 30
TIMEOUT = 2.0
TRIES = 2
# The packet that we shall send to each router along the path is the
ICMP echo
# request packet, which is exactly what we had used in the ICMP ping
exercise.
# We shall use the same packet that we built in the Ping exercise
def checksum (str):
#Code Start
#Code End
def build_packet ():
#Code Start
# In the sendOnePing () method of the ICMP Ping exercise
,firstly the header of our
# packet to be sent was made, secondly the checksum was
appended to the header and
# then finally the complete packet was sent to the destination.
# Make the header in a similar way to the ping exercise.
# Append checksum to the header.
# Don’t send the packet yet , just return the final packet in
this function.
# So the function ending should look like this
#packet = header + data
#return packet
def get_route (hostname):
timeLeft = TIMEOUT
for ttl in xrange (1,MAX_HOPS):
for tries in xrange (TRIES):
destAddr = gethostbyname (hostname)
#Code Start
# Make a raw socket named mySocket
#Code End
mySocket.setsockopt (IPPROTO_IP, IP_TTL, struct.pack ( 'I ',
ttl))
mySocket.settimeout (TIMEOUT)
try:
d = build_packet ()
mySocket.sendto (d, (hostname, 0))
t= time.time ()
startedSelect = time.time ()
whatReady = select.select ( [mySocket], [], [],
timeLeft)
howLongInSelect = (time.time () - startedSelect)
if whatReady [0] == []: # Timeout
print " * * * Request timed
out."
recvPacket, addr = mySocket.recvfrom (1024)
timeReceived = time.time ()
timeLeft = timeLeft - howLongInSelect
if timeLeft <= 0:
print " * * * Request timed
out."
except timeout:
continue
else:
#Code Start
# Fetch the icmp type from the IP packet
#Code End
if type == 11:
bytes = struct.calcsize ("d")
timeSent = struct.unpack ("d", recvPacket [28:28 +
bytes]) [0]
print " %d rtt=%.0f ms %s" % (ttl,
(timeReceived -t)*1000, addr [0])
elif type == 3:
bytes = struct.calcsize ("d")
elif request_type == 0:
bytes = struct.calcsize ("d")
timeSent = struct.unpack ("d", recvPacket [28:28 +
bytes]) [0]
print " %d rtt=%.0f ms %s" % (ttl, (timeReceived
-timeSent)*1000, addr [0])
return
else:
print "error"
break
finally:
mySocket.close ()
get_route ("google.com")
2023-07-10