Skip to content

ipaddress considers some not globally reachable addresses global and vice versa #113171

Closed
@jstasiak

Description

@jstasiak

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

Metadata

Metadata

Assignees

Labels

type-bugAn unexpected behavior, bug, or errortype-securityA security issue

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions