Last active
January 3, 2017 17:57
-
-
Save blacktwin/71e984d5d8d552b2e22416b933e7a6fb to your computer and use it in GitHub Desktop.
Prints tracert output to console then projects map of hop locations with connecting lines. Random IP if set to blank with Country code restriction.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Need GeoLiteCity.dat | |
https://dev.maxmind.com/geoip/legacy/geolite/ | |
Place in root of tracert_t.py | |
''' | |
import pygeoip | |
import matplotlib.pyplot as plt | |
import matplotlib as mpl | |
import random | |
from subprocess import Popen, PIPE | |
from mpl_toolkits.basemap import Basemap | |
from collections import OrderedDict | |
from geopy.geocoders import Nominatim | |
from ipwhois import IPWhois | |
from pprint import pprint | |
geolocator = Nominatim() | |
#Edit# | |
ip = '' #if blank then IP will be random. | |
LAN_SUBNET = '192.168' #change to your network | |
num_hops = '20' | |
title_string = "Traceroute data" | |
legend_title = "Legend" | |
COUNTRY = 'US' # Only tested in US. Country should restrict random IPs to country code. | |
## | |
#Map settings | |
plt.figure(figsize=(16, 9), dpi=100, frameon=False, tight_layout=True) | |
m = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-54, urcrnrlat=55, projection='lcc', resolution='l', lat_1=32, | |
lat_2=45, lon_0=-95) | |
m.drawmapboundary(fill_color='#1F1F1F') | |
m.drawcoastlines() | |
m.drawstates() | |
m.drawcountries() | |
m.fillcontinents(color='#3C3C3C', lake_color='#1F1F1F') | |
mpl.rcParams['legend.handlelength'] = 0 | |
class Whowho(object): | |
def __init__(self, data=None): | |
data = data or [] | |
self.place = [d['address'] for d in data] | |
self.city = [d['city'] for d in data] | |
self.cidr = [d['cidr'] for d in data] | |
self.country = [d['country'] for d in data] | |
self.postal_code = [d['postal_code'] for d in data] | |
def whoiswho(IP): | |
obj = IPWhois(IP) | |
results = obj.lookup_whois() | |
data = results['nets'] | |
return Whowho(data=data) | |
def mean(numbers): | |
return float(sum(numbers)) / max(len(numbers), 1) | |
def tracertt(ip_address): | |
lst = [] | |
new_lst = [] | |
p = Popen(['tracert', '-h', num_hops, '-d', ip_address], stdout=PIPE) | |
while True: | |
line = p.stdout.readline() | |
print(line.strip()) | |
if line.strip() == "" or line.startswith("Trac") or line.startswith("over"): | |
pass | |
else: | |
line = line.strip() | |
line = " ".join(line.split()) | |
line = line.replace(' ms', '', 3) | |
line = line.replace('<', '', 3) | |
line = line.replace('*', '0', 3) | |
line = line.replace('[', '') | |
line = line.replace(']', '') | |
line = line.split() | |
if line[-1].endswith('.'): | |
pass | |
else: | |
frontline = [int(i) for i in line[0:4]] | |
back = line[4:5] | |
[frontline.append(i) for i in back] | |
lst += [frontline] | |
if not line: break | |
p.wait() | |
# Pull IP addresses for Geo data | |
for i in lst: | |
try: | |
IP = i[4] | |
if not IP.startswith(LAN_SUBNET): | |
gi = pygeoip.GeoIP('GeoLiteCity.dat') | |
gir = gi.record_by_addr(IP) | |
if not isinstance(gir['city'], unicode): | |
pass | |
else: | |
i += [str(gir['latitude'])] + [str(gir['longitude'])] + [str(gir['city'])] | |
new_lst += [i] | |
except IndexError: | |
pass | |
continue | |
gclines = [] | |
label_lst = [] | |
for (hop, t1, t2, t3, ip, lat, lon, city) in new_lst: | |
x, y = m(lon, lat) | |
ms = [v for v in [t1, t2, t3] if v != 0] | |
markersize = int(mean(ms)) | |
labels = 'Hop: ' + str(hop) + '. ' + city + ' @ ' + ip | |
label_lst += [labels] | |
m.plot(x, y, marker='.', color='red', markersize=markersize, alpha=0.09) | |
gclines += [lon] + [lat] | |
for i, j, k, l in zip(gclines[0::2], gclines[1::2], gclines[2::2], gclines[3::2]): | |
m.drawgreatcircle(float(i), float(j), float(k), float(l), linewidth=1, alpha=0.5, | |
color='#AC7420') | |
for i, j, k in zip(label_lst[0::2], label_lst[1::2], label_lst[2::2]): | |
label_path = [i, j, j, k] | |
for t, n in zip(label_path[0::2], label_path[1::2]): | |
f_label = t + ' --> ' + n | |
z, q = m('0', '0') | |
m.plot(z, q, marker='.', color='red', label=f_label) | |
handles, labels = plt.gca().get_legend_handles_labels() | |
by_label = OrderedDict(zip(labels, handles)) | |
leg = plt.legend(by_label.values(), by_label.keys(), fancybox=True, fontsize='xx-small', numpoints=1, | |
title=legend_title) | |
if leg: | |
lleng = len(leg.legendHandles) | |
for i in range(0, lleng): | |
leg.legendHandles[i]._legmarker.set_markersize(5) | |
leg.legendHandles[i]._legmarker.set_alpha(1) | |
leg.get_title().set_color('#7B777C') | |
leg.draggable() | |
leg.get_frame().set_facecolor('#2C2C2C') | |
for text in leg.get_texts(): | |
plt.setp(text, color='#A5A5A7') | |
plt.title(title_string) | |
plt.show() | |
if __name__ == '__main__': | |
if ip == '': | |
while ip == '': | |
# Random IP | |
oct1_r = random.randint(3, 216) | |
if oct1_r == 10: | |
pass | |
oct_r = random.randint(0, 255) | |
ip = str(oct1_r) + '.' + str(oct_r) + '.' + str(oct_r) + '.' + str(oct_r) | |
whoru = whoiswho(ip) | |
try: | |
if whoru.country[0] == COUNTRY: | |
tracertt(ip) | |
break | |
else: | |
ip = '' | |
except IndexError: | |
pass | |
else: | |
tracertt(ip) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment