UDP 多播客户端看不到 tcpreplay 生成的 UDP 多播流量 [英] UDP multicast client does not see UDP multicast traffic generated by tcpreplay

查看:21
本文介绍了UDP 多播客户端看不到 tcpreplay 生成的 UDP 多播流量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个程序:

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

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

When I run the server on one machine and listeners on some (other) machine(s), the listener sees UDP traffic and prints it correctly. So these programs should be in a good shape.

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

However, when I try to capture the traffic, on whatever machine, with tcpdump:

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

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

and when I later try to replay it, on whatever machine, with tcpreplay:

sudo tcpreplay -i eth0 0.pcap

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

none of the listeners sees those captured packets:

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 看到它:

Note that even though none of the listeners sees UDP multicast traffic, I am still able to see it, on whatever machine, with tcpdump:

sudo tcpdump -i eth0 'dst 233.65.120.153' -X

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

My question: What should I do (differently) if I want to tcpreplay the UDP multicast traffic I am creating so that I can see it on application level (e.g. my listener program), not only by tcpdump?

$ cat sender.c

$ cat sender.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);
     }
}

$ cat listener.c

$ cat listener.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
", nbytes);
      int i;
      for (i=0; i < nbytes; i++)
              printf("%02x ", ((unsigned char) msgbuf[i]));
      printf("
");
     }
}

推荐答案

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

We had the same problem. With tcpdump we saw the data; however, the multicast client/listener was not picking up the data. Then we realized that the Reverse Path Filter (rp_filter) was rejecting the packets.

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

After disabling the rp-filter, the client/listener application started picking up the packets. Use the below command to disable rp_filter:

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

在上面,如果不是eth0,则将'eth0'替换为接收多播的接口

In the above, replace 'eth0' with the interface receiving the multicast if other than eth0

这篇关于UDP 多播客户端看不到 tcpreplay 生成的 UDP 多播流量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆