I modified some lines on previous traceroute on #32.
- modified break sequence so that it can skip those nodes which are configured not to respond to udp request.
- added RTT. I tried to use sent_time and time from the scapy itself. But it seems the value is not retirievable and I just ended up using legacy time function to get the idea of RTT(of course this is not reliable, so it’s just an idea)
Output Example:
$ python3 ntwk_basetools.py 1: 192.168.1.1 50 msec 2: 100.64.X.X 18 msec 3: 172.17.2.76 17 msec 4: 172.16.17.192 17 msec 5: 172.16.24.26 22 msec 6: 172.16.25.234 24 msec 7: 172.16.24.82 19 msec 8: 77.67.98.205 17 msec 9: 89.149.142.254 93 msec 10: 216.98.120.41 94 msec 11: 58.138.80.77 161 msec 12: 58.138.88.105 249 msec 13: * 14: * 15: * 16: * 17: *
Here is the code:
import time from scapy.all import * TIMEOUT = 30 def udptraceroute(hostname): result = [] time_result = [] for i in range(1, 20): pkt = IP(dst=hostname, ttl=i) / UDP(dport=33433 + i) start_time = time.time() reply = sr1(pkt, verbose=0, timeout=TIMEOUT) end_time = time.time() result.append(reply) time_result.append(end_time - start_time) # stop trace if last 5 trial doesn't get reply. consider it's dead end if all(response is None for response in result[-5:]): break # reply.type 3 is port unreachable. hence it's replied by the host itself if reply is not None and reply.type == 3: break return result, time_result if __name__ == "__main__": result, time_result = udptraceroute("www.asahi.co.jp") for id, (reply, rtt) in enumerate(zip(result, time_result), start=1): if reply is not None: print(f"{id}: {reply.src} {int(rtt * 1000)} msec") else: print(f"{id}: *")