Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 validation seems to not check zone_id correctly #140

Open
harlowja opened this issue Nov 1, 2016 · 4 comments
Open

IPv6 validation seems to not check zone_id correctly #140

harlowja opened this issue Nov 1, 2016 · 4 comments

Comments

@harlowja
Copy link

harlowja commented Nov 1, 2016

Looking at the following:

https://tools.ietf.org/html/rfc4007#page-15

It appears that the zone_id has certain restrictions but netaddr isn't checking those.

>>> x = 'fe80::1%'
>>> netaddr.valid_ipv6(x)
True

Apparently one of the checks is that the zone_id can't be null (which it is in the above).

@sileht
Copy link

sileht commented Jan 4, 2017

I don't think this is a netaddr issue, this method is just a wrapper around _socket methods.
The wrapper and the builtin socket methods implementation doesn't have such issue.

>>> import netaddr, netaddr.fbsocket
>>> x = 'fe80::1%'
>>> netaddr.valid_ipv6(x)
False
>>> netaddr.fbsocket.inet_pton(netaddr.fbsocket.AF_INET6, x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/cdt.C6o62gPN/venv/local/lib/python2.7/site-packages/netaddr/fbsocket.py", line 196, in inet_pton
    [_pack('>H', int(i, 16)) for i in l_suffix]
ValueError: invalid literal for int() with base 16: '1%'

And my _socket module work as expected, so that looks like yours is buggy :)

>>> import _socket
>>> _socket.inet_pton(_socket.AF_INET6, x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.error: illegal IP address string passed to inet_pton

@sileht
Copy link

sileht commented Jan 4, 2017

I think at least on Linux, valid_ipv6 doesn't support zone_id at all.

@MEschenbacher
Copy link

We've now come across the issue and it looks to be a fundamental one. It appears that netaddr is not considering IPv6 with zone_id as IPv6.

In our usecase, we configure IPv6 link local addresses for daemons to bind to and communicate with. We're using the ansible netaddr/utils filters to detect and modify IPv6 addresses (which internally make heavy use of netaddr, if I'm correct in reading through the source):

  • ansible.utils.ipv6 filter to decide if this is an IPv6 address or IPv4 one (because we need to adjust firewall rules depending on the IP protocol). This filter fails to detect link local IPv6 addresses with zone_id as IPv6 e.g. fe80::1%eth1.
  • ansible.utils.ipwrap filter to wrap IPv6 addresses in brackets. This filter fails to wrap link local IPv6 addresses with zone_id e.g. fe80::1%eth1.

Example playbook:

---
- hosts: localhost
  tasks:
    - debug:
        msg:
          - "{{ 'fe80::1%ens18.18'|ansible.utils.ipwrap }} we believe should output [fe80::1%ens18.18]"
          - "{{ 'fe80::1%ens18.18'|ansible.utils.ipv6 }} we believe should output true"

Is fe80::1%eth1 a valid IPv6? Should it be identifyable as such? https://datatracker.ietf.org/doc/html/rfc4007#section-11 specifies that in order to prevent ambiguity of non-global IPv6 addresses, one should use the zone_id i.e. %zone_id.

@jstasiak
Copy link
Contributor

Is fe80::1%eth1 a valid IPv6? Should it be identifyable as such?

These are great questions. I'm entirely sure right now, need to sleep on this. I don't think this library is prepared for IPv6 scope zones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants