IPv6: connect() always fail with errno 22

我怕爱的太早我们不能终老 提交于 2019-12-05 05:56:20

问题


The OS is Ubuntu. I'm doing a simple test for basic IPv6 operations. The PC is connected with an IP Camera (support IPv6) via a hub. ping6 testing is successful.

$ ping6 -I eth1 fe80::240:8cff:fe94:451e
PING fe80::240:8cff:fe94:451e(fe80::240:8cff:fe94:451e) from fe80::224:8cff:fe90:ad3b eth1: 56 data bytes
64 bytes from fe80::240:8cff:fe94:451e: icmp_seq=1 ttl=64 time=3.86 ms
64 bytes from fe80::240:8cff:fe94:451e: icmp_seq=2 ttl=64 time=0.471 ms

The code is below:

#include <linux/in6.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>

void main()
{
  int s, ret, err;
  struct sockaddr_in6 addr;

  s = socket(AF_INET6, SOCK_STREAM, 0);
  addr.sin6_family = AF_INET6;
  addr.sin6_port = htons(554);
  addr.sin6_flowinfo = 0;
  addr.sin6_scope_id = 0;
  addr.sin6_addr.s6_addr[0] = 0xfe;
  addr.sin6_addr.s6_addr[1] = 0x80;
  addr.sin6_addr.s6_addr[2] = 0x00;
  addr.sin6_addr.s6_addr[3] = 0x00;
  addr.sin6_addr.s6_addr[4] = 0x00;
  addr.sin6_addr.s6_addr[5] = 0x00;  
  addr.sin6_addr.s6_addr[6] = 0x00;
  addr.sin6_addr.s6_addr[7] = 0x00;
  addr.sin6_addr.s6_addr[8] = 0x02;
  addr.sin6_addr.s6_addr[9] = 0x40;
  addr.sin6_addr.s6_addr[10] = 0x8c;
  addr.sin6_addr.s6_addr[11] = 0xff;
  addr.sin6_addr.s6_addr[12] = 0xfe;
  addr.sin6_addr.s6_addr[13] = 0x94;
  addr.sin6_addr.s6_addr[14] = 0x45;
  addr.sin6_addr.s6_addr[15] = 0x1e;

  ret = connect(s, (struct sockaddr*)&addr, sizeof(addr));
  if (ret == -1)
  {
    err = errno;
    printf("connect failure, errno = %d\n", err);
  }
}

The result is always "connect failure, errno = 22" Where is the problem?


回答1:


If you're going to use a link-local address, you have to set the sin6_scope_id to match the device index of the network device on the link (this is why you have to specify -I eth1 to your ping6 command).

You can have getaddrinfo() do all the hard work for you, including setting scope ID (note the %eth1 at the end of the address) and the port:

struct addrinfo hints = { 0 };
struct addrinfo *res;
int gai_err;
int s;

hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;

gai_err = getaddrinfo("fe80::240:8cff:fe94:451e%eth1", "554", &hints, &res);

if (gai_err)
{
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_err));
    return 1;
}

s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

if (s < 0) {
    perror("socket");
    return 1;
}

if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
    perror("connect");
    return 1;
}


来源:https://stackoverflow.com/questions/6786648/ipv6-connect-always-fail-with-errno-22

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!