Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个send-IPv6-local-node-multicast程序可以在MacOS/X下工作,而不能在Linux下工作?_C_Linux_Macos_Ipv6_Multicast - Fatal编程技术网

为什么这个send-IPv6-local-node-multicast程序可以在MacOS/X下工作,而不能在Linux下工作?

为什么这个send-IPv6-local-node-multicast程序可以在MacOS/X下工作,而不能在Linux下工作?,c,linux,macos,ipv6,multicast,C,Linux,Macos,Ipv6,Multicast,下面是一个在MacOS/X和Linux下编译的简单示例程序。其目的是通过机器的环回设备发送单节点范围的UDP/IPv6多播数据包。我相信这是正确的,它在MacOS/X下确实可以正常工作,但在Linux下,它的输出失败: Attempting to send an IPv6/UDP packet to multicast address [ff11:0:1:0:94a4:2318:6300:4d51] on interface at index 1 (aka lo) FAILURE! sendt

下面是一个在MacOS/X和Linux下编译的简单示例程序。其目的是通过机器的环回设备发送单节点范围的UDP/IPv6多播数据包。我相信这是正确的,它在MacOS/X下确实可以正常工作,但在Linux下,它的输出失败:

Attempting to send an IPv6/UDP packet to multicast address [ff11:0:1:0:94a4:2318:6300:4d51] on interface at index 1 (aka lo)
FAILURE!  sendto() returned -1, errno=101 aka [Network is unreachable]
。。。但是,如果我修改第26行设置常量
interfaceeidx=0
,而不是
interfaceeidx=if_nametoindex(ifaceName)
,它将在Linux下成功发送数据包:

Attempting to send an IPv6/UDP packet to multicast address [ff11:0:1:0:94a4:2318:6300:4d51] on interface at index 0 (aka lo)
SUCCESS!  sendto() returned 18
。。。因此,我可以输入一个
#ifdef\uuuu linux\uuuuu
,强制
interfaceIdx
变量为0,但我觉得这不是正确的修复方法,因为正确设置接口索引是IPv6范围的多播的一个要求。有人知道为什么将
interfaceIdx
设置为正确的值会破坏Linux下的程序吗

节目如下:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>

// This function is here solely to make sure I pass in the right pointer to inet_pton's third argument
static int Inet_PtoN(int af, const char * src, struct in6_addr * dst)
{
   return inet_pton(af, src, dst);
}

int main(void)
{
   const char * dest = "ff11:0:1:0:94a4:2318:6300:4d51";  // my local-node-scoped IPv6 multicast address
#ifdef __linux__
   const char * ifaceName = "lo";   // name of loopback device under Linux
#else
   const char * ifaceName = "lo0";  // name of loopback device under MacOS/X
#endif
   const int interfaceIdx = if_nametoindex(ifaceName);

   printf("Attempting to send an IPv6/UDP packet to multicast address [%s] on interface at index %i (aka %s)\n", dest, interfaceIdx, ifaceName);

   int s = socket(AF_INET6, SOCK_DGRAM, 0);
   if (s<0) {perror("socket()"); return 10;}

   if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interfaceIdx, sizeof(interfaceIdx)) != 0) {perror("setsockopt(IPV6_MULTICAST_IF)"); return -1;}

   struct sockaddr_in6 toAddr; memset(&toAddr, 0, sizeof(toAddr));
   toAddr.sin6_family = AF_INET6;
   toAddr.sin6_port   = htons(12345);
   if (Inet_PtoN(AF_INET6, dest, &toAddr.sin6_addr) <= 0) {perror("inet_pton()"); return -1;}
   toAddr.sin6_scope_id = interfaceIdx;

   char buf[] = "dummy payload text";
   const int r = sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
   if (r >= 0) printf("SUCCESS!  sendto() returned %i\n", r);
          else printf("FAILURE!  sendto() returned %i, errno=%i aka [%s]\n", r, errno, strerror(errno));

   close(s);
   return 0;
}
。。。。下面是my Mac(通过VMWare Fusion托管Linux Ubuntu VM)上的
ifconfig-a
的输出:

lo0:flags=8049 mtu 16384
选项=1203
inet 127.0.0.1网络掩码0xff000000
inet6::1预桥128
inet6 fe80::1%lo0预桥64作用域ID 0x1
inet 127.94.0.2网络掩码0xff000000
inet 127.94.0.1网络掩码0xff000000
nd6选项=201
gif0:标志=8010 mtu 1280
stf0:标志=0 mtu 1280
XHC0:flags=0 mtu 0
XHC1:flags=0 mtu 0
XHC20:标志=0 mtu 0
VHC128:标志=0 mtu 0
en0:标志=8863 mtu 1500
选项=50b
乙醚f0:18:98:e8:e4:81
inet6 fe80::4ef:a7f5:734c:5a82%en0预桥64安全作用域ID 0x8
inet 10.0.1.26网络掩码0xffffff00广播10.0.1.255
nd6选项=201
媒体:自动选择()
状态:活动
en6:标志=8863 mtu 1500
乙醚ac:de:48:00:11:22
inet6 fe80::aede:48ff:fe00:1122%en6预桥64作用域ID 0x9
nd6选项=201
介质:自动选择(100baseTX)
状态:活动
en8:标志=8863 mtu 1500
选项=400
乙醚52:de:06:3a:29:9f
inet6 fe80::1438:7fb7:7145:e06c%en8预桥64安全作用域ID 0xa
inet 169.254.73.131网络掩码0xffff0000广播169.254.255.255
nd6选项=201
介质:自动选择(100baseTX)
状态:活动
ap1:标志=8802 mtu 1500
选项=400
乙醚f2:18:98:a8:a3:b4
媒体:自动选择
状态:不活跃
en1:标志=8863 mtu 1500
选项=400
乙醚f0:18:98:a8:a3:b4
nd6选项=201
媒体:自动选择()
状态:不活跃
p2p0:标志=8802 mtu 2304
选项=400
乙醚02:18:98:a8:a3:b4
媒体:自动选择
状态:不活跃
awdl0:flags=8902 mtu 1484
选项=400
乙醚2a:72:ad:a2:71:2b
nd6选项=201
媒体:自动选择
状态:不活跃
llw0:flags=8863 mtu 1500
选项=400
乙醚2a:72:ad:a2:71:2b
nd6选项=201
媒体:自动选择
状态:不活跃
en5:标志=8963 mtu 1500
选项=460
乙醚82:32:b3:81:34:04
媒体:自动选择
状态:不活跃
en2:标志=8963 mtu 1500
选项=460
乙醚82:32:b3:81:34:01
媒体:自动选择
状态:不活跃
en3:标志=8963 mtu 1500
选项=460
乙醚82:32:b3:81:34:00
媒体:自动选择
状态:不活跃
en4:标志=8963 mtu 1500
选项=460
乙醚82:32:b3:81:34:05
媒体:自动选择
状态:不活跃
桥0:flags=8863 mtu 1500
选项=63
乙醚82:32:b3:81:34:01
配置:
id 0:0:0:0:0:0优先级0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100超时1200
根id 0:0:0:0:0:0优先级0如果成本0端口0
ipfilter禁用标志0x0
成员:en2标志=3
ifmaxaddr 0端口17优先级0路径成本0
成员:en3标志=3
ifmaxaddr 0端口18优先级0路径成本0
成员:en4标志=3
ifmaxaddr 0端口19优先级0路径成本0
成员:en5标志=3
ifmaxaddr 0端口16优先级0路径成本0
nd6选项=201
媒体:
状态:不活跃
utun0:flags=8051 mtu 1380
inet6 fe80::d1a3:48e0:11d1:fc27%utun0预驱动桥64作用域ID 0x15
nd6选项=201
utun1:flags=8051 mtu 2000
inet6 fe80::ee71:43c3:4648:31b0%utun1预桥64作用域ID 0x16
nd6选项=201
utun2:标志=8051 mtu 1500
inet 172.27.224.165-->172.27.224.165网络掩码0xFFFFC0
vmnet1:flags=8863 mtu 1500
乙醚00:50:56:c0:00:08
inet 172.16.158.1网络掩码0xffffff00广播172.16.158.255

由于
ffx1:
不应离开系统,因此通常可以在系统默认界面上渲染(除非在客户端和服务器设置时界面可能会上下波动)。如果操作系统可能意外地在线路上发送或接受这些地址,可以添加防火墙规则

如果要使实际的lo接口作为有效的多播在专用链路上显式呈现VOUZ,则需要与普通接口相同的配置。如何在引导时保持这种持久性可能会有所不同,但我认为大多数现代Linuxes会理解以下命令:

ifconfig lo multicast
ip -6 route show table local
# find an interface route and copy it for lo and create it with a lower metric:
ip -6 route add table local ff00::/8 dev lo metric 255 pref medium

Linux上的
ifconfg
似乎在告诉您
lo
的IPv6地址的作用域ID是0x10,而程序的输出表明该接口的接口号是1,这可能是相关的。我不清楚这些属性之间是否有任何特定的关联。@JohnBollinger我也这么认为,但AFAICT 0x10和0x20不是有效的区域ID(即,如果我打印出由
if_nameindex()返回的结构)
它只显示
1/lo
2/ens33
,如果我尝试发送带有
interfaceIdx=16
的多播数据包,我会收到一个“无效设备索引”类型的错误)。所以我不清楚尾随的0应该表示什么,但它不是实际区域ID的一部分。我承认有点超出了我通常的区域,但据我所知或所能确定,区域ID适用
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
            options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
    inet 127.0.0.1 netmask 0xff000000
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
    inet 127.94.0.2 netmask 0xff000000
    inet 127.94.0.1 netmask 0xff000000
    nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
XHC0: flags=0<> mtu 0
XHC1: flags=0<> mtu 0
XHC20: flags=0<> mtu 0
VHC128: flags=0<> mtu 0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=50b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV,CHANNEL_IO>
    ether f0:18:98:e8:e4:81
    inet6 fe80::4ef:a7f5:734c:5a82%en0 prefixlen 64 secured scopeid 0x8
    inet 10.0.1.26 netmask 0xffffff00 broadcast 10.0.1.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (<unknown type>)
    status: active
en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether ac:de:48:00:11:22
    inet6 fe80::aede:48ff:fe00:1122%en6 prefixlen 64 scopeid 0x9
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (100baseTX <full-duplex>)
    status: active
en8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether 52:de:06:3a:29:9f
    inet6 fe80::1438:7fb7:7145:e06c%en8 prefixlen 64 secured scopeid 0xa
    inet 169.254.73.131 netmask 0xffff0000 broadcast 169.254.255.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (100baseTX <full-duplex>)
    status: active
ap1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether f2:18:98:a8:a3:b4
    media: autoselect
    status: inactive
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether f0:18:98:a8:a3:b4
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (<unknown type>)
    status: inactive
p2p0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 2304
    options=400<CHANNEL_IO>
    ether 02:18:98:a8:a3:b4
    media: autoselect
    status: inactive
awdl0: flags=8902<BROADCAST,PROMISC,SIMPLEX,MULTICAST> mtu 1484
    options=400<CHANNEL_IO>
    ether 2a:72:ad:a2:71:2b
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: inactive
llw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether 2a:72:ad:a2:71:2b
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: inactive
en5: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 82:32:b3:81:34:04
    media: autoselect <full-duplex>
    status: inactive
en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 82:32:b3:81:34:01
    media: autoselect <full-duplex>
    status: inactive
en3: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 82:32:b3:81:34:00
    media: autoselect <full-duplex>
    status: inactive
en4: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 82:32:b3:81:34:05
    media: autoselect <full-duplex>
    status: inactive
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=63<RXCSUM,TXCSUM,TSO4,TSO6>
    ether 82:32:b3:81:34:01
    Configuration:
            id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
            maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
            root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
            ipfilter disabled flags 0x0
    member: en2 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 17 priority 0 path cost 0
    member: en3 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 18 priority 0 path cost 0
    member: en4 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 19 priority 0 path cost 0
    member: en5 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 16 priority 0 path cost 0
    nd6 options=201<PERFORMNUD,DAD>
    media: <unknown type>
    status: inactive
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
    inet6 fe80::d1a3:48e0:11d1:fc27%utun0 prefixlen 64 scopeid 0x15
    nd6 options=201<PERFORMNUD,DAD>
utun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
    inet6 fe80::ee71:43c3:4648:31b0%utun1 prefixlen 64 scopeid 0x16
    nd6 options=201<PERFORMNUD,DAD>
utun2: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
    inet 172.27.224.165 --> 172.27.224.165 netmask 0xffffffc0
vmnet1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether 00:50:56:c0:00:08
    inet 172.16.158.1 netmask 0xffffff00 broadcast 172.16.158.255
ifconfig lo multicast
ip -6 route show table local
# find an interface route and copy it for lo and create it with a lower metric:
ip -6 route add table local ff00::/8 dev lo metric 255 pref medium