Draw a graph from RIS BGP data. A PNG file will be generated with name 'YYYY- MM-DD-HH-MM-route.png'. During the generation, all the paths are printed to the console in case you want to see prepending and such.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

88 lines
2.5 KiB

#!/usr/bin/env python
import argparse
import cymruwhois
import itertools
import json
import pydot
import random
import time
import urllib.request
parser = argparse.ArgumentParser(description='''
Draw a graph from RIS BGP data. A PNG file will be generated with name
'YYYY-MM-DD-HH-MM-route.png'.
During the generation, all the paths are printed to the console in case you want
to see prepending and such.
''')
parser.add_argument('--route', dest='route', type=str,
help='IPv4 or IPv6 range present in the DFZ')
args = parser.parse_args()
print(args.route)
def pairwise(iterable):
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
paths = {}
ris_json = urllib.request.urlopen('https://stat.ripe.net/data/looking-glass/data.json?resource={}'.format(args.route))
ris_data = json.load(ris_json)
prefix = ris_data['data']['rrcs'][0]['peers'][0]['prefix']
for rrc in ris_data['data']['rrcs']:
for peer in rrc['peers']:
path = []
for asn in peer['as_path'].split():
path.append(asn)
path.append(prefix)
paths[peer['peer']] = path
#json_graph = json.JSONEncoder().encode(paths)
nodes = {}
edges = {}
dot_graph = pydot.Dot('BGPMAP', graph_type='digraph')
cymruwhois_client = cymruwhois.Client()
for peer in paths:
print(peer, paths[peer])
string_prepended_path = ['AS'+v for v in paths[peer][:-1]]
print(string_prepended_path)
cymruwhois_query = cymruwhois_client.lookupmany_dict(string_prepended_path)
for previous_asn, asn in pairwise(paths[peer]):
as_name = cymruwhois_query['AS'+previous_asn].owner
print(as_name)
edge_tuple = (previous_asn, asn)
color = "#%x" % random.randint(0, 16777215)
if edge_tuple not in edges:
edge = pydot.Edge(*edge_tuple)
edge.set_style("dashed")
edge.set_color(color)
dot_graph.add_edge(edge)
edges[edge_tuple] = edge
if previous_asn not in nodes:
nodes[previous_asn] = pydot.Node(previous_asn)
label = 'AS' + previous_asn + '\n' + as_name
nodes[previous_asn].set_label(label)
dot_graph.add_node(nodes[previous_asn])
current_time = time.localtime()
filename = '{}-{}-{}-{}-{}-{}.png'.format(
"{:04d}".format(current_time.tm_year),
"{:02d}".format(current_time.tm_mon),
"{:02d}".format(current_time.tm_mday),
"{:02d}".format(current_time.tm_hour),
"{:02d}".format(current_time.tm_min),
args.route.replace('/', '-')
)
dot_graph.write_png(filename)