-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathICMPtraceroute.py
122 lines (95 loc) · 3.96 KB
/
ICMPtraceroute.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# Attribution: this assignment is based on ICMP Traceroute Lab from Computer Networking: a Top-Down Approach by Jim Kurose and Keith Ross.
# It was modified for use in CSC249: Networks at Smith College by R. Jordan Crouser in Fall 2022
from socket import *
from ICMPpinger import checksum
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 build_packet():
# 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.
#---------------#
# Fill in start #
#---------------#
# TODO: Make the header in a similar way to the ping exercise.
# Append checksum to the header.
# Solution can be implemented in 10 lines of Python code.
#-------------#
# Fill in end #
#-------------#
# Don’t send the packet yet , just return the final packet in this function.
packet = header + data
return packet
def get_route(hostname):
timeLeft = TIMEOUT
for ttl in range(1,MAX_HOPS):
for tries in range(TRIES):
destAddr = gethostbyname(hostname)
#---------------#
# Fill in start #
#---------------#
# TODO: Make a raw socket named mySocket
# Solution can be implemented in 2 lines of Python code.
#-------------#
# Fill in 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:
#---------------#
# Fill in start #
#---------------#
#TODO: Fetch the icmp type from the IP packet
# Solution can be implemented in 2 lines of Python code.
#-------------#
# Fill in end #
#-------------#
if types == 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 types == 3:
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 types == 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()
# Runs program
if __name__ == "__main__":
target = sys.argv[1]
get_route(target)