ring.py: adding support for https://lg.ring.nlnog.net
This commit is contained in:
parent
46a90db4f9
commit
0609194aac
93
ring.py
Executable file
93
ring.py
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
import pydot
|
||||
import random
|
||||
import time
|
||||
import urllib.request
|
||||
from dns import resolver
|
||||
|
||||
parser = argparse.ArgumentParser(description='''
|
||||
Draw a graph from ring 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 = {}
|
||||
|
||||
ring_json = urllib.request.urlopen(f'http://lg02.infra.ring.nlnog.net/bgplgd/rib?prefix={args.route}')
|
||||
|
||||
ring_data = json.load(ring_json)
|
||||
prefix = ring_data['rib'][0]['prefix']
|
||||
for peer in ring_data['rib']:
|
||||
path = []
|
||||
for asn in peer['aspath'].split():
|
||||
path.append(asn)
|
||||
path.append(prefix)
|
||||
paths[peer['neighbor']['description']] = path
|
||||
|
||||
#json_graph = json.JSONEncoder().encode(paths)
|
||||
nodes = {}
|
||||
edges = {}
|
||||
|
||||
dot_graph = pydot.Dot('BGPMAP', graph_type='digraph')
|
||||
|
||||
resolv = resolver.Resolver()
|
||||
resolv.timeout = 0.5
|
||||
|
||||
for peer in paths:
|
||||
print(peer, paths[peer])
|
||||
|
||||
string_prepended_path = ['AS'+v for v in paths[peer][:-1]]
|
||||
print(string_prepended_path)
|
||||
|
||||
for previous_asn, asn in pairwise(paths[peer]):
|
||||
|
||||
try:
|
||||
as_name = resolv.query(f"AS{previous_asn}.asn.cymru.com", "TXT")
|
||||
as_name = as_name.response.answer[0].to_text().split('|')[4]
|
||||
as_name = as_name.strip().replace("'","").replace('"','')
|
||||
except Exception as e:
|
||||
print(e, previous_asn)
|
||||
as_name = ''
|
||||
|
||||
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)
|
Loading…
Reference in a new issue