aboutsummaryrefslogtreecommitdiff
path: root/scripts/rpki/resource_set.py
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2007-08-12 03:04:03 +0000
committerRob Austein <sra@hactrn.net>2007-08-12 03:04:03 +0000
commiteba8fc672bf69b608e759daa9d20aa48e1b88b88 (patch)
tree57484cc973a58a5597fb0bbdfd88e837ca01359d /scripts/rpki/resource_set.py
parentc866ab06942baf21404c25128c2858d639fd4092 (diff)
Doc
svn path=/scripts/generate-testrepo.py; revision=868
Diffstat (limited to 'scripts/rpki/resource_set.py')
-rw-r--r--scripts/rpki/resource_set.py141
1 files changed, 66 insertions, 75 deletions
diff --git a/scripts/rpki/resource_set.py b/scripts/rpki/resource_set.py
index c5e71eb6..518a65b9 100644
--- a/scripts/rpki/resource_set.py
+++ b/scripts/rpki/resource_set.py
@@ -1,11 +1,22 @@
# $Id$
+"""Classes dealing with sets of resources.
+
+The basic mechanics of a resource set are the same for any of the
+resources we handle (ASNs, IPv4 addresses, or IPv6 addresses), so we
+can provide the same operations on any of them, even though the
+underlying details vary.
+
+We also provide some basic set operations (union, intersection, etc).
+"""
+
import re, ipaddrs
class resource_range(object):
- """
- Generic resource range type. Assumes underlying type is some kind of integer.
- You probably don't want to use this type directly.
+ """Generic resource range type.
+
+ Assumes underlying type is some kind of integer. You probably don't
+ want to use this type directly.
"""
def __init__(self, min, max):
@@ -21,9 +32,9 @@ class resource_range(object):
return c
class resource_range_as(resource_range):
- """
- Range of Autonomous System Numbers.
- Denote a single ASN by a range whose min and max values are identical.
+ """Range of Autonomous System Numbers.
+
+ Denotes a single ASN by a range whose min and max values are identical.
"""
def __str__(self):
@@ -33,10 +44,10 @@ class resource_range_as(resource_range):
return str(self.min) + "-" + str(self.max)
class resource_range_ip(resource_range):
- """
- Range of (generic) IP addresses. Prefixes are converted to ranges
- on input, and ranges that can be represented as prefixes are written
- as prefixes on output.
+ """Range of (generic) IP addresses.
+
+ Prefixes are converted to ranges on input, and ranges that can be
+ represented as prefixes are written as prefixes on output.
"""
def __str__(self):
@@ -51,18 +62,15 @@ class resource_range_ip(resource_range):
return str(self.min) + "/" + str(prefixlen)
class resource_range_ipv4(resource_range_ip):
- """
- Range of IPv4 addresses.
- """
+ """Range of IPv4 addresses."""
pass
class resource_range_ipv6(resource_range_ip):
- """
- Range of IPv6 addresses.
- """
+ """Range of IPv6 addresses."""
pass
-def rsplit(rset, that):
+def _rsplit(rset, that):
+ """Split a resource range into two resource ranges."""
this = rset.pop(0)
cell_type = type(this.min)
assert type(this) is type(that) and type(this.max) is cell_type and type(that.min) is cell_type and type(that.max) is cell_type
@@ -75,9 +83,10 @@ def rsplit(rset, that):
rset.insert(1, type(this)(cell_type(that.max + 1), this.max))
class resource_set(list):
- """
- Generic resource set. List type containing resource ranges. You
- probably don't want to use this type directly.
+ """Generic resource set.
+
+ List type containing resource ranges. You probably don't want to
+ use this type directly.
"""
def __init__(self, ini=None):
@@ -97,12 +106,13 @@ class resource_set(list):
def __str__(self):
return ",".join(map(str, self))
- def comm(self, other):
- """
- Like comm(1), sort of. Returns a tuple of three resource sets:
- resources only in self, resources only in other, and resources in
- both. Used (not very efficiently) as the basis for most set
- operations on resource sets.
+ def _comm(self, other):
+ """Like comm(1), sort of.
+
+ Returns a tuple of three resource sets: resources only in self,
+ resources only in other, and resources in both. Used (not very
+ efficiently) as the basis for most set operations on resource
+ sets.
"""
assert type(self) is type(other)
set1 = self[:]
@@ -114,13 +124,13 @@ class resource_set(list):
elif set2 and (not set1 or set2[0].max < set1[0].min):
only2.append(set2.pop(0))
elif set1[0].min < set2[0].min:
- rsplit(set1, set2[0])
+ _rsplit(set1, set2[0])
elif set2[0].min < set1[0].min:
- rsplit(set2, set1[0])
+ _rsplit(set2, set1[0])
elif set1[0].max < set2[0].max:
- rsplit(set2, set1[0])
+ _rsplit(set2, set1[0])
elif set2[0].max < set1[0].max:
- rsplit(set1, set2[0])
+ _rsplit(set1, set2[0])
else:
assert set1[0].min == set2[0].min and set1[0].max == set2[0].max
both.append(set1.pop(0))
@@ -128,9 +138,7 @@ class resource_set(list):
return type(self)(only1), type(self)(only2), type(self)(both)
def union(self, other):
- """
- Set union for resource sets.
- """
+ """Set union for resource sets."""
assert type(self) is type(other)
set1 = self[:]
set2 = other[:]
@@ -152,28 +160,20 @@ class resource_set(list):
return type(self)(result)
def intersection(self, other):
- """
- Set intersection for resource sets.
- """
- return self.comm(other)[2]
+ """Set intersection for resource sets."""
+ return self._comm(other)[2]
def difference(self, other):
- """
- Set difference for resource sets.
- """
- return self.comm(other)[0]
+ """Set difference for resource sets."""
+ return self._comm(other)[0]
def symmetric_difference(self, other):
- """
- Set symmetric difference (XOR) for resource sets.
- """
- com = self.comm(other)
+ """Set symmetric difference (XOR) for resource sets."""
+ com = self._comm(other)
return com[0].union(com[1])
def contains(self, item):
- """
- Set membership test for resource sets.
- """
+ """Set membership test for resource sets."""
for i in self:
if isinstance(item, type(i)) and i.min <= item.min and i.max >= item.max:
return True
@@ -184,11 +184,10 @@ class resource_set(list):
return False
class resource_set_as(resource_set):
- """
- ASN resource set.
- """
+ """ASN resource set."""
def parse_str(self, x):
+ """Parse AS resource sets from text (eg, XML attributes)."""
r = re.match("^([0-9]+)-([0-9]+)$", x)
if r:
return resource_range_as(long(r.group(1)), long(r.group(2)))
@@ -196,6 +195,7 @@ class resource_set_as(resource_set):
return resource_range_as(long(x), long(x))
def parse_tuple(self, x):
+ """Parse AS resource sets from intermediate form generated by ASN.1 decoder."""
assert x[0] == "asIdsOrRanges" # Not handling "inherit" yet
for aor in x[1]:
if aor[0] == "range":
@@ -207,12 +207,13 @@ class resource_set_as(resource_set):
self.append(resource_range_as(min, max))
class resource_set_ip(resource_set):
- """
- (Generic) IP address resource set.
+ """(Generic) IP address resource set.
+
You probably don't want to use this type directly.
"""
def parse_str(self, x):
+ """Parse IP address resource sets from text (eg, XML attributes)."""
r = re.match("^([0-9:.a-fA-F]+)-([0-9:.a-fA-F]+)$", x)
if r:
return self.range_type(self.addr_type(r.group(1)), self.addr_type(r.group(2)))
@@ -227,52 +228,41 @@ class resource_set_ip(resource_set):
raise RuntimeError, 'Bad IP resource "%s"' % (x)
def parse_tuple(self, x):
+ """Parse IP address resource sets from intermediate form generated by ASN.1 decoder."""
assert x[0] == "addressesOrRanges" # Not handling "inherit" yet
for aor in x[1]:
if aor[0] == "addressRange":
- min = bs2long(aor[1][0]) << (self.addr_type.bits - len(aor[1][0]))
- max = bs2long(aor[1][1]) << (self.addr_type.bits - len(aor[1][1]))
+ min = _bs2long(aor[1][0]) << (self.addr_type.bits - len(aor[1][0]))
+ max = _bs2long(aor[1][1]) << (self.addr_type.bits - len(aor[1][1]))
mask = (1L << (self.addr_type.bits - len(aor[1][1]))) - 1
else:
- min = bs2long(aor[1]) << (self.addr_type.bits - len(aor[1]))
+ min = _bs2long(aor[1]) << (self.addr_type.bits - len(aor[1]))
mask = (1L << (self.addr_type.bits - len(aor[1]))) - 1
assert (min & mask) == 0, "Resource not in canonical form: %s" % (str(x))
max = min | mask
self.append(self.range_type(self.addr_type(min), self.addr_type(max)))
class resource_set_ipv4(resource_set_ip):
- """
- IPv4 address resource set.
- """
+ """IPv4 address resource set."""
addr_type = ipaddrs.v4addr
range_type = resource_range_ipv4
class resource_set_ipv6(resource_set_ip):
- """
- IPv6 address resource set.
- """
+ """IPv6 address resource set."""
addr_type = ipaddrs.v6addr
range_type = resource_range_ipv6
-def bs2long(bs):
- """
- Convert a bitstring (tuple representation) into a long.
- """
-
+def _bs2long(bs):
+ """Convert a bitstring (tuple representation) into a long."""
return reduce(lambda x, y: (x << 1) | y, bs, 0L)
def parse_extensions(exts):
- """
- Parse RFC 3779 extensions out of the tuple encoding returned by
- POW.pkix.cert.getExtensions().
- """
-
+ """Parse RFC 3779 extensions from intermediate form returned by ASN.1 decoder."""
as = None
v4 = None
v6 = None
-
for x in exts:
if x[0] == (1, 3, 6, 1, 5, 5, 7, 1, 8): # sbgp-autonomousSysNum
assert x[2][1] is None, "RDI not implemented: %s" % (str(x))
@@ -293,13 +283,14 @@ def parse_extensions(exts):
if __name__ == "__main__":
def test(t, s1, s2):
+ """Lame unit test."""
print
r1 = t(s1)
r2 = t(s2)
print "x: ", r1
print "y: ", r2
- v1 = r1.comm(r2)
- v2 = r2.comm(r1)
+ v1 = r1._comm(r2)
+ v2 = r2._comm(r1)
assert v1[0] == v2[1] and v1[1] == v2[0] and v1[2] == v2[2]
for i in r1: assert r1.contains(i) and r1.contains(i.min) and r1.contains(i.max)
for i in r2: assert r2.contains(i) and r2.contains(i.min) and r2.contains(i.max)