Description
Bug report
Bug description:
Judging by what the is_private
and is_global
implementations in the ipaddress
module do[1], everything that IANA special-purpose address registries[2][3] considers globally reachable should result in is_global == True
, the rest should be is_global = True
.
is_private
is almost always the opposite of is_global
(100.64.0.0/10
is special).
The problem is the ranges present in the code (in the _private_networks
variables) are not quite right:
- There are some ranges missing (so we incorrectly treat them as globally reachable)
- Some of the ranges fail to account for more specific allocations defined as globally reachable (so we incorrectly treat them as not globally reachable)
This is what I have right now and I'll submit that as a PR:
diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
index 5b5520b92bde..3ee565bcd30b 100644
--- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -1558,13 +1558,18 @@ class _IPv4Constants:
_public_network = IPv4Network('100.64.0.0/10')
+ # Not globally reachable address blocks listed on
+ # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
_private_networks = [
IPv4Network('0.0.0.0/8'),
IPv4Network('10.0.0.0/8'),
+ # 100.64.0.0/10 missing
IPv4Network('127.0.0.0/8'),
IPv4Network('169.254.0.0/16'),
IPv4Network('172.16.0.0/12'),
+ # Incomplete. Should be 192.0.0.0/24 - (192.0.0.9/32 + 192.0.0.10/32)
IPv4Network('192.0.0.0/29'),
+ # 192.0.0.8/32 missing
IPv4Network('192.0.0.170/31'),
IPv4Network('192.0.2.0/24'),
IPv4Network('192.168.0.0/16'),
@@ -2306,15 +2311,31 @@ class _IPv6Constants:
_multicast_network = IPv6Network('ff00::/8')
+ # Not globally reachable address blocks listed on
+ # https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
_private_networks = [
IPv6Network('::1/128'),
IPv6Network('::/128'),
IPv6Network('::ffff:0:0/96'),
+ # 64:ff9b:1::/48 missing
IPv6Network('100::/64'),
+ # Not quite right as there are multiple more specific allocations that are globally
+ # reachable. Should be:
+ # 2001::/23 - (
+ # 2001:1::1/128
+ # + 2001:1::2/128
+ # + 2001:3::/32
+ # + 2001:4:112::/48
+ # + 2001:20::/28
+ # + 2001:30::/28
+ # )
IPv6Network('2001::/23'),
+ # Unnecessary, covered by 2001::/23
IPv6Network('2001:2::/48'),
IPv6Network('2001:db8::/32'),
+ # Unnecessary, covered by 2001::/23
IPv6Network('2001:10::/28'),
+ # Potentially 2002::/16 missing? IANA says N/A, there is no true/false value
IPv6Network('fc00::/7'),
IPv6Network('fe80::/10'),
]
[1] And which should really be documented per #65056 – a separate issue though
[2] https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
[3] https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Linked PRs
- GH-113171: Fix "private" (non-global) IP address ranges #113179
- [3.12] gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) #118177
- [3.11] gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) (GH-118177) #118227
- [3.10] gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) (GH-118177) #118229
- [3.9] gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) (GH-118177) #118472
- [3.8] gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) (GH-118177) #118479