我拥有接口的IPv4地址。 我尝试了以下操作,但套接字没有接收到任何UDP(单播、广播、多播)数据包。
struct sockaddr_in addr;
int fd, nbytes;
socklen_t addrlen;
struct ip_mreq mreq;
// my_ipv4Addr equals current IP as String, e.g. "89.89.89.89"
// create what looks like an ordinary UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
exit(1);
}
// set up addresses
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
// [-] addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_addr.s_addr = inet_addr(my_ipv4Addr);
addr.sin_port = htons(port);
// bind socket
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
// use setsockopt() to request that the kernel join a multicast group
mreq.imr_multiaddr.s_addr = inet_addr(group);
// [-] mreq.imr_interface.s_addr = htonl(INADDR_ANY);
mreq.imr_interface.s_addr = inet_addr(my_ipv4Addr);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))< 0) {
perror("setsockopt");
exit(1);
}
编辑:
让我解释一下我的程序目的。 我正在编写一个小工具,用于检查网络是否支持广播/组播。 因此,我拥有一个带有两个接口的系统,并通过Interface1发送多播数据包,并尝试使用Interface2接收它。 但是:数据包应通过网络传输,而不是loopback设备。
想法是在thread1/interface1上阻止组播回环:
u_char loop = 0;
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
我需要监听线程2/接口2的特定内容。Tcpdump显示数据包已经到达,但是根据我上述的配置被丢弃了。
setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 4)
。 - Genemreq.imr_interface.s_addr = htonl(INADDR_ANY);
。 - shinkousetsockopt( ... SO_BINDTODEVICE ...)
我可以将 UDP 套接字绑定到一个接口,但是如何显式地为多播做到这一点呢?@shinkou 将其设置为 INADDR_ANY(UDP 和多播订阅)并不会改变套接字不接收数据包的事实。数据包被丢弃为 martian(在 /var/log/syslog 中看到),直到我设置了net.ipv4.{all,default,interfaces}.rp_filter = 0
。似乎与 Linux 相关,因为数据包可以通过 tcpdump 在出站和入站接口上看到。现在没有头绪了... - user22602setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, ..)
来控制数据包从哪个接口发送... - Chris Dodd