gpt4 book ai didi

UDP 多播客户端看不到 tcpreplay 生成的 UDP 多播流量

转载 作者:行者123 更新时间:2023-12-01 18:05:55 42 4
gpt4 key购买 nike

我有两个程序:

  • 服务器...它在选定的多播上生成 UDP 流量
  • listener ...它打印所选多播上的 UDP 流量 (它订阅多播并打印 无论它收到什么)。

当我在一台计算机上运行服务器并在某些(其他)计算机上运行监听器时,监听器会看到 UDP 流量并正确打印它。所以这些程序应该处于良好状态。

但是,当我尝试使用 tcpdump 在任何计算机上捕获流量时:

sudo tcpdump -i eth0 'dst 233.65.120.153' -w 0.pcap

当我稍后尝试在任何机器上使用 tcpreplay 重播它时:

sudo tcpreplay -i eth0 0.pcap

没有一个监听器看到这些捕获的数据包:

09:38:40.975604 IP (tos 0x0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 32)
172.27.6.176.53507 > 233.65.120.153.64968: [udp sum ok] UDP, length 4
0x0000: 4500 0020 0000 4000 0111 6527 ac1b 06b0 E.....@...e'....
0x0010: e941 7899 d103 fdc8 000c 579c 6162 6364 .Ax.......W.abcd
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............
09:38:41.975709 IP (tos 0x0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 32)
172.27.6.176.53507 > 233.65.120.153.64968: [udp sum ok] UDP, length 4
0x0000: 4500 0020 0000 4000 0111 6527 ac1b 06b0 E.....@...e'....
0x0010: e941 7899 d103 fdc8 000c 579c 6162 6364 .Ax.......W.abcd
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............
09:38:42.975810 IP (tos 0x0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 32)
172.27.6.176.53507 > 233.65.120.153.64968: [udp sum ok] UDP, length 4
0x0000: 4500 0020 0000 4000 0111 6527 ac1b 06b0 E.....@...e'....
0x0010: e941 7899 d103 fdc8 000c 579c 6162 6364 .Ax.......W.abcd
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............

请注意,即使没有一个监听器看到 UDP 多播流量,我仍然可以在任何计算机上使用 tcpdump 看到它:

sudo tcpdump -i eth0 'dst 233.65.120.153' -X

我的问题:如果我想 tcpreplay 我正在创建的 UDP 多播流量,以便我可以在应用程序级别(例如我的监听器程序)上看到它,而不仅仅是在通过 tcpdump?

$猫发件人.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define PORT 64968
#define GROUP "233.65.120.153"

main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, cnt;
struct ip_mreq mreq;
char *message="abcd";

/* Create what looks like an ordinary UDP socket:
AF_INET ... IPv4
SOCK_DGRAM ... UDP
0 ... required constant
*/
if ((fd=socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
exit(1);
}

/* Set up destination address:
AF_INET ... IPv4
GROUP ... the IP-address of the multicast group
to which we want to multicast
PORT ... the UDP port that on which we want to multicast
*/
memset(&addr, 0, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(GROUP);
addr.sin_port=htons(PORT);

/* now just sendto() our destination! */
while (1) {
if (sendto(fd, message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
sleep(1);
}
}

$猫监听器.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define PORT 64968
#define GROUP "233.65.120.153"
#define MSGBUFSIZE 1000000

char msgbuf[MSGBUFSIZE];

main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;

u_int yes=1;

/* Create what looks like an ordinary UDP socket:
AF_INET ... IPv4
SOCK_DGRAM ... UDP
0 ... required constant
*/
if ((fd=socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
exit(1);
}

/* Allow multiple sockets to use the same PORT number:
SOL_SOCKET ... manipulate properties of the socket API itself
SO_REUSEADDR ... Allow reuse of local addresses for bind
*/
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}

/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
addr.sin_port=htons(PORT);

/* bind to receive address */
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);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}

/* now just enter a read-print loop */
while (1) {
addrlen=sizeof(addr);
memset(msgbuf, 0, MSGBUFSIZE);
if ((nbytes=recvfrom(fd, msgbuf, MSGBUFSIZE,0,
(struct sockaddr *) &addr, &addrlen)) < 0) {
perror("recvfrom");
exit(1);
}
printf("Incoming message size = %d\n", nbytes);
int i;
for (i=0; i < nbytes; i++)
printf("%02x ", ((unsigned char) msgbuf[i]));
printf("\n");
}
}

最佳答案

我们也遇到了同样的问题。通过 tcpdump 我们看到了数据;但是,多播客户端/监听器没有获取数据。然后我们意识到反向路径过滤器 (rp_filter) 拒绝了数据包。

禁用 rp-filter 后,客户端/监听器应用程序开始拾取数据包。使用以下命令禁用 rp_filter:

echo 0 >/proc/sys/net/ipv4/conf/eth0/rp_filter

上面的“eth0”如果不是 eth0,则替换为接收多播的接口(interface)

关于UDP 多播客户端看不到 tcpreplay 生成的 UDP 多播流量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13471680/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com