I'm currently writing a python wrapper for a C++-Library that does network communication via IPv6 link-local addresses. To initialize the library the network interface has to be selected. This is done via the link-local address of the desired interface.
On the C++ side we use boost address_v6 objects. On the python side the ipaddress.IPv6Address seemed to be a perfect match.
However I did not find a way to specify the scope id of the interface on the python side.
ip = ipaddress.IPv6Address('fe80::3c4e:6a7:3f57:4cbc%12')
gives the error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python34\lib\ipaddress.py", line 1835, in __init__
self._ip = self._ip_int_from_string(addr_str)
File "C:\Python34\lib\ipaddress.py", line 1664, in _ip_int_from_string
raise AddressValueError("%s in %r" % (exc, ip_str)) from None
ipaddress.AddressValueError: Only hex digits permitted in '4cbc%12' in 'fe80::3c4e:6a7:3f57:4cbc%12'
IPv6 link-local communication is pretty much impossible without the scope ids.
Am I missing something here or is the best way to specify an IPv6 link-local interface addresses as a string?
I recommend using the same structures as the Python socket module in all those cases where this makes any sense. Even if using your native library means the Python socket module isn't going to be used, it can still be beneficial, if some data structures are compatible between the two.
For representing an IP address, the Python socket module does indeed use a string. And that string can include a scope ID when appropriate.
The Python socket module also needs to represent socket addresses for that purpose it uses a tuple consisting of four fields. It could for example be:
('ff02::2%eth0', 80, 0, 2)
Notice that this representation is slightly redundant, because the scope ID is specified both as %eth0
inside the IP address and as 2
(the last element of the tuple).