New submission from Michiel:

(See also: http://stackoverflow.com/q/19159168/1298153. This is my first bug 
submission)
Contrary to IPv4, IPv6 does not have a concept of network and broadcast 
addresses. It looks like the same code is used to generate the hosts for both 
IPv4 and IPv6, resulting in the network and broadcast addresses being omitted 
in IPv6, even though these are valid IPv6 addresses, albeit they may have a 
special meaning.

Repro:

$ python3
Python 3.3.2 (default, Sep  6 2013, 09:30:10) 
[GCC 4.8.1 20130725 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ipaddress
>>> print("\n".join([str(x) for x in 
>>> ipaddress.ip_network("2001:0db8::/120").hosts()]))
2001:db8::1
2001:db8::2
...
2001:db8::fe
>>> 
>>> hex(int(ipaddress.ip_address('2001:db8::fe')))
'0x20010db80000000000000000000000fe'

The v4 docs state, that the hosts() function...
"Returns an iterator over the usable hosts in the network. The usable hosts are 
all the IP addresses that belong to the network, except the network address 
itself and the network broadcast address."

Assuming hosts excludes routers, this should probably return a generator/an 
iterator covering all addresses in the network, apart from the very first one 
(all 0's after the prefix), since this is typically the subnet-router anycast 
address (http://tools.ietf.org/html/rfc4291#section-2.6.1).

While the top range (including the currently omitted prefix + "all 1's" 
address) contains reserved anycast addresses 
(http://tools.ietf.org/html/rfc2526), I'm not sure whether excluding them is a 
great idea, as in the future some of these may become valid (anycast) host 
addresses.

Backwards compatibility considerations:
The proposed fix would add one extra address to the ones already returned. I 
think this is less likely to break code, than, say, removing all the reserved 
anycast addresses.

Implementation options:
1. override _BaseNetwork hosts() implementation in IPv6Network
2. add an is_host_address(ip_address) method, or something along those lines, 
to IPv4 and IPv6Address classes, and change the hosts() function to only return 
addresses for which is_host_address is True. This function might be generally 
useful, but the implementation is likely to be slower than 1.
3. use address_exclude perhaps..

I'm sure there are many other ways to implement the fix, but I've attached a 
"naive" diff. I'm not sure if there's a better way to implement it that doesn't 
involve copying code from hosts()/__iter__ and slightly tweaking it.

With 1:
>>> print("\n".join([str(x) for x in 
>>> ipaddress.ip_network("2001:0db8::/124").hosts()]))
2001:db8::1
2001:db8::2
2001:db8::3
2001:db8::4
2001:db8::5
2001:db8::6
2001:db8::7
2001:db8::8
2001:db8::9
2001:db8::a
2001:db8::b
2001:db8::c
2001:db8::d
2001:db8::e
2001:db8::f

----------
components: Library (Lib)
files: ipaddress_ipv6_hosts.diff
keywords: patch
messages: 198927
nosy: m01
priority: normal
severity: normal
status: open
title: ipaddress.IPv6Network.hosts function omits network and broadcast 
addresses
type: behavior
versions: Python 3.3, Python 3.4
Added file: http://bugs.python.org/file31956/ipaddress_ipv6_hosts.diff

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue19157>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to