-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinvalid-rpki-routes.py.orig
executable file
·145 lines (124 loc) · 4.33 KB
/
invalid-rpki-routes.py.orig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python
################################################################
# (c) CarlosM [email protected]
#
# 2019-04-18
################################################################
import pytricia
import sqlite3
import logging
import fire
import collections
import pysnooper
dbfile = "../../data/netdata-latest.db"
# cc = 'AR'
rir = 'lacnic'
type = 'ipv4'
maxLen = 24
class netdatadb:
def __init__(self, wdb):
try:
self.con = sqlite3.connect(wdb)
self.con.row_factory = sqlite3.Row
except:
self.conf = False
raise
# end init
def runsql(self, wsql):
self.cur = self.con.cursor()
self.cur.execute(wsql)
return self.cur
# end runsql
# def getOneValue(self, wsql):
# self.cur = self.con.cursor()
# self.cur.execute(wsql)
# for x in self.cur:
# val = x.pop(0)
# return val
# # end getOneValue
# end netdatadb
class counters:
def __init__(self):
self.cnt = {}
# end
def set(self, wkey, wval):
self.cnt[wkey] = wval
# end
def get(self, wkey):
return self.cnt.get(wkey, 0)
# end
def inc(self, wkey, winc=1):
self.cnt[wkey] = self.cnt[wkey] + winc
# end counters
# begin assignValidityStatus
# @pysnooper.snoop(depth=2)
def assignValidityStatus(wroas_trie, wpfx):
vs = "unknown"
roas = wroas_trie.get(wpfx['prefix'], None)
if roas == None:
return vs, None
for roa in roas:
if roa['origin_as2'] == wpfx['origin_as']:
if wpfx['pfxlen']>=roa['pfxlen'] and wpfx['pfxlen']<=roa['maxlen']:
vs = "valid"
break
else:
vs = "invalid"
else:
vs = "invalid"
return vs, roas
# end assignValidityStatus
if __name__ == "__main__":
logging.basicConfig( level=logging.INFO )
stats = counters()
logging.debug("Finding RPKI invalid routes - 20190418")
#
ndb = netdatadb(dbfile)
# load roadata into pytricia
logging.info("Loading ROAs into pytricia")
roadata_pyt = pytricia.PyTricia(48)
sql_roas = "SELECT * FROM roadata WHERE ta LIKE '%lacnic%' AND type='{}' " \
.format(type)
stats.set('nroas', 0)
for e in ndb.runsql(sql_roas):
pfx = str(e['prefix'])
logging.debug("loading ROA for {} origin {}".format(pfx, e['origin_as']))
if roadata_pyt.get(pfx, None) == None:
roadata_pyt[pfx] = [e]
else:
roadata_pyt[pfx].append(e)
stats.inc('nroas')
#
logging.info("Loaded {} ROAS into trie".format(stats.get('nroas')) )
# read routes and look for covering roas, logi assumes that most if not all ROAs will
# protect _more specific_ prefixes than the ones listed in roas
stats.set('ninvalid', 0)
stats.set('nvalid', 0)
stats.set('nunknown', 0)
stats.set('nroutes', 0)
for x in ndb.runsql("SELECT * FROM riswhois WHERE type='{}' AND pfxlen <={} ".format(type, maxLen)):
stats.inc('nroutes')
rpfx = str(x['prefix'])
(rov_status, roas) = assignValidityStatus(roadata_pyt, x)
if rov_status == "valid":
# logging.debug("prefix {} has ROV status VALID, rt_as={}, roa_as={}, roa_pfx={}" \
# .format( rpfx, x['origin_as'], roa['origin_as2'], roa['prefix'] ) )
stats.inc('nvalid')
elif rov_status == "invalid":
# logging.info("prefix {} has ROV status INVALID, rt_as={}, roa_as={}, roa_pfx={}" \
# .format( rpfx, x['origin_as'], roa['origin_as2'], roa['prefix'] ) )
<<<<<<< HEAD
logging.info("prefix {} has ROV status INVALID (showing first ROA only), adv_as={}, roa_as={}, roa_pfx={} " \
.format( rpfx, x['origin_as'], roas[0]['origin_as2'], roas[0]['prefix'] ) )
=======
logging.info("route to prefix {} has ROV status INVALID" \
.format( rpfx ) )
>>>>>>> 2d8ef11fee12a7e313bf0070d6d2bed444ee4b15
stats.inc('ninvalid')
elif rov_status == "unknown":
stats.inc('nunknown')
logging.info("Found {} TOTAL routes".format(stats.get('nroutes')) )
logging.info("Found {} valid routes".format(stats.get('nvalid')) )
logging.info("Found {} invalid routes".format(stats.get('ninvalid')) )
logging.info("Found {} unknown routes".format(stats.get('nunknown')) )
# end script