connect() returns "invalid argument" with ipv6 address
Solution 1
Addresses starting with ff...
are multicast addresses. Connecting a stream to a multicast address does not work.
Addresses starting with fe80...
are link-local addresses, which have an interface identifier associated with them. Try looking at the sockaddr
returned from getaddrinfo
, is the scope
field filled out?
Solution 2
You need to specify the interface for IPv6 ping (i.e. -I eth0):
ping6 -I eth0 fe80::208:54ff:fe34:22ae
Using link-local addresses for an IPv6 ping, requires to define what device it must send/receive the packet - each device has a link-local address.
Trying without this, will result in error message like:
--> # ping6 fe80::208:54ff:fe34:22ae
connect: Invalid argument
In this case you have to specify the interface additionally like shown here:
--> # ping6 -I eth0 fe80::208:54ff:fe34:22ae
PING fe80::208:54ff:fe34:22ae(fe80::208:54ff:fe34:22ae) from fe80::208:54ff:fe34:22ae eth0: 56 data bytes
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=0 ttl=64 time=0.027 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=2 ttl=64 time=0.036 ms
One similar approach you must to follow in your client APP..
Related videos on Youtube
Comments
-
flyjohny almost 2 years
I have this simple client-server application pair. The code is pretty simple, I'm using only new, advised methods like getaddinfo etc and everything works just fine for ipv4. Even for ipv6 loopback (::1) it works. Problems start when it comes to some other ipv6 addresses... I have two machines in a network, everything works fine when I pass their ipv4 addresses, but when I give my client ipv6 address, I get an error on connect function: invalid argument. Hey, don't I already know this? I do! When I try to ping6 this ipv6 address, I get the same error:
connect: Invalid argument
But there is a way to overcome this block - one should choose an interface with a -I switch and it all runs smoothly since then. But how can I achieve the same in my client app? What should I do? My client code looks like this:
struct addrinfo hints; struct addrinfo *server; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int status; if((status = getaddrinfo(argv[1], argv[2], &hints, &server) != 0)) { perror("getaddrinfo error"); return 1; } int sock_fd; struct addrinfo *ptr; for(ptr=server;ptr!=NULL;ptr=ptr->ai_next) { if( (sock_fd = socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol)) == -1) { perror("socket error"); continue; } if( connect(sock_fd, ptr->ai_addr,ptr->ai_addrlen) == -1 ) { perror("connect error"); continue; } break; }
-
Ariel over 11 yearsWhat is this problematic address that ping rejects?
-
-
flyjohny over 11 yearsI know that I am lazy ass but could you tell me how to turn on the ip6 protocol in the interface? I am using a Linux box.
-
Oliver over 11 yearsFirst check this Guide tldp.org/HOWTO/Linux+IPv6-HOWTO/x790.html after that try this on your specific interface : ping6 -I eth0 "fill the ip6addr here" it could be that your loopback interface has ip6 support activated and therefore the local ping works with no issues, Can you maybe tell us your Linux distro and the kernel version?
-
Simon Richter over 11 yearsThis field should contain the interface number. Have you specified the scope with the
%eth0
or%1
(1 being the interface number, which you can look up with theip
tool) notation?\ -
flyjohny over 11 yearsNope. When I do that, this scope field is filled with some value and it seems to work (although I need to configure my specific FW, but I get no invalid argument anymore). But I seem to miss something and in all the materials connected with ipv6 I was reading I didn't come across this - do I need to specify the interface whenever I use link-local address?
-
Simon Richter over 11 yearsYes, you do. Link-local address means precisely that uniqueness of the address is only guaranteed on this particular link, so the system has no way of finding out which interface to send the data to unless you tell it. The alternative is to assign addresses with global scope and use a routing table.
-
kaps over 5 years@SimonRichter - If I am using the local link address, does it mean that the scope_id field will be always 0 and we need to explicitly specify it ? Can system pick this automatically with any config in /etc/hosts ot any other config ? (Note : I have no DNS in place in my network)
-
Simon Richter over 5 years@kaps, no, there is no way to have the system auto-select the interface. It is perfectly legal to have
ppp0
,ppp1
andppp2
all configured to use a local address offe80::1
and a peer address offe80::2
, so the OS could not decide which interface to use for a destination address offe80::2
. So the program needs to fill in thescope_id
. When the addresses are configured by the user,getaddrinfo
will fill it out when the user uses the%
notation, when you use multicast for discovery, you can use the scope ID from the discovery packet's origin.