summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Stasiak <jakub@stasiak.at>2020-07-03 15:47:30 +0200
committerJakub Stasiak <jakub@stasiak.at>2020-07-03 15:47:30 +0200
commit67f1992e73dffdca15c2fd299d87923d27dd3b0f (patch)
tree5887c8de89031ce5fd0d3c5b85d3e863db1ad5e2
parent2ce9c813f78918968f6c1734b7d0ba524d4855a2 (diff)
downloadnetaddr-67f1992e73dffdca15c2fd299d87923d27dd3b0f.tar.gz
Revert "Handle RFC 6164 IPv6 addresses"
This reverts commit 2984c0a40a706ffadd6f22a7686f3f4f056e7f51. We've decided to temporarily revert this before the 0.8.0 release to let people know in advance that this behavior is going to change. 0.8.0 will include documentation mentioning this and the change will be reinstated in release 0.9.0.
-rw-r--r--netaddr/ip/__init__.py46
-rw-r--r--netaddr/tests/ip/test_ip_v4.py6
-rw-r--r--netaddr/tests/ip/test_ip_v6.py19
3 files changed, 28 insertions, 43 deletions
diff --git a/netaddr/ip/__init__.py b/netaddr/ip/__init__.py
index 86c1ed1..b57ef5f 100644
--- a/netaddr/ip/__init__.py
+++ b/netaddr/ip/__init__.py
@@ -1004,7 +1004,7 @@ class IPNetwork(BaseIP, IPListMixin):
@property
def broadcast(self):
"""The broadcast address of this `IPNetwork` object"""
- if (self._module.width - self._prefixlen) <= 1:
+ if self._module.version == 4 and (self._module.width - self._prefixlen) <= 1:
return None
else:
return IPAddress(self._value | self._hostmask_int, self._module.version)
@@ -1306,38 +1306,36 @@ class IPNetwork(BaseIP, IPListMixin):
A generator that provides all the IP addresses that can be assigned
to hosts within the range of this IP object's subnet.
- - for IPv4, the network and broadcast addresses are excluded, excepted \
- when using /31 or /32 subnets as per RFC 3021.
+ - for IPv4, the network and broadcast addresses are always excluded. \
+ for subnets that contains less than 4 IP addresses /31 and /32 \
+ report in a manner per RFC 3021
- - for IPv6, only Subnet-Router anycast address (first address in the \
- network) is excluded as per RFC 4291 section 2.6.1, excepted when using \
- /127 or /128 subnets as per RFC 6164.
+ - for IPv6, only the unspecified address '::' or Subnet-Router anycast \
+ address (first address in the network) is excluded.
:return: an IPAddress iterator
"""
it_hosts = iter([])
- # Common logic, first IP is always reserved.
- first_usable_address = self.first + 1
if self._module.version == 4:
- # IPv4 logic, last address is reserved for broadcast.
- last_usable_address = self.last - 1
- else:
- # IPv6 logic, no broadcast address reserved.
- last_usable_address = self.last
-
- # If subnet has a size of less than 4, then it is a /31, /32, /127 or /128.
- # Handle them as per RFC 3021 (IPv4) or RFC 6164 (IPv6), and don't reserve
- # first or last IP address.
- if self.size >= 4:
- it_hosts = iter_iprange(
- IPAddress(first_usable_address, self._module.version),
- IPAddress(last_usable_address, self._module.version))
+ # IPv4 logic.
+ if self.size >= 4:
+ it_hosts = iter_iprange(
+ IPAddress(self.first + 1, self._module.version),
+ IPAddress(self.last - 1, self._module.version))
+ else:
+ it_hosts = iter_iprange(
+ IPAddress(self.first, self._module.version),
+ IPAddress(self.last, self._module.version))
else:
- it_hosts = iter_iprange(
- IPAddress(self.first, self._module.version),
+ # IPv6 logic.
+ # RFC 4291 section 2.6.1 says that the first IP in the network is
+ # the Subnet-Router anycast address. This address cannot be
+ # assigned to a host, so use self.first+1.
+ if self.size >= 2:
+ it_hosts = iter_iprange(
+ IPAddress(self.first + 1, self._module.version),
IPAddress(self.last, self._module.version))
-
return it_hosts
def __str__(self):
diff --git a/netaddr/tests/ip/test_ip_v4.py b/netaddr/tests/ip/test_ip_v4.py
index f827704..f482d6d 100644
--- a/netaddr/tests/ip/test_ip_v4.py
+++ b/netaddr/tests/ip/test_ip_v4.py
@@ -260,6 +260,8 @@ def test_iterhosts_v4():
IPAddress('192.168.0.1'),
]
+ assert list(IPNetwork("1234::/128")) == [IPAddress('1234::')]
+ assert list(IPNetwork("1234::/128").iter_hosts()) == []
assert list(IPNetwork("192.168.0.0/31").iter_hosts()) == [IPAddress('192.168.0.0'),IPAddress('192.168.0.1')]
assert list(IPNetwork("192.168.0.0/32").iter_hosts()) == [IPAddress('192.168.0.0')]
@@ -511,6 +513,10 @@ def test_rfc3021_subnets():
assert IPNetwork('192.0.2.0/32').broadcast is None
assert list(IPNetwork('192.0.2.0/32').iter_hosts()) == [IPAddress('192.0.2.0')]
+ # IPv6 must not be affected
+ assert IPNetwork('abcd::/127').broadcast is not None
+ assert IPNetwork('abcd::/128').broadcast is not None
+
def test_ipnetwork_change_prefixlen():
ip = IPNetwork('192.168.0.0/16')
diff --git a/netaddr/tests/ip/test_ip_v6.py b/netaddr/tests/ip/test_ip_v6.py
index 395dcf3..412e15e 100644
--- a/netaddr/tests/ip/test_ip_v6.py
+++ b/netaddr/tests/ip/test_ip_v6.py
@@ -147,22 +147,3 @@ def test_ipv6_unicast_address_allocation_info():
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'
-
-def test_rfc6164_subnets():
- # Tests for /127 subnet
- assert list(IPNetwork('1234::/127')) == [
- IPAddress('1234::'),
- IPAddress('1234::1'),
- ]
- assert list(IPNetwork('1234::/127').iter_hosts()) == [
- IPAddress('1234::'),
- IPAddress('1234::1'),
- ]
- assert IPNetwork('1234::/127').network == IPAddress('1234::')
- assert IPNetwork('1234::').broadcast is None
-
- # Tests for /128 subnet
- assert IPNetwork("1234::/128").network == IPAddress('1234::')
- assert IPNetwork("1234::/128").broadcast is None
- assert list(IPNetwork("1234::/128")) == [IPAddress('1234::')]
- assert list(IPNetwork("1234::/128").iter_hosts()) == [IPAddress('1234::')]