import subprocess import re import json import ipaddress from datetime import datetime from sys import hash_info import pprint def run_traceroute(host): result = subprocess.run(['traceroute', host], stdout=subprocess.PIPE) return result.stdout.decode() def parse_traceroute_output(output): lines = output.strip().split('\n') hops = [] ip_regex = r"\((.*?)\)" # ipaddress are in () target = output.strip().split('\n')[0].split()[2] for line in lines[1:]: hop = [] hop_info = line.split() hop_number = int(hop_info[0]) hop_name = None hop_ip = None hop_latency = None latencies = [] #print("##### "+str(hop_info)) count = 0 for part in hop_info[1:]: count += 1 # source node drops or blocks icmp packages # We will give funny to name to hop for not answering and move on. if part == '*': hop_name = 'hop.'+str(count)+'.'+str(target) break # If first colum is either name or ip-address if count == 1: print(part) match = re.search(ip_regex, part) if match: hop_ip = part.strip('()') else: print('do ever here?') hop_name = part # Second colum is ip-address first latency reading if count == 2: print(part) if re.search(ip_regex, part): try: _ip = ipaddress.ip_address(part.strip('()')) hop_ip = part.strip('()') except ValueError: pass # Ignore if it's not a valid IP address # Rest of the input colums are either latency floats, 'ms' or # reruns of the hop_name and hop_ip... # We only need the latency floats anymore. else: print(part) try: latency = float(part) latencies.append(latency) except ValueError: pass hop_latency = sum(latencies) / len(latencies) if latencies else None hop.append(hop_number) if not hop_name == None: hop.append(hop_name) hop.append(hop_ip) hop.append(hop_latency) hops.append(hop) return target, hops if __name__ == '__main__': target='8.8.8.8' traceroute_output = run_traceroute(target) target, hops = parse_traceroute_output(traceroute_output) print('>> '+target) pprint.pprint(hops)