无法设置套接字选项IPV6多播:没有此类设备错误

时间:2015-09-15 23:10:31

标签: c sockets network-programming ipv6 multicast

我正在使用linux Ubuntu 14.04并尝试使用IPv6进行多播。我的链接本地地址为fe80::9a90:96ff:fe98:a985。运行以下代码:

int main (int argc, char *argv[]) {
  int sd;
  struct in6_addr localInterface;
  /* Create a datagram socket on which to send/receive. */
  sd = socket(AF_INET6, SOCK_DGRAM, 0);

  if(sd < 0) {
    perror("Opening datagram socket error");
    exit(1);
  }
  else {
    printf("Opening the datagram socket...OK.\n");
  }

  /* Set local interface for outbound multicast datagrams. */
  /* The IP address specified must be associated with a local, */
  /* multicast capable interface. */
  inet_pton (AF_INET6, "fe80::9a90:96ff:fe98:a985", &(localInterface.s6_addr));

  if(setsockopt(sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface)) < 0)
    {
      perror("Setting local interface error");
      printf ("%d\n", errno);
      exit(1);
    }
  else {
    printf("Setting the local interface...OK\n");
  }

}

给出错误:Setting local interface error : No such device

我已经测试了多播以使用IPv4,并且还通过使用IPv6命令ping本地节点来成功测试了ping6

1 个答案:

答案 0 :(得分:2)

通过一些调整,我能够修改你的程序,让它在我的Mac上发送多播数据包(显示在WireShark中)(运行OS / X 10.10.5)。我没有尝试过其他操作系统,但它或多或少也适用于其他操作系统。

请注意,程序已将接口编号硬编码为4,因为这是我计算机上的en0;您的计算机上的接口编号可能会有所不同,对于一个通常有用的程序,您希望动态地发现正确的接口编号(使用getifaddrs()或GetAdaptersAddresses()或类似);为简单起见,这里只是硬编码。

修改后的程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>

int main (int argc, char *argv[]) 
{
   int sd = socket(AF_INET6, SOCK_DGRAM, 0);
   if(sd < 0)
   {
      perror("Opening datagram socket error");
      exit(1);
   }
   else printf("Opening the datagram socket...OK.\n");

   // 4 is the interface ID (scope_id) of interface en0 on my Mac,
   // as printed by ifconfig; the appropriate interface index 
   // value on your computer will likely be different  --jaf
   int my_network_devices_scope_id = 4;

   if(setsockopt(sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&my_network_devices_scope_id, sizeof(my_network_devices_scope_id)) < 0)
   {
       perror("Setting local interface error");
       printf ("%d\n", errno);
       exit(1);
   }
   else printf("Setting the local interface...OK\n");

   struct sockaddr_in6 multicastIP;
   multicastIP.sin6_family   = AF_INET6;
   multicastIP.sin6_scope_id = my_network_devices_scope_id;
   multicastIP.sin6_port     = htons(9999);  // destination port chosen at random
   inet_pton(AF_INET6, "ff12::bead:cede:deed:feed", &multicastIP.sin6_addr.s6_addr);  // a multicast address I chose at random

   while(1)
   {
       char buf[] = "hello";
       if (sendto(sd, buf, sizeof(buf), 0, (const struct sockaddr *) &multicastIP, sizeof(multicastIP)) == sizeof(buf))
       {
          printf("Sent a %i-byte multicast packet!\n", (int) sizeof(buf));
       }
       else perror("sendto");

       sleep(1);
   }

   return 0;
}