add a ripedb based AS-SET resolver; it fetches AS sets, reads their AS
number members, and for each of those fetches the originating routes. These are our peers at CIXP/SWISSIX/TIX and their own routes (not their customer routes). git-svn-id: svn+ssh://svn.ipng.nl/usr/share/subversion/repositories/ircnet.ipng.ch@16 c5d60b8d-fdcb-4146-b734-af4215e9eb71
This commit is contained in:
178
ripedb/asset_ilines.py
Executable file
178
ripedb/asset_ilines.py
Executable file
@ -0,0 +1,178 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""The purpose of this script is to take the RIPE NCC's routing database
|
||||
and transform a comma separated list of AS-SETs (-as-sets) into IRCnet's
|
||||
I-Line structure. It will look at all ipv4 and ipv6 route objects in a
|
||||
certain AS number, and it finds the AS numbers by expanding the AS-SET
|
||||
members. It uses the class speficied on the commandline (-class)
|
||||
Example usage:
|
||||
$ asset_ilines.py -as-sets AS-IP-MAN-PEERING-CIXP,AS-IP-MAN-PEERING-TIX \
|
||||
-class 210 -output ilines.as-set.conf
|
||||
"""
|
||||
|
||||
import getopt
|
||||
import sys
|
||||
import types
|
||||
import time
|
||||
import os
|
||||
import getpass
|
||||
import socket
|
||||
import re
|
||||
|
||||
def usage():
|
||||
print """Usage:
|
||||
-h (-help): Help, this message
|
||||
-a (-as-sets): The (comma separeted list of) AS set(s) to resolve
|
||||
-o (-output): The output file to write
|
||||
-y (-class): The Y-line class to put the I line in (default: 200)"""
|
||||
pass
|
||||
|
||||
def asn_to_route(_asn, _whois_server = "whois.ripe.net",
|
||||
_prerequest_sleep_time = 1):
|
||||
list = []
|
||||
time.sleep(_prerequest_sleep_time)
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.connect((_whois_server, 43))
|
||||
except:
|
||||
return list
|
||||
ifile = s.makefile('w')
|
||||
ifile.write('-i origin AS'+_asn+'\r\n')
|
||||
ifile.flush()
|
||||
print("Fetching route/route6 from %s on %s" % (_asn, _whois_server))
|
||||
while True:
|
||||
line = ifile.readline()
|
||||
if not line:
|
||||
break
|
||||
matches = re.search('^route6?:[\s]*([0-9a-fA-F.:/]+)', line)
|
||||
if not matches:
|
||||
continue
|
||||
list.append(matches.group(1))
|
||||
ifile.close()
|
||||
print("%d route/route6 object(s) found for AS%s" % (len(list), _asn))
|
||||
return list
|
||||
|
||||
def asset_to_asn(_asset, _whois_server = "whois.ripe.net",
|
||||
_prerequest_sleep_time = 1):
|
||||
list = []
|
||||
time.sleep(_prerequest_sleep_time)
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.connect((_whois_server, 43))
|
||||
except:
|
||||
return list
|
||||
ifile = s.makefile('w')
|
||||
ifile.write(_asset+'\r\n')
|
||||
ifile.flush()
|
||||
print("Fetching %s from %s" % (_asset, _whois_server))
|
||||
|
||||
while True:
|
||||
line = ifile.readline()
|
||||
if not line:
|
||||
break
|
||||
matches = re.search('^members:.*AS([0-9]+)', line)
|
||||
if not matches:
|
||||
continue
|
||||
list.append(matches.group(1))
|
||||
ifile.close()
|
||||
print("%d AS numbers found for %s" % (len(list), _asset))
|
||||
return list
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "ha:o:y:",
|
||||
["help", "assets=", "output=", "class="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err) # will print something like "option -foo not recognized"
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
_assets = ["AS-IP-MAN-PEERING-TIX", "AS-IP-MAN-PEERING-CIXP",
|
||||
"AS-IP-MAN-PEERING-SWISSIX"]
|
||||
_class = 200
|
||||
_output = None
|
||||
|
||||
for o,a in opts:
|
||||
if o == "-h" or o == "-help":
|
||||
usage()
|
||||
sys.exit(2)
|
||||
elif o == "-a" or o == "-as-sets":
|
||||
_assets = a.split(',')
|
||||
elif o == "-o" or o == "-output":
|
||||
_output = a
|
||||
elif o == "-y" or o == "-class":
|
||||
_class = int(a)
|
||||
else:
|
||||
assert False, "unhandled option(s)"
|
||||
|
||||
# Check input args a bit
|
||||
if _output == None:
|
||||
usage()
|
||||
assert False, "-o (-output) Must set output file"
|
||||
if type(_class) != types.IntType:
|
||||
usage()
|
||||
assert False, "-y (-class) must be an integer"
|
||||
if len(_assets) < 1:
|
||||
usage()
|
||||
assert False, "-a (-as-sets) must be a list of AS-SETs"
|
||||
|
||||
try:
|
||||
ofile = open(_output, "w")
|
||||
except:
|
||||
assert False, "Coult not open output file"
|
||||
|
||||
_data = {'as-set': {}, 'asn': {}}
|
||||
for _asset in _assets:
|
||||
asn_list = asset_to_asn (_asset)
|
||||
_data['as-set'][_asset] = asn_list
|
||||
for _asn in asn_list:
|
||||
if _asn in _data['asn']:
|
||||
continue
|
||||
_data['asn'][_asn] = []
|
||||
|
||||
all_route_list = []
|
||||
for _asn in _data['asn'].keys():
|
||||
route_list = asn_to_route (_asn)
|
||||
for _route in route_list:
|
||||
if _route in all_route_list:
|
||||
continue
|
||||
_data['asn'][_asn].append(_route)
|
||||
all_route_list = list(set(all_route_list + route_list))
|
||||
|
||||
# print(_data)
|
||||
print("Objects found: %d route/route6, %d ASn, %d as-set" %
|
||||
(len(all_route_list), len(_data['asn']), len(_assets)))
|
||||
|
||||
ofile.write("# File generated on %s by %s@%s\n" %
|
||||
(time.asctime(time.localtime(time.time())),
|
||||
getpass.getuser(), socket.gethostname()))
|
||||
ofile.write("# Commandline: %s\n" % ' '.join(sys.argv))
|
||||
ofile.write("# assets=%s output=%s class=%s\n" %
|
||||
(','.join(_assets), _output, _class))
|
||||
|
||||
ofile.write("# Objects found: %d route/route6, %d ASn, %d as-set\n\n" %
|
||||
(len(all_route_list), len(_data['asn']), len(_assets)))
|
||||
|
||||
for _asset in _data['as-set']:
|
||||
ofile.write("# %s: %s\n" %
|
||||
(_asset, ', '.join(_data['as-set'][_asset])))
|
||||
ofile.write("#\n\n")
|
||||
|
||||
output_linecount = 0
|
||||
for _asn in _data['asn']:
|
||||
ofile.write("# AS%s (%d lines)\n" %
|
||||
(_asn, len(_data['asn'][_asn])))
|
||||
for _route in _data['asn'][_asn]:
|
||||
ofile.write("I%%*@%s%%%%%%%%%d%%%%\n" %
|
||||
(_route, _class))
|
||||
output_linecount = output_linecount + 1
|
||||
ofile.write("\n")
|
||||
ofile.write("# Output %d I-lines\n" % (output_linecount))
|
||||
|
||||
ofile.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user