- made progress on self hop parser
This commit is contained in:
parent
f51f4d0888
commit
1d168d48f6
1 changed files with 61 additions and 62 deletions
123
traceroute.py
123
traceroute.py
|
|
@ -41,7 +41,7 @@ class Traceroute(object):
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.locations = {}
|
self.locations = {}
|
||||||
self.hops = []
|
self.hops = {}
|
||||||
self.country = country
|
self.country = country
|
||||||
|
|
||||||
# Localhost Specific operations happen here
|
# Localhost Specific operations happen here
|
||||||
|
|
@ -81,15 +81,11 @@ class Traceroute(object):
|
||||||
open(filepath, "w").write(traceroute)
|
open(filepath, "w").write(traceroute)
|
||||||
traceroute = open(filepath, "r").read()
|
traceroute = open(filepath, "r").read()
|
||||||
|
|
||||||
# hop_num, hosts
|
self.__get_hops(traceroute)
|
||||||
hops = self.__get_hops(traceroute)
|
|
||||||
|
|
||||||
# hop_num, hostname, ip_address, rtt
|
|
||||||
self.hops = self.__get_formatted_hops()
|
|
||||||
|
|
||||||
if not self.no_geo:
|
#if not self.no_geo:
|
||||||
# hop_num, hostname, ip_address, rtt, latitude, longitude
|
# self.__get_geocoded_hops()
|
||||||
self.hops = self.__get_geocoded_hops()
|
|
||||||
|
|
||||||
#self.hops = map(lambda h: {h.pop("hop_num") : h}, self.hops)
|
#self.hops = map(lambda h: {h.pop("hop_num") : h}, self.hops)
|
||||||
|
|
||||||
|
|
@ -121,70 +117,73 @@ class Traceroute(object):
|
||||||
"""
|
"""
|
||||||
Returns hops from traceroute output in an array of dicts each
|
Returns hops from traceroute output in an array of dicts each
|
||||||
with hop number and the associated hosts data.
|
with hop number and the associated hosts data.
|
||||||
"""
|
|
||||||
regex = r'^(?P<hop_num>\d+)(?P<hosts>.*?)$'
|
|
||||||
lines = traceroute.split("\n")
|
|
||||||
for line in lines:
|
|
||||||
line = line.strip()
|
|
||||||
hop = {}
|
|
||||||
if not line:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
hop = re.match(regex, line).groupdict()
|
|
||||||
except AttributeError:
|
|
||||||
continue
|
|
||||||
self.print_debug(hop)
|
|
||||||
self.hops.append(hop)
|
|
||||||
|
|
||||||
def __get_formatted_hops(self):
|
|
||||||
"""
|
|
||||||
Hosts data from get_hops() is represented in a single string.
|
|
||||||
We use this function to better represent the hosts data in a dict.
|
|
||||||
"""
|
|
||||||
formatted_hops = []
|
|
||||||
regex = r'(?P<h>[\w.-]+) \((?P<i>[\d.]+)\) (?P<r>\d{1,4}.\d{1,4} ms)'
|
|
||||||
for hop in self.hops:
|
|
||||||
hop_num = int(hop['hop_num'].strip())
|
|
||||||
hosts = hop['hosts'].replace(" ", " ").strip()
|
|
||||||
# Using re.findall(), we split the hosts, then for each host,
|
|
||||||
# we store a tuple of hostname, IP address and the first RTT.
|
|
||||||
hosts = re.findall(regex, hosts)
|
|
||||||
for host in hosts:
|
|
||||||
hop_context = {
|
hop_context = {
|
||||||
'hop_num': hop_num,
|
'hop_num': hop_num,
|
||||||
'hostname': host[0],
|
'hostname': host[0],
|
||||||
'ip_address': host[1],
|
'ip_address': host[1],
|
||||||
'rtt': host[2],
|
'rtt': host[2],
|
||||||
}
|
}
|
||||||
self.print_debug(hop_context)
|
"""
|
||||||
formatted_hops.append(hop_context)
|
# This breaks up the line into hop num => host data
|
||||||
return formatted_hops
|
#hop_pattern = '^(?P<hop_num>\w+)\s+(?P<hosts>.*)'
|
||||||
|
hop_pattern = '^(?P<hop_num>[0-9]+)\s+(?P<hosts>.*)'
|
||||||
|
# This matches hosts which are ip or dns mapped
|
||||||
|
host_pattern = '([\d\w.]+\s+\(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\)\s+\d+\.\d+ ms)'
|
||||||
|
# This is essentially the same as the previous pattern but breaks into usable chunks
|
||||||
|
hop_element_pattern = '([\d\w.]+)\s+\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\)\s+(\d+\.\d+ ms)'
|
||||||
|
hp = re.compile(hop_element_pattern)
|
||||||
|
|
||||||
|
for entry in traceroute.split('\n'):
|
||||||
|
entry = entry.strip()
|
||||||
|
result = re.match(hop_pattern,entry)
|
||||||
|
|
||||||
|
if result is None: # should only fail on first line
|
||||||
|
continue
|
||||||
|
hop = result.groupdict()
|
||||||
|
hop_num = int(hop['hop_num'])
|
||||||
|
|
||||||
|
hop_hosts = re.findall(host_pattern, hop['hosts'])
|
||||||
|
self.hops[hop_num] = []
|
||||||
|
for host in hop_hosts:
|
||||||
|
m = hp.search(host)
|
||||||
|
(hostname, ip, ping_time) = m.groups()
|
||||||
|
if self.no_geo:
|
||||||
|
self.hops[hop_num].append(
|
||||||
|
{
|
||||||
|
'hostname' : hostname,
|
||||||
|
'ip_address' : ip,
|
||||||
|
'rtt' : ping_time
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
location = self.__get_geocoded_data(ip)
|
||||||
|
if location:
|
||||||
|
self.hops[hop_num].append(
|
||||||
|
{
|
||||||
|
'hostname' : hostname,
|
||||||
|
'ip_address' : ip,
|
||||||
|
'rtt' : ping_time,
|
||||||
|
'latitude' : location['latitude'],
|
||||||
|
'longitude' : location['longitude']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def __get_geocoded_hops(self):
|
|
||||||
|
|
||||||
|
def __get_geocoded_data(self, ip_address):
|
||||||
"""
|
"""
|
||||||
Returns hops from get_formatted_hops() with geolocation information
|
Returns a location hash with long/lat for a particular IP address
|
||||||
for each hop.
|
|
||||||
"""
|
"""
|
||||||
geocoded_hops = []
|
location = None
|
||||||
for hop in self.hops:
|
if ip_address in self.locations:
|
||||||
ip_address = hop['ip_address']
|
location = self.locations[ip_address]
|
||||||
location = None
|
else:
|
||||||
if ip_address in self.locations:
|
location = self.get_location(ip_address)
|
||||||
location = self.locations[ip_address]
|
self.locations[ip_address] = location
|
||||||
else:
|
|
||||||
location = self.get_location(ip_address)
|
return location
|
||||||
self.locations[ip_address] = location
|
|
||||||
if location:
|
|
||||||
geocoded_hops.append({
|
|
||||||
'hop_num': hop['hop_num'],
|
|
||||||
'hostname': hop['hostname'],
|
|
||||||
'ip_address': hop['ip_address'],
|
|
||||||
'rtt': hop['rtt'],
|
|
||||||
'latitude': location['latitude'],
|
|
||||||
'longitude': location['longitude'],
|
|
||||||
})
|
|
||||||
return geocoded_hops
|
|
||||||
|
|
||||||
def get_location(self, ip_address):
|
def get_location(self, ip_address):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue