Skip to content

Instantly share code, notes, and snippets.

@jcjones
Forked from pnc/python-traceroute.py
Last active October 30, 2022 22:36
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save jcjones/0f3f11a785a833e0a216 to your computer and use it in GitHub Desktop.
Save jcjones/0f3f11a785a833e0a216 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import socket
import struct
import sys
# We want unbuffered stdout so we can provide live feedback for
# each TTL. You could also use the "-u" flag to Python.
class flushfile(file):
def __init__(self, f):
self.f = f
def write(self, x):
self.f.write(x)
self.f.flush()
sys.stdout = flushfile(sys.stdout)
def main(dest_name):
dest_addr = socket.gethostbyname(dest_name)
port = 33434
max_hops = 30
icmp = socket.getprotobyname('icmp')
udp = socket.getprotobyname('udp')
ttl = 1
while True:
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
# Build the GNU timeval struct (seconds, microseconds)
timeout = struct.pack("ll", 5, 0)
# Set the receive timeout so we behave more like regular traceroute
recv_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeout)
recv_socket.bind(("", port))
sys.stdout.write(" %d " % ttl)
send_socket.sendto("", (dest_name, port))
curr_addr = None
curr_name = None
finished = False
tries = 3
while not finished and tries > 0:
try:
_, curr_addr = recv_socket.recvfrom(512)
finished = True
curr_addr = curr_addr[0]
try:
curr_name = socket.gethostbyaddr(curr_addr)[0]
except socket.error:
curr_name = curr_addr
except socket.error as (errno, errmsg):
tries = tries - 1
sys.stdout.write("* ")
send_socket.close()
recv_socket.close()
if not finished:
pass
if curr_addr is not None:
curr_host = "%s (%s)" % (curr_name, curr_addr)
else:
curr_host = ""
sys.stdout.write("%s\n" % (curr_host))
ttl += 1
if curr_addr == dest_addr or ttl > max_hops:
break
if __name__ == "__main__":
main('google.com')
@gtomsho
Copy link

gtomsho commented Jun 29, 2018

A syntax error is generated on line 52: except socket.error as (errno, errmsg)
Running Python 3.6.3 on Windows 10.

@Yakuza-UA
Copy link

Yakuza-UA commented Jul 3, 2018

@gtomsho, I believe you are trying to use this script with Python3, but it was created for Python2. There are a number of things, not compatible with Python3. Even if you fix the exception bit, it then generates new error which is related to files handling in Python3 - it's not possible to inherit 'file' Class anymore and it has to be done slightly differently. Basically, script needs a few modifications

@onrsz15
Copy link

onrsz15 commented Oct 3, 2018

Guys, we're gonna need a version 3.6. I've tried, but can't help?

@zhongWJ
Copy link

zhongWJ commented Oct 16, 2018

@onrsz15 I change the code to support python 3.6 version
https://gist.github.com/zhongWJ/4783e74f04f7832d749f65fcd821d813

@x011
Copy link

x011 commented Jun 8, 2020

This code is for python2, don't bother to use or fix it if you're using python3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment