diff options
author | David Moss <drkjam@gmail.com> | 2015-08-28 23:14:52 +0100 |
---|---|---|
committer | David Moss <drkjam@gmail.com> | 2015-08-28 23:14:52 +0100 |
commit | 6bb599cd44230340338ffe899287edd06e055f55 (patch) | |
tree | 28c1e6e150ed693f2a44d829d50b5f673ae6b5ee | |
parent | 568ed3b8253f6b2391b295fdedf455a221bc82ee (diff) | |
download | netaddr-6bb599cd44230340338ffe899287edd06e055f55.tar.gz |
Completed #109 - lookup of IPv6 unicast allocations
-rw-r--r-- | Makefile | 1 | ||||
-rwxr-xr-x | netaddr/ip/iana.py | 123 | ||||
-rw-r--r-- | netaddr/ip/ipv6-unicast-address-assignments.xml | 446 | ||||
-rw-r--r-- | netaddr/tests/ip/test_ip_v6.py | 13 |
4 files changed, 527 insertions, 56 deletions
@@ -51,6 +51,7 @@ download: cd netaddr/ip/ && wget -N http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml cd netaddr/ip/ && wget -N http://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xml cd netaddr/ip/ && wget -N http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xml + cd netaddr/ip/ && wget -N http://www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xml register: @echo 'releasing netaddr' diff --git a/netaddr/ip/iana.py b/netaddr/ip/iana.py index 7e63ac1..6338ec2 100755 --- a/netaddr/ip/iana.py +++ b/netaddr/ip/iana.py @@ -29,22 +29,21 @@ More details can be found at the following URLs :- - IEEE Protocols Information Home Page - http://www.iana.org/protocols/ """ -import os as _os import os.path as _path import sys as _sys - from xml.sax import make_parser, handler -from netaddr.core import Publisher, Subscriber, dos2unix +from netaddr.core import Publisher, Subscriber from netaddr.ip import IPAddress, IPNetwork, IPRange, cidr_abbrev_to_verbose - from netaddr.compat import _dict_items, _callable + #: Topic based lookup dictionary for IANA information. IANA_INFO = { 'IPv4': {}, 'IPv6': {}, + 'IPv6_unicast': {}, 'multicast': {}, } @@ -221,6 +220,42 @@ class IPv6Parser(XMLRecordParser): return record +class IPv6UnicastParser(XMLRecordParser): + """ + A XMLRecordParser that understands how to parse and retrieve data records + from the IANA IPv6 unicast address assignments file. + + It can be found online here :- + + - http://www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xml + """ + def __init__(self, fh, **kwargs): + """ + Constructor. + + fh - a valid, open file handle to an IANA IPv6 address space file. + + kwargs - additional parser options. + """ + super(IPv6UnicastParser, self).__init__(fh) + + def process_record(self, rec): + """ + Callback method invoked for every record. + + See base class method for more details. + """ + record = { + 'status': str(rec.get('status', '')).strip(), + 'description': str(rec.get('description', '')).strip(), + 'prefix': str(rec.get('prefix', '')).strip(), + 'date': str(rec.get('date', '')).strip(), + 'whois': str(rec.get('whois', '')).strip(), + } + + return record + + class MulticastParser(XMLRecordParser): """ A XMLRecordParser that knows how to process the IANA IPv4 multicast address @@ -305,6 +340,9 @@ class DictUpdater(Subscriber): elif self.topic == 'IPv6': cidr = IPNetwork(cidr_abbrev_to_verbose(data_id)) self.dct[cidr] = data + elif self.topic == 'IPv6_unicast': + cidr = IPNetwork(data_id) + self.dct[cidr] = data elif self.topic == 'multicast': iprange = None if '-' in data_id: @@ -334,6 +372,10 @@ def load_info(): ipv6.attach(DictUpdater(IANA_INFO['IPv6'], 'IPv6', 'prefix')) ipv6.parse() + ipv6ua = IPv6UnicastParser(open(_path.join(PATH, 'ipv6-unicast-address-assignments.xml'))) + ipv6ua.attach(DictUpdater(IANA_INFO['IPv6_unicast'], 'IPv6_unicast', 'prefix')) + ipv6ua.parse() + mcast = MulticastParser(open(_path.join(PATH, 'multicast-addresses.xml'))) mcast.attach(DictUpdater(IANA_INFO['multicast'], 'multicast', 'address')) mcast.parse() @@ -356,77 +398,46 @@ def pprint_info(fh=None): fh.write('%-45r' % (iprange) + details + "\n") -def query(ip_addr): - """ - Returns informational data specific to this IP address. - """ - info = {} +def _within_bounds(ip, ip_range): + # Boundary checking for multiple IP classes. + if hasattr(ip_range, 'first'): + # IP network or IP range. + return ip in ip_range + elif hasattr(ip_range, 'value'): + # IP address. + return ip == ip_range + + raise Exception('Unsupported IP range or address: %r!' % ip_range) - def within_bounds(ip, ip_range): - # Boundary checking for multiple IP classes. - if hasattr(ip_range, 'first'): - # IP network or IP range. - return ip in ip_range - elif hasattr(ip_range, 'value'): - # IP address. - return ip == ip_range - raise Exception('Unsupported IP range or address: %r!' % ip_range) +def query(ip_addr): + """Returns informational data specific to this IP address.""" + info = {} if ip_addr.version == 4: for cidr, record in _dict_items(IANA_INFO['IPv4']): - if within_bounds(ip_addr, cidr): + if _within_bounds(ip_addr, cidr): info.setdefault('IPv4', []) info['IPv4'].append(record) if ip_addr.is_multicast(): for iprange, record in _dict_items(IANA_INFO['multicast']): - if within_bounds(ip_addr, iprange): + if _within_bounds(ip_addr, iprange): info.setdefault('Multicast', []) info['Multicast'].append(record) elif ip_addr.version == 6: for cidr, record in _dict_items(IANA_INFO['IPv6']): - if within_bounds(ip_addr, cidr): + if _within_bounds(ip_addr, cidr): info.setdefault('IPv6', []) info['IPv6'].append(record) - return info + for cidr, record in _dict_items(IANA_INFO['IPv6_unicast']): + if _within_bounds(ip_addr, cidr): + info.setdefault('IPv6_unicast', []) + info['IPv6_unicast'].append(record) - -def get_latest_files(): - """Download the latest files from IANA""" - if _sys.version_info[0] == 3: - # Python 3.x - from urllib.request import Request, urlopen - else: - # Python 2.x - from urllib2 import Request, urlopen - - urls = [ - 'http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml', - 'http://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xml', - 'http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xml', - ] - - for url in urls: - _sys.stdout.write('downloading latest copy of %s\n' % url) - request = Request(url) - response = urlopen(request) - save_path = _path.dirname(__file__) - basename = _os.path.basename(response.geturl().rstrip('/')) - filename = _path.join(save_path, basename) - fh = open(filename, 'wb') - fh.write(response.read()) - fh.close() - - # Make sure the line endings are consistent across platforms. - dos2unix(filename) - - -if __name__ == '__main__': - # Generate indices when module is executed as a script. - get_latest_files() + return info # On module import, read IANA data files and populate lookups dict. load_info() diff --git a/netaddr/ip/ipv6-unicast-address-assignments.xml b/netaddr/ip/ipv6-unicast-address-assignments.xml new file mode 100644 index 0000000..4f62e9d --- /dev/null +++ b/netaddr/ip/ipv6-unicast-address-assignments.xml @@ -0,0 +1,446 @@ +<?xml version='1.0' encoding='UTF-8'?> +<?xml-stylesheet type="text/xsl" href="ipv6-unicast-address-assignments.xsl"?> +<?oxygen RNGSchema="ipv6-unicast-address-assignments.rng" type="xml"?> +<registry xmlns="http://www.iana.org/assignments" id="ipv6-unicast-address-assignments"> + <title>IPv6 Global Unicast Address Assignments</title> + <category>Internet Protocol version 6 (IPv6) Global Unicast Allocations</category> + <updated>2015-08-10</updated> + <xref type="rfc" data="rfc7249"/> + <registration_rule>Allocations to RIRs are made in line with the Global Policy published at <xref type="uri" data="http://www.icann.org/en/resources/policy/global-addressing"/>. +All other assignments require IETF Review.</registration_rule> + <description>The allocation of Internet Protocol version 6 (IPv6) unicast address space is listed +here. References to the various other registries detailing the use of the IPv6 address +space can be found in the <xref type="registry" data="ipv6-address-space">IPv6 Address Space registry</xref>.</description> + <note>The assignable Global Unicast Address space is defined in <xref type="rfc" data="rfc4291"/> as being the address +block defined by the prefix 2000::/3. All address space in this block not listed in the +table below is reserved by IANA for future allocation.</note> + <record date="1999-07-01"> + <prefix>2001:0000::/23</prefix> + <description>IANA</description> + <whois>whois.iana.org</whois> + <status>ALLOCATED</status> + <notes>2001:0000::/23 is reserved for IETF Protocol Assignments <xref type="rfc" data="rfc2928"/>. +2001:0000::/32 is reserved for TEREDO <xref type="rfc" data="rfc4380"/>. +2001:0002::/48 is reserved for Benchmarking <xref type="rfc" data="rfc5180"/>. +2001:10::/28 is reserved for ORCHID <xref type="rfc" data="rfc4843"/>. +For complete registration details, see <xref type="registry" data="iana-ipv6-special-registry"/>.</notes> + </record> + <record date="1999-07-01"> + <prefix>2001:0000::/23</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes/> + </record> + <record date="1999-07-01"> + <prefix>2001:0400::/23</prefix> + <description>ARIN</description> + <whois>whois.arin.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.arin.net/registry</server> + <server>http://rdap.arin.net/registry</server> + </rdap> + <notes/> + </record> + <record date="1999-07-01"> + <prefix>2001:0600::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2002-05-02"> + <prefix>2001:0800::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2002-11-02"> + <prefix>2001:0a00::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2002-05-02"> + <prefix>2001:0c00::/23</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes>2001:db8::/32 reserved for Documentation <xref type="rfc" data="rfc3849"/>. +For complete registration details, see <xref type="registry" data="iana-ipv6-special-registry"/>.</notes> + </record> + <record date="2003-01-01"> + <prefix>2001:0e00::/23</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes/> + </record> + <record date="2002-11-01"> + <prefix>2001:1200::/23</prefix> + <description>LACNIC</description> + <whois>whois.lacnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.lacnic.net/rdap/</server> + </rdap> + <notes/> + </record> + <record date="2003-02-01"> + <prefix>2001:1400::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2003-07-01"> + <prefix>2001:1600::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2003-04-01"> + <prefix>2001:1800::/23</prefix> + <description>ARIN</description> + <whois>whois.arin.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.arin.net/registry</server> + <server>http://rdap.arin.net/registry</server> + </rdap> + <notes/> + </record> + <record date="2004-01-01"> + <prefix>2001:1a00::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-05-04"> + <prefix>2001:1c00::/22</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-05-04"> + <prefix>2001:2000::/20</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-05-04"> + <prefix>2001:3000::/21</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-05-04"> + <prefix>2001:3800::/22</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record> + <prefix>2001:3c00::/22</prefix> + <description>IANA</description> + <whois/> + <status>RESERVED</status> + <notes>2001:3c00::/22 is reserved for possible future allocation to the RIPE NCC.</notes> + </record> + <record date="2004-06-11"> + <prefix>2001:4000::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-06-01"> + <prefix>2001:4200::/23</prefix> + <description>AFRINIC</description> + <whois>whois.afrinic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.afrinic.net/rdap/</server> + <server>http://rdap.afrinic.net/rdap/</server> + </rdap> + <notes/> + </record> + <record date="2004-06-11"> + <prefix>2001:4400::/23</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-08-17"> + <prefix>2001:4600::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-08-24"> + <prefix>2001:4800::/23</prefix> + <description>ARIN</description> + <whois>whois.arin.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.arin.net/registry</server> + <server>http://rdap.arin.net/registry</server> + </rdap> + <notes/> + </record> + <record date="2004-10-15"> + <prefix>2001:4a00::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-12-17"> + <prefix>2001:4c00::/23</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-09-10"> + <prefix>2001:5000::/20</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-11-30"> + <prefix>2001:8000::/19</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes/> + </record> + <record date="2004-11-30"> + <prefix>2001:a000::/20</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes/> + </record> + <record date="2006-03-08"> + <prefix>2001:b000::/20</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes/> + </record> + <record date="2001-02-01"> + <prefix>2002:0000::/16</prefix> + <description>6to4</description> + <whois/> + <status>ALLOCATED</status> + <notes>2002::/16 is reserved for 6to4 <xref type="rfc" data="rfc3056"/>. +For complete registration details, see <xref type="registry" data="iana-ipv6-special-registry"/>.</notes> + </record> + <record date="2005-01-12"> + <prefix>2003:0000::/18</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes/> + </record> + <record date="2006-10-03"> + <prefix>2400:0000::/12</prefix> + <description>APNIC</description> + <whois>whois.apnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.apnic.net/</server> + </rdap> + <notes>2400:0000::/19 was allocated on 2005-05-20. 2400:2000::/19 was allocated on 2005-07-08. 2400:4000::/21 was +allocated on 2005-08-08. 2404:0000::/23 was allocated on 2006-01-19. The more recent allocation (2006-10-03) +incorporates all these previous allocations.</notes> + </record> + <record date="2006-10-03"> + <prefix>2600:0000::/12</prefix> + <description>ARIN</description> + <whois>whois.arin.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.arin.net/registry</server> + <server>http://rdap.arin.net/registry</server> + </rdap> + <notes>2600:0000::/22, 2604:0000::/22, 2608:0000::/22 and 260c:0000::/22 were allocated on 2005-04-19. The more +recent allocation (2006-10-03) incorporates all these previous allocations.</notes> + </record> + <record date="2005-11-17"> + <prefix>2610:0000::/23</prefix> + <description>ARIN</description> + <whois>whois.arin.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.arin.net/registry</server> + <server>http://rdap.arin.net/registry</server> + </rdap> + <notes/> + </record> + <record date="2006-09-12"> + <prefix>2620:0000::/23</prefix> + <description>ARIN</description> + <whois>whois.arin.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.arin.net/registry</server> + <server>http://rdap.arin.net/registry</server> + </rdap> + <notes/> + </record> + <record date="2006-10-03"> + <prefix>2800:0000::/12</prefix> + <description>LACNIC</description> + <whois>whois.lacnic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.lacnic.net/rdap/</server> + </rdap> + <notes>2800:0000::/23 was allocated on 2005-11-17. The more recent allocation (2006-10-03) incorporates the +previous allocation.</notes> + </record> + <record date="2006-10-03"> + <prefix>2a00:0000::/12</prefix> + <description>RIPE NCC</description> + <whois>whois.ripe.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.db.ripe.net/</server> + </rdap> + <notes>2a00:0000::/21 was originally allocated on 2005-04-19. 2a01:0000::/23 was allocated on 2005-07-14. +2a01:0000::/16 (incorporating the 2a01:0000::/23) was allocated on 2005-12-15. The more recent allocation +(2006-10-03) incorporates these previous allocations.</notes> + </record> + <record date="2006-10-03"> + <prefix>2c00:0000::/12</prefix> + <description>AFRINIC</description> + <whois>whois.afrinic.net</whois> + <status>ALLOCATED</status> + <rdap> + <server>https://rdap.afrinic.net/rdap/</server> + <server>http://rdap.afrinic.net/rdap/</server> + </rdap> + <notes/> + </record> + <record date="1999-07-01"> + <prefix>2d00:0000::/8</prefix> + <description>IANA</description> + <whois/> + <status>RESERVED</status> + <notes/> + </record> + <record date="1999-07-01"> + <prefix>2e00:0000::/7</prefix> + <description>IANA</description> + <whois/> + <status>RESERVED</status> + <notes/> + </record> + <record date="1999-07-01"> + <prefix>3000:0000::/4</prefix> + <description>IANA</description> + <whois/> + <status>RESERVED</status> + <notes/> + </record> + <record date="2008-04"> + <prefix>3ffe::/16</prefix> + <description>IANA</description> + <whois/> + <status>RESERVED</status> + <notes>3ffe:831f::/32 was used for Teredo in some old but widely distributed networking stacks. This usage is +deprecated in favor of 2001::/32, which was allocated for the purpose in <xref type="rfc" data="rfc4380"/>. +3ffe::/16 and 5f00::/8 were used for the 6bone but were returned. <xref type="rfc" data="rfc5156"/></notes> + </record> + <record date="2008-04"> + <prefix>5f00::/8</prefix> + <description>IANA</description> + <whois/> + <status>RESERVED</status> + <notes>3ffe::/16 and 5f00::/8 were used for the 6bone but were returned. <xref type="rfc" data="rfc5156"/></notes> + </record> + <people/> +</registry> diff --git a/netaddr/tests/ip/test_ip_v6.py b/netaddr/tests/ip/test_ip_v6.py index 2744844..fb19f19 100644 --- a/netaddr/tests/ip/test_ip_v6.py +++ b/netaddr/tests/ip/test_ip_v6.py @@ -118,3 +118,16 @@ def test_ipnetwork_pickling_v6(): assert cidr2.value == 281473902969344 assert cidr2.prefixlen == 120 assert cidr2.version == 6 + + +def test_ipv6_unicast_address_allocation_info(): + ip = IPNetwork('2001:1200::/23') + + assert ip.info.IPv6[0].allocation == 'Global Unicast' + assert ip.info.IPv6[0].prefix == '2000::/3' + assert ip.info.IPv6[0].reference == 'rfc4291' + + assert ip.info.IPv6_unicast[0].prefix == '2001:1200::/23' + assert ip.info.IPv6_unicast[0].description == 'LACNIC' + assert ip.info.IPv6_unicast[0].whois == 'whois.lacnic.net' + assert ip.info.IPv6_unicast[0].status == 'ALLOCATED' |