diff options
author | Rob Austein <sra@hactrn.net> | 2007-08-12 03:04:03 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2007-08-12 03:04:03 +0000 |
commit | eba8fc672bf69b608e759daa9d20aa48e1b88b88 (patch) | |
tree | 57484cc973a58a5597fb0bbdfd88e837ca01359d /scripts/rpki/resource_set.py | |
parent | c866ab06942baf21404c25128c2858d639fd4092 (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.py | 141 |
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) |