added --tmp_dir to specify download directory and --no_geo to skip geolocation data
This commit is contained in:
parent
4832744fd6
commit
033fe8d54e
1 changed files with 28 additions and 34 deletions
|
|
@ -8,7 +8,7 @@ for each hop for a specified host from geographically distant source(s).
|
||||||
|
|
||||||
__author__ = 'Dazzlepod (info@dazzlepod.com)'
|
__author__ = 'Dazzlepod (info@dazzlepod.com)'
|
||||||
__copyright__ = 'Copyright (c) 2013 Dazzlepod'
|
__copyright__ = 'Copyright (c) 2013 Dazzlepod'
|
||||||
__version__ = '$Revision: #7 $'
|
__version__ = '$Revision: #11 $'
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
|
@ -24,9 +24,11 @@ from subprocess import Popen, PIPE
|
||||||
|
|
||||||
class Traceroute(object):
|
class Traceroute(object):
|
||||||
"""Traceroute instance."""
|
"""Traceroute instance."""
|
||||||
def __init__(self, ip_address='8.8.8.8', debug=False):
|
def __init__(self, ip_address='8.8.8.8', tmp_dir='/tmp', no_geo=False, debug=False):
|
||||||
super(Traceroute, self).__init__()
|
super(Traceroute, self).__init__()
|
||||||
self.ip_address = ip_address
|
self.ip_address = ip_address
|
||||||
|
self.tmp_dir = tmp_dir
|
||||||
|
self.no_geo = no_geo
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
# cache geocoded IP addresses during the lifetime of this instance
|
# cache geocoded IP addresses during the lifetime of this instance
|
||||||
self.locations = {}
|
self.locations = {}
|
||||||
|
|
@ -34,17 +36,17 @@ class Traceroute(object):
|
||||||
def traceroute(self):
|
def traceroute(self):
|
||||||
"""Instead of running the actual traceroute command, we will fetch
|
"""Instead of running the actual traceroute command, we will fetch
|
||||||
standard traceroute results from several publicly available webpages
|
standard traceroute results from several publicly available webpages
|
||||||
that are listed at traceroute.org.
|
that are listed at traceroute.org. For each hop, we will then attach
|
||||||
|
geolocation information to it."""
|
||||||
For each hop, we will then attach geolocation information to it."""
|
|
||||||
self.print_debug("ip_address = %s" % self.ip_address)
|
self.print_debug("ip_address = %s" % self.ip_address)
|
||||||
if not os.path.exists('%s.txt' % self.ip_address):
|
txt = os.path.join(self.tmp_dir, '%s.txt' % self.ip_address)
|
||||||
|
if not os.path.exists(txt):
|
||||||
(status_code, traceroute) = self.get_traceroute_output()
|
(status_code, traceroute) = self.get_traceroute_output()
|
||||||
f = open('%s.txt' % self.ip_address, 'w')
|
f = open(txt, 'w')
|
||||||
f.write(traceroute)
|
f.write(traceroute)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
traceroute = open('%s.txt' % self.ip_address, 'r').read()
|
traceroute = open(txt, 'r').read()
|
||||||
|
|
||||||
# hops = dicts with keys: hop_num, hosts
|
# hops = dicts with keys: hop_num, hosts
|
||||||
hops = self.get_hops(traceroute)
|
hops = self.get_hops(traceroute)
|
||||||
|
|
@ -52,11 +54,9 @@ class Traceroute(object):
|
||||||
# hops = dicts with keys: hop_num, hostname, ip_address, rtt
|
# hops = dicts with keys: hop_num, hostname, ip_address, rtt
|
||||||
hops = self.get_formatted_hops(hops)
|
hops = self.get_formatted_hops(hops)
|
||||||
|
|
||||||
# hops = dicts with keys: hop_num, hostname, ip_address, rtt, location
|
if not self.no_geo:
|
||||||
hops = self.get_geocoded_hops(hops)
|
# hops = dicts with keys: hop_num, hostname, ip_address, rtt, latitude, longitude
|
||||||
|
hops = self.get_geocoded_hops(hops)
|
||||||
# hops = dicts with keys: hop_num, ip_address, latitude, longitude, rtt
|
|
||||||
hops = self.get_stripped_hops(hops)
|
|
||||||
|
|
||||||
return hops
|
return hops
|
||||||
|
|
||||||
|
|
@ -119,36 +119,29 @@ class Traceroute(object):
|
||||||
def get_geocoded_hops(self, hops):
|
def get_geocoded_hops(self, hops):
|
||||||
"""Return hops from get_formatted_hops() with geolocation information
|
"""Return hops from get_formatted_hops() with geolocation information
|
||||||
for each hop."""
|
for each hop."""
|
||||||
|
geocoded_hops = []
|
||||||
|
|
||||||
for hop in hops:
|
for hop in hops:
|
||||||
ip_address = hop['ip_address']
|
ip_address = hop['ip_address']
|
||||||
|
|
||||||
location = None
|
location = None
|
||||||
if self.locations.has_key(ip_address):
|
if self.locations.has_key(ip_address):
|
||||||
location = self.locations[ip_address]
|
location = self.locations[ip_address]
|
||||||
else:
|
else:
|
||||||
location = self.get_location(ip_address)
|
location = self.get_location(ip_address)
|
||||||
self.locations[ip_address] = location
|
self.locations[ip_address] = location
|
||||||
hop['location'] = location
|
|
||||||
|
|
||||||
return hops
|
if location:
|
||||||
|
geocoded_hops.append({
|
||||||
def get_stripped_hops(self, hops):
|
|
||||||
""" Return hops from get_geocoded_hops() with each dict containing
|
|
||||||
data ready for plotting with e.g. Google Maps JavaScript API."""
|
|
||||||
stripped_hops = []
|
|
||||||
|
|
||||||
for hop in hops:
|
|
||||||
if hop['location']:
|
|
||||||
lat = hop['location']['latitude']
|
|
||||||
lon = hop['location']['longitude']
|
|
||||||
stripped_hops.append({
|
|
||||||
'hop_num': hop['hop_num'],
|
'hop_num': hop['hop_num'],
|
||||||
|
'hostname': hop['hostname'],
|
||||||
'ip_address': hop['ip_address'],
|
'ip_address': hop['ip_address'],
|
||||||
'latitude': lat,
|
|
||||||
'longitude': lon,
|
|
||||||
'rtt': hop['rtt'],
|
'rtt': hop['rtt'],
|
||||||
|
'latitude': location['latitude'],
|
||||||
|
'longitude': location['longitude'],
|
||||||
})
|
})
|
||||||
|
|
||||||
return stripped_hops
|
return geocoded_hops
|
||||||
|
|
||||||
def get_location(self, ip_address):
|
def get_location(self, ip_address):
|
||||||
"""Return geolocation information for the specified IP address, e.g.:
|
"""Return geolocation information for the specified IP address, e.g.:
|
||||||
|
|
@ -171,7 +164,7 @@ class Traceroute(object):
|
||||||
location = tmp_location
|
location = tmp_location
|
||||||
return location
|
return location
|
||||||
|
|
||||||
def urlopen(self, url, context = None):
|
def urlopen(self, url, context=None):
|
||||||
"""Perform HTTP GET/POST on the specified URL and return the resultant
|
"""Perform HTTP GET/POST on the specified URL and return the resultant
|
||||||
status code and response.
|
status code and response.
|
||||||
"""
|
"""
|
||||||
|
|
@ -208,15 +201,16 @@ class Traceroute(object):
|
||||||
def main():
|
def main():
|
||||||
usage = """%prog --ip_address=IP_ADDRESS"""
|
usage = """%prog --ip_address=IP_ADDRESS"""
|
||||||
cmdparser = optparse.OptionParser(usage, version=("traceroute " + __version__))
|
cmdparser = optparse.OptionParser(usage, version=("traceroute " + __version__))
|
||||||
cmdparser.add_option("-i", "--ip_address", type="string", default="", help="IP address of destination host")
|
cmdparser.add_option("-i", "--ip_address", type="string", default="8.8.8.8", help="IP address of destination host (default: 8.8.8.8)")
|
||||||
cmdparser.add_option("-d", "--debug", action="store_true", default=False, help="Show debug output")
|
cmdparser.add_option("-t", "--tmp_dir", type="string", default="/tmp", help="Temporary directory to store downloaded traceroute results (default: /tmp)")
|
||||||
|
cmdparser.add_option("-n", "--no_geo", action="store_true", default=False, help="No geolocation data (default: False)")
|
||||||
|
cmdparser.add_option("-d", "--debug", action="store_true", default=False, help="Show debug output (default: False)")
|
||||||
|
|
||||||
(options, args) = cmdparser.parse_args()
|
(options, args) = cmdparser.parse_args()
|
||||||
|
|
||||||
if options.ip_address:
|
if options.ip_address:
|
||||||
traceroute = Traceroute(ip_address=options.ip_address, debug=options.debug)
|
traceroute = Traceroute(ip_address=options.ip_address, tmp_dir=options.tmp_dir, no_geo=options.no_geo, debug=options.debug)
|
||||||
hops = traceroute.traceroute()
|
hops = traceroute.traceroute()
|
||||||
hops = json.dumps(hops, indent=2)
|
|
||||||
print hops
|
print hops
|
||||||
else:
|
else:
|
||||||
cmdparser.print_usage()
|
cmdparser.print_usage()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue