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".
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.