This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: 192.0.0.8 (IPv4 dummy address) considered globally reachable
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: CosmicKid, cdirkx, mjpieters
Priority: normal Keywords: patch

Created on 2021-01-15 23:00 by cdirkx, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 26205 open CosmicKid, 2021-05-18 02:35
Messages (6)
msg385127 - (view) Author: CDirkx (cdirkx) Date: 2021-01-15 23:00
Currently the method `ipaddress.is_global` returns true for the IPv4 address 192.0.0.8. This was correct when `is_global` was initially implemented, but in 2015 192.0.0.8 got designated as the "IPv4 dummy address" and not globally reachable, see the IANA special purpose address registry: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml.

The correct behaviour now, according to the documentation of `is_global` which refers to the IANA registry, would be to return false for 192.0.0.8.
msg393843 - (view) Author: Wayne Johnston (CosmicKid) * Date: 2021-05-17 23:19
This a simple matter of adding the address to the _private_networks constant.   I will add it and issue a pull request today/tomorrow.  I could add some of the others too for completeness.   However, these are really special use versus private.   Private is a subset of special use.  Should a "_special_use" constant be created.  This would include multicast, link_local, private_use, and a few more.

There are many others included in  https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml.
msg393862 - (view) Author: Martijn Pieters (mjpieters) * Date: 2021-05-18 09:15
This is related to #42937, the IPv4 private network list is not considering the whole of 192.0.0.0/24 to be private.

RFC 5736 / 6890 reserved 192.0.0.0/24 for special purposes (private networks) and to date a few subnets of that network have received assignments. The ipaddress modules should use that subnet for any `is_private` test, and not just the subnets of that network that have received specific assignments.

E.g. the list currently contains just 192.0.0.0/29 and 192.0.0.170/31, but as this bug report points out, 192.0.0.8/32 has since been added, as have 192.0.0.9/32 and 192.0.0.10/32.

The IPv6 implementation *does* cover the whole reserved subnet (although it also includes 2 specific registrations, see the aforementioned #42937), it is just IPv4 that is inconsistent and incomplete here.
msg393863 - (view) Author: Martijn Pieters (mjpieters) * Date: 2021-05-18 09:26
Oops, I got my issue numbers mixed up. This is related to #44167, I meant.
msg393870 - (view) Author: Martijn Pieters (mjpieters) * Date: 2021-05-18 11:30
> Private is a subset of special use.  Should a "_special_use" constant be created.  This would include multicast, link_local, private_use, and a few more.

There are already dedicated tests for those other special use networks in ipaddress. 192.0.0.0/24 is the block reserved for "IETF Protocol Assignments", which really means: private use. https://datatracker.ietf.org/doc/html/rfc6890#section-2.2.2 marks the block as "Not usable unless by virtue of a more specific reservation.".

The registry at https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml lists those specific reservations, and only 2 to date are *globally reachable*, which means they are probably not private:

- 192.0.0.9/32, Port Control Protocol Anycast, RFC 7723
- 192.0.0.10/32, Traversal Using Relays around NAT Anycast, RFC 8155

I strongly feel that _any other IP address in the reserved range_ should be treated as private unless marked, by IANA, as globally reachable, at some future date.

That would require the list of networks for IPv4Address / IPv4Network is_private to include all of 192.0.0.0/24 _minus those two exceptions_; calculating the network masks for these:

>>> def exclude_all(network, *excluded):
...     try:
...         for sub in network.address_exclude(excluded[0]):
...             yield from exclude_all(sub, *excluded[1:])
...     except (IndexError, ValueError):
...         yield network
...
>>> iana_reserved = IPv4Network("192.0.0.0/24")
>>> to_remove = IPv4Network("192.0.0.9/32"), IPv4Network("192.0.0.10/32")

>>> for sub in exclude_all(iana_reserved, *to_remove):
...     print(sub)
...
192.0.0.128/25
192.0.0.64/26
192.0.0.32/27
192.0.0.16/28
192.0.0.0/29
192.0.0.12/30
192.0.0.11/32
192.0.0.8/32

The module could trivially do this on import, or we could hard-code the above list.
msg394256 - (view) Author: Wayne Johnston (CosmicKid) * Date: 2021-05-24 16:57
I completely agree with comments about .is_global and special_use.  Private IPs are just a subset of special use.  For some part Private means the Private use networks reserved by IANA and specified in IETF RFC1918.      

For this PR "IPv4 dummy address" is for sure not global.  Technically, it is not a private use IP either.  Just following what others have done.  I really like the apporoach of removing the routable special IPs.  Let me know if I should create a PR to do this.  This would include adding specific special use constant plus a whole bunch of very specific constants.  A constant like is_dummy will be added.

I pretty much have the code ready to go for IPV4.
History
Date User Action Args
2022-04-11 14:59:40adminsetgithub: 87103
2021-05-24 16:57:26CosmicKidsetmessages: + msg394256
components: + Library (Lib)
versions: + Python 3.11, - Python 3.9
2021-05-18 11:30:22mjpieterssetmessages: + msg393870
2021-05-18 09:26:18mjpieterssetmessages: + msg393863
2021-05-18 09:15:33mjpieterssetnosy: + mjpieters
messages: + msg393862
2021-05-18 02:35:44CosmicKidsetkeywords: + patch
stage: patch review
pull_requests: + pull_request24822
2021-05-17 23:19:27CosmicKidsetnosy: + CosmicKid
messages: + msg393843
2021-01-15 23:00:38cdirkxcreate