Skip to content

Instantly share code, notes, and snippets.

@kamikat
Last active May 4, 2018 19:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kamikat/d4e4206ff3d5d8bfc8db0931c5851a61 to your computer and use it in GitHub Desktop.
Save kamikat/d4e4206ff3d5d8bfc8db0931c5851a61 to your computer and use it in GitHub Desktop.
Traceroute implementation in Python 2.
#!/usr/bin/env python2.7
import argparse
import socket
import struct
import random
import time
MAX_HOP=64
MAX_ICMP_PACKET_SIZE=1508
class Protocol:
def __init__(self, packet):
self.packet = packet
def shift(self, size):
data = self.packet[:size]
self.packet = self.packet[size:]
return data
def probe(addr, ttl, port=60021):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl)
s.sendto("\x00"*16, (addr, port))
def traceroute(host):
s_icmp = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
s_icmp.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
s_icmp.settimeout(5.0)
for ttl in xrange(1, MAX_HOP + 1):
dport = random.randint(60000, 61000)
for i in xrange(3):
probe(host, ttl, dport)
t0 = time.time()
while time.time() - t0 < 5.0:
try:
ip_packet, addr = s_icmp.recvfrom(MAX_ICMP_PACKET_SIZE)
except socket.timeout:
continue
packet = Protocol(ip_packet)
packet.shift(20) # skip IP header
t, code, checksum = struct.unpack('!bbH', packet.shift(4))
if t == 11 and code == 0:
packet.shift(4) # skip TEM reserved
packet.shift(20) # skip IP header
udp_sport, udp_dport = struct.unpack('!HH', packet.shift(4))
if udp_dport == dport:
yield (ttl, addr[0], time.time() - t0)
break
else:
yield (ttl, None, time.time() - t0)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="print the route packets take to network host")
parser.add_argument('host', help='destination host')
args = parser.parse_args()
print "traceroute to %s, %d hops max" % (args.host, MAX_HOP)
for hop, addr, rtt in traceroute(args.host):
print " %-2s %-15s %9s" % (hop, addr if addr else '*', "%.3fms" % (rtt * 1000) if addr else '')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment