Reputation: 137
I am trying to bind my local IPv6 address to a socket. But always get "invalid argument". The reason I want to bind the specific IP address to socket is that if I don't bind the error "No route to host" came up. When I tried to ping an IPv6 address with command below it does not work.
ping6 fe80::7ed1:c3ff:fe86
I have to point out from which interface I want to send the packet.
ping6 -I en1 fe80::7ed1:c3ff:fe86
And this works fine. So I think if I bind the socket to the interface then I can send the packet successfully. Anyone can tell me how to send an IPv6 address without specify the interface or how to solve this problem of binding?
Here are the codes.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <netdb.h>
#define LOCALADDR "fe80::7ed1:c3ff:fe86:ddae"
int main(void)
{
int sock,status;
struct addrinfo local_addr;
struct addrinfo *servinfo;
char buffer[1024];
/* create a DGRAM (UDP) socket in the INET6 (IPv6) protocol */
sock = socket(PF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
perror("creating socket");
exit(1);
}
/*Binding specific interface to socket*/
memset(&local_addr, 0, sizeof(local_addr));
local_addr.ai_family = AF_INET6;
local_addr.ai_socktype = SOCK_DGRAM;
local_addr.ai_flags = AI_PASSIVE;
if ((status = getaddrinfo(NULL, "3535", &local_addr, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
if (bind(sock, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
error("ERROR on binding");
I have also tried to replace "NULL" in the "getaddrinfo" to be "LOCALADDR".
if ((status = getaddrinfo(LOCALADDR, "3535", &local_addr, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
And I still get the same problem.
I can successfully binding the socket with "in6addr_any",but then I get the error "No route to host".
Upvotes: 2
Views: 5235
Reputation: 6452
That is a link-local IPv6 address, not a routable IPv6 address. The link-local addresses are specific to a link, and each link can have the same addresses as the other links. For instance if you have three different interfaces, you can assign the same link-local address to each of the interfaces. To use a link-local address, you need to specify the interface so that the OS knows which link to use. All the interfaces will have a link-local address in the same network: fe80::/10.
If you use a routable IPv6 address, you will not need to specify an interface.
Upvotes: 4
Reputation: 180058
You are creating the socket incorrectly. The 'domain' (first argument) should be AF_INET6
, not PF_INET6
. I am uncertain whether these in fact expand to different values in your environment, but the AF_*
macros are the ones designated for this purpose.
Otherwise, for a socket that accepts connections, you should get an address much the way you first present. In particular, the docs for getaddrinfo()
say
If the
AI_PASSIVE
flag is specified inhints.ai_flags
, andnode
is NULL, then the returned socket addresses will be suitable forbind
(2)ing a socket that willaccept
(2) connections. The returned socket address will contain the "wildcard address" (INADDR_ANY
for IPv4 addresses,IN6ADDR_ANY_INIT
for IPv6 address). The wildcard address is used by applications (typically servers) that intend to accept connections on any of the hosts’s network addresses. Ifnode
is not NULL, then theAI_PASSIVE
flag is ignored.
Thus, you certainly could and probably should specify a NULL first argument.
Note, however, that getaddrinfo()
returns a linked list of addresses, and under some circumstances it is necessary to choose a different one than the first. I think the first ought to be fine in this particular case, though.
Do also be aware that a "no route to host" message from a client trying to connect does not necessarily indicate that the server is not listening. It could well be that the client is using the wrong address (c.f. @RonMaupin's answer) or, just as it says, that there is no (known) route through the network from the client to the server. That could arise because of router or firewall configuration, for example.
Upvotes: 0