IP_ADD_MEMBERSHIP上的医生说:
IP_ADD_MEMBERSHIP (自Linux1.2)加入多播组。参数是一个ip_mreqn结构。 结构ip_mreqn { struct in_addr imr_multiaddr;/* IP组播组地址*/ struct in_addr imr_address;本地接口*/ int imr_ifindex的/* IP地址;/*接口索引*/ };imr_multiaddr包含应用程序希望加入或离开的多播组的地址。它必须是一个有效的多播地址(或者setsockopt(2)由于错误EINVAL而失败)。imr_address是系统应该加入多播组的本地接口的地址;如果它等于INADDR_ANY,则由系统选择合适的接口。imr_ifindex是接口的接口索引,应该加入/离开imr_multiaddr组,或者0来指示任何接口。
因此,我有一个接口"eth0“与ip 192.168.1.5。我想加入这个接口到多播组225.1.1.1。我有点困惑如何正确地设置ip_mreqn结构?我找到了两种可能的方法:
1.
ip_mreqn group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;2.
ip_mreqn group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");第三种方法是使用SO_BINDTODEVICE套接字选项。
我的问题是。
1)将特定接口连接到组播组的正确方法是什么?
( 2) imr_address与imr_ifindex的功能差异是什么?
3)如何使用SO_BINDTODEVICE选项?
编辑:,我做了一些研究。
假设我有两个网络接口: ip 192.168.1.5的eth0和ip 192.168.1.255的eth1,ip 192.168.1.5在eth0上接收组播。
这些方法是正确地工作(我在eth0上获得多播消息):
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;或
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");或者很明显
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth0");甚至
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth0");不使用的方式(我在eth0上没有得到多播消息):
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth1");和
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth1");发布于 2018-02-05 21:58:10
我一直使用旧的struct ip_mreq而不是struct ip_mreqn,因为两者都是受支持的。这个结构没有索引字段,因此它对于需要设置的内容不那么含糊。
struct ip_mreq
{
/* IP multicast address of group. */
struct in_addr imr_multiaddr;
/* Local IP address of interface. */
struct in_addr imr_interface;
};然后,您将其设置为:
struct ip_mreq group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_interface.s_addr = inet_addr("192.168.1.5");发布于 2021-07-28 01:31:30
ip_mreqn用于在linux/net/ipv4/igmp.c(Linux5.13)的内核源代码中查找网络接口设备,如下所示。
static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
{
struct net_device *dev = NULL;
struct in_device *idev = NULL;
if (imr->imr_ifindex) {
idev = inetdev_by_index(net, imr->imr_ifindex);
return idev;
}
if (imr->imr_address.s_addr) {
dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
if (!dev)
return NULL;
}
if (!dev) {
struct rtable *rt = ip_route_output(net,
imr->imr_multiaddr.s_addr,
0, 0, 0);
if (!IS_ERR(rt)) {
dev = rt->dst.dev;
ip_rt_put(rt);
}
}
if (dev) {
imr->imr_ifindex = dev->ifindex;
idev = __in_dev_get_rtnl(dev);
}
return idev;
}imr->imr_ifindex首先用于搜索设备。如果未找到,则使用imr->imr_address。
https://stackoverflow.com/questions/48624503
复制相似问题