I want to ceate Ipv6 socket at python, I do it like this:
#!/usr/bin/env python
import sys
import struct
import socket
host = \'fe80::225:b3ff:fe26:576\'
sa
There are two parts to the problem
First Issue
You should use the sa.bind(sockaddr) where sockaddr is obtained from getaddrinfo
>>> HOST = 'localhost'
>>> PORT = 50007
>>> res = socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)
>>> family, socktype, proto, canonname, sockaddr = res[1]
>>> proto
17
>>> sockaddr
('fe80::1%lo0', 50007, 0, 1)
Second Issue
If you look at the example provided in the socket documentation at
Socket accepts three arguments
socket( [family[, type[, proto]]])
As per the documentation
Create a new socket using the given address family,
socket type and protocol number. The address family
should be AF_INET (the default), AF_INET6 or AF_UNIX.
The socket type should be SOCK_STREAM (the default),
SOCK_DGRAM or perhaps one of the other "SOCK_" constants.
The protocol number is usually zero and may be omitted in that case.
And if you used getaddressinfo to get the values for proto then the value is different from the default 0
But when I executed the following, I get a different protocol value - 17. You may want to investigate this too.
And of course socket.has_ipv6 is True for me.
The other thing missing from the above is that fe80::* are link-local addresses.As such you can't technically use them without a Scope ID.
Just in case that didn't sink in, "link-local
" means that the address can only be used on a specific link, but the corollary is that since the address is link-specific theoretically you could have that same address on more than one link.
Now granted that in most cases a link-local address is generated from the already unique hardware (EUI-48) address by converting it to an EUI-64 and then flipping on the U/L bit (see) but this is not the only way you can generate a link-local address and other mechanisms could result in re-using the address (I don't think there's anything that prohibits this). So now you know why it didn't work.
The next question is how do you fix it, or rather where do you get the Scope ID. This is unfortunately non-obvious. If you read the IPV6 RFCs that discuss "Scope
" you find that it is defined in a general fashion. In practice if you are running this code in Linux (maybe also Windows/Mac?) you can use the interface index.
Note that there's currently a bug in nss-mdns such that .local names are returned with scope id always zero so in Linux using .local names basically doesn't work unless your code has already figured out the scope id and sets it by itself.