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.   Dont 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.

# Dont 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")