标签: igmp

Linux和IGMPv3上的组播加入

我们遇到了一个棘手的问题.我们正在编写一个接收多播UDP流量的c ++程序.我们正在将应用程序迁移到不同的网络环境,我们的运营团队已要求我们支持来自应用程序的IGMPv3会员公告.初步调查表明,Linux 2.6内核确实支持IGMPv3.因此,我很困惑,当我们运行tcpdump时,我们看到以下输出跟踪:

[rtv@myhost]$ sudo /usr/sbin/tcpdump -i eth1.22 igmp
tcpdump: listening on eth1.22
00:20:09.007094 switch-a.stage > ALL-SYSTEMS.MCAST.NET: igmp query v2 [max resp time 20] [ttl 1]
00:20:09.241946 10.129.22.236 > 232.0.1.10: igmp v2 report 232.0.1.10 (DF) [tos 0xc0]  [ttl 1]
00:20:10.472159 10.129.22.236 > 236.0.1.101: igmp v2 report 236.0.1.101 (DF) [tos 0xc0]  [ttl 1]

44 packets received by filter
Run Code Online (Sandbox Code Playgroud)

我的理解是,通过在文件/proc/sys/net/ipv4/conf/eth1.22/force_igmp_version中指定非零值,可以强制内核使用较低版本的IGMP; 但是,我已经确认该文件的配置值为零.

我们的应用程序使用以下代码加入多播组:

... joinMulticast(in_addr mcast_addr, in_addr interface_addr)
{
  struct ip_mreq  mcast_req;

  mcast_req.imr_multiaddr.s_addr = mcast_addr;
  mcast_req.imr_interface.s_addr = interface_addr;
  int err = setsockopt(fFileDesc, IPPROTO_IP, …
Run Code Online (Sandbox Code Playgroud)

networking multicast igmp

10
推荐指数
1
解决办法
3万
查看次数

为什么多播接收不适用于某些Android设备?

似乎多播接收在某些Android设备上不起作用.我无法通过13个测试设备中的4个接收多播.在这4个设备上,应用程序似乎不发送加入多播组的IGMP请求.

接收多播的代码如下所示:

WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiManager.WifiLock wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TAG);
WifiManager.MulticastLock multicastLock = wifiManager.createMulticastLock(TAG);
multicastLock.setReferenceCounted(true);

wifiLock.acquire();
multicastLock.acquire();

try {
    MulticastSocket socket = new MulticastSocket(32123);

    InetAddress group = InetAddress.getByName("224.1.2.3");
    socket.joinGroup(group);

    DatagramPacket packet;
    byte[] buf = new byte[256];
    packet = new DatagramPacket(buf, buf.length);

    socket.receive(packet);

    socket.leaveGroup(group);
    socket.close();
} catch (IOException e) {
    e.printStackTrace();
}

multicastLock.release();
wifiLock.release();
Run Code Online (Sandbox Code Playgroud)

该应用具有以下权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
Run Code Online (Sandbox Code Playgroud)

为了演示这个问题,我在GitHub:MulticastTest上使用上面的代码创建了一个小测试项目.

我的代码有问题吗?我错过了许可吗?

编辑1:此问题似乎与特定的Android版本无关.我可以在Android 4.x,5.x和6.x上重现这种行为.

编辑2:有一个相关的问题.

networking android multicast igmp android-networking

10
推荐指数
1
解决办法
3838
查看次数

套接字错误:90:消息太长

我在以下场景中遇到IGMP套接字调用错误;

fd = socket(PF_INET,  SOCK_RAW, IPPROTO_IGMP) ;
setsockopt( fd, IPPROTO_IP, IP_HDRINCL, nval, sizeof(nval) );
/** Fill in the IP header and Ethernet header**/
/*** Fill, create the IGMP packet structures***/
if(sendto( fd, &buf, sizeof(buf), 0,(struct sockaddr *) &addr, sizeof(addr)) < 0) {
    printf("Socket Sendto error %d : %s\n", errno, strerror(errno));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

sendto调用失败说消息太长.我使用8192作为缓冲区大小.所以我尝试使用以下调用来修复此错误;

if(setsockopt(dlpifd, IPPROTO_IP, SO_SNDBUF, &val, sizeof(int)) < 0) {
   printf("Can't set socket options:%d:%s\n", errno, strerror(errno));
   return 0;`
}
Run Code Online (Sandbox Code Playgroud)

setsockopt()调用成功,但sendto()的错误相同;

所以我用getsockopt()调用检查SO_SNDBUF大小,它显示1个字节?

我在做什么是错的.

Linux内核是否需要重新编译才能获得IGMP支持?或者我错过了什么?

c sockets network-programming igmp linux-kernel

5
推荐指数
1
解决办法
2万
查看次数

加入 igmp_group 无法在 lightwight IP (lwip) 中工作

我是 lwip 的新手,我想用 lwip 创建一个多播接收器。我的步骤如下: 1.启用LWIP_IGMP;2、在low_level_init()中设置NETIF_FLAG_IGMP;3、加入组播组,创建并绑定pcb;4. udp_connect到remote_ip(或多播IP地址?都尝试过但失败)

加入组返回成功,当程序执行此操作时,一切看起来都很好。然而组播接收器不工作,没有组播数据进入网络接口。看来我实际上并没有将我的接收者加入到 igmp 组,尽管加入过程看起来不错。有人知道我错过了什么吗?

我在igmp_joingroup()中发现“netif->igmp_mac_filter != NULL”,但是这个回调被设置为NULL并且没有实现。我是否需要自己实现来设置 MAC 过滤器,或者将其保留为 NULL 就可以了?

非常感谢你的帮助!

瑞安

multicast igmp lwip

5
推荐指数
1
解决办法
4100
查看次数

列出主机上的所有有效Ipv4Addr

我需要在主机上的所有可用地址上发送相同的多播UDP数据包.我需要发送到localhost/ 127.0.0.1239.255.0.1.std从版本1.2开始,Rust的lib已经弃用了多播行为,无论如何,为了获得我需要的特性,我必须切换到更完整的行为net2.

net2API有一堆的UDP扩展其提供我正在寻找的API.我特别感兴趣

fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> Result<()>
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何处理multiaddr vs interface.我以为我会给multiaddr 127.0.0.1或者239.255.0.1如何找到interface参数的有效IPv4 ?有一个Rust函数,在某个地方,可以提供一个Vec<Ipv4Addr>?我需要解析输出ifconfig吗?

这是一个独立的程序,它发出我的公共接口(必须192.168.0.102手动找到该地址):

extern crate net2;

use std::net::{ UdpSocket, Ipv4Addr };
use net2::UdpSocketExt;

fn main() {
  let sock = UdpSocket::bind("0.0.0.0:2345").unwrap();
  let local_addr = Ipv4Addr::new(192, 168, 0, 102);
  let multicast_addr = Ipv4Addr::new(239, 255, 0, 1);

  sock.join_multicast_v4(&multicast_addr, &local_addr).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

如果这有任何区别,我正在编制夜莺.

sockets udp multicast igmp rust

5
推荐指数
0
解决办法
146
查看次数

如果我在关闭套接字之前不发送 IP_DROP_MEMBERSHIP 会发生什么?

我正在编写一些使用 IGMP 加入多播组的代码

struct ip_mreq mreq;
inet_pton(AF_INET, group, &mreq.imr_multiaddr.s_addr);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);

if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) < 0)
    throw std::runtime_error(perror("setsockopt(IP_ADD_MEMBERSHIP)"));
Run Code Online (Sandbox Code Playgroud)

当应用程序关闭时,它关闭套接字

close(fd);
Run Code Online (Sandbox Code Playgroud)

但是,它不执行IP_DROP_MEMBERSHIP.

  • 上游路由器会继续将多播传送到我的网络接口吗?
  • 操作系统(在我的情况下是 Linux)是否足够智能,可以在套接字关闭时为我发送删除成员资格请求?

c++ sockets multicast igmp

3
推荐指数
1
解决办法
1464
查看次数

如何在C#(IGMPv3)中加入源特定组播组

我们有一个C#应用程序,可以加入和接收来自多播组的数据.这很好用.我们现在想要支持IGMPv3并且能够在加入多播组时指定源的IP.从MSDN文档中,我看不到如何执行此操作.我发现以下链接似乎回答了我的问题.

http://social.msdn.microsoft.com/Forums/en/netfxnetcom/thread/e8063f6d-22f5-445e-a00c-bf46b46c1561

这是我实现这个的方式:

byte[] membershipAddresses = new byte[12]; // 3 IPs * 4 bytes (IPv4)
Buffer.BlockCopy(multicastIp.GetAddressBytes(), 0, membershipAddresses, 0, 4);
Buffer.BlockCopy(sourceIp.GetAddressBytes(), 0, membershipAddresses, 4, 4);
Buffer.BlockCopy(localIp.GetAddressBytes(), 0, membershipAddresses, 8, 4);
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, membershipAddresses);
Run Code Online (Sandbox Code Playgroud)

但是当我用这个错误调用SetSocketOption()时,我得到一个SocketException : The requested address is not valid in its context.

有人能指出我在这里做错了吗?谢谢!

c# sockets multicast igmp

2
推荐指数
1
解决办法
3344
查看次数

如何在Python中发送具有给定十六进制有效载荷的IP数据包?

我已经嗅探了一个IGMP数据包,现在我想在python的帮助下发送它。有什么办法可以发送像

0x0000   01 00 5E 00 43 67 00 02-B3 C8 7F 44 81 00 00 DE   ..^.Cg..??D?..?
0x0010   08 00 46 00 00 20 00 01-00 00 01 02 36 4C C0 A8   ..F.. ......6L??
0x0020   00 7B EA 00 43 67 94 04-00 00 16 00 BC 97 EA 00   .{?.Cg”.....?—?.
0x0030   43 67                                             Cg
Run Code Online (Sandbox Code Playgroud)

没有像流浪者这样的数据包生成器?

UPD好吧,我尝试使用原始套接字,如下所示:

dst = '234.0.67.103'

# Open a raw socket.
s = socket.socket(socket.AF_INET, socket.SOCK_RAW,2)

res=''

temp='01 00 5E 00 43 67 00 02 …
Run Code Online (Sandbox Code Playgroud)

python sockets igmp

0
推荐指数
1
解决办法
9847
查看次数