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
|
# $Id$
# Copyright (C) 2012 SPARTA, Inc. a Parsons Company
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
import sys, itertools, re
import struct
import _mysql_exceptions
from django.db import transaction, connection
from rpki.resource_set import resource_range_ipv4, resource_range_ipv6
import rpki.gui.app.timestamp
f = open(sys.argv[1])
prefixes = {}
ip_re = re.compile(r'^[0-9a-fA-F:.]+/\d{1,3}$')
class InvalidPrefix(Exception):
pass
last_prefix = None
last_asn = None
for row in itertools.islice(f, 5, None):
try:
cols = row.split()
prefix = cols[1]
# index -1 is i/e/? for igp/egp
origin_as = cols[-2]
# FIXME: skip AS_SETs
if origin_as[0] == '{':
continue
# the output may contain multiple paths to the same origin.
# if this is the same prefix as the last entry, we don't need
# to validate it again.
if prefix != last_prefix:
# validate the prefix since the "sh ip bgp" output is sometimes corrupt
# by no space between the prefix and the next hop IP address.
if not ip_re.match(prefix):
net, bits = prefix.split('/')
if len(bits) > 2 and int(bits[0]) <= 3:
print 'mask for %s looks fishy...' % prefix,
prefix = '%s/%s' % (net, bits[0:2])
print 'assuming it should be %s' % prefix
if not ip_re.match(prefix):
raise InvalidPrefix(prefix)
last_prefix = prefix
elif origin_as == last_asn:
# we are only interested in origins, so skip alternate paths
# to same origin as last entry.
continue
last_asn = origin_as
asns = prefixes.get(prefix)
if not asns:
asns = set()
prefixes[prefix] = asns
asns.add(int(origin_as))
except InvalidPrefix, e:
print >>sys.stderr, 'skipping bad entry: ' + row,
print >>sys.stderr, e
f.close()
def commit():
cursor = connection.cursor()
try:
print 'Dropping existing staging table...'
cursor.execute('DROP TABLE IF EXISTS routeview_routeorigin_new')
except _mysql_exceptions.Warning:
pass
print 'Creating staging table...'
cursor.execute('CREATE TABLE routeview_routeorigin_new LIKE routeview_routeorigin')
print 'Disabling autocommit...'
cursor.execute('SET autocommit=0')
print 'Adding rows to table...'
for prefix, asns in prefixes.iteritems():
family = 6 if ':' in prefix else 4
cls = resource_range_ipv6 if family == 6 else resource_range_ipv4
rng = cls.parse_str(prefix)
if family == 4:
xform = long
else:
xform = lambda v: struct.pack('!QQ', (long(v) >> 64) &0xffffffffffffffffL, long(v) & 0xFFFFFFFFFFFFFFFFL)
cursor.executemany("INSERT INTO routeview_routeorigin_new SET asn=%s, prefix_min=%s, prefix_max=%s",
[(asn, xform(rng.min), xform(rng.max)) for asn in asns])
print 'Committing...'
cursor.execute('COMMIT')
try:
print 'Dropping old table...'
cursor.execute('DROP TABLE IF EXISTS routeview_routeorigin_old')
except _mysql_exceptions.Warning:
pass
print 'Swapping staging table with live table...'
cursor.execute('RENAME TABLE routeview_routeorigin TO routeview_routeorigin_old, routeview_routeorigin_new TO routeview_routeorigin')
transaction.commit_unless_managed()
commit()
print 'Updating timestamp metadata...'
rpki.gui.app.timestamp.update('bgp_v4_import')
sys.exit(0)
|