Hello, I have two programs: - sender ... which generates some UDP multicast traffic - listener ... which listens to a given UDP multicast group (in this case 233.65.120.153:64968) When I compile these two programs, all seems to be working fine. All "listeners" on the local network are getting data from the "sender". So I believe that routers/switches are configured properly and the transmitted packets have correct Ethernet/IP/UDP headers. Now I am trying to capture the traffic with "tcpdump": sudo tcpdump -i eth0 -X 'dst 233.65.120.153' -w 0.pcap (attached). However, when I try to replay this pcap-file: $ sudo tcpreplay -i eth0 0.pcap sending out eth0 processing file: 0.pcap Actual: 4 packets (240 bytes) sent in 3.00 seconds Rated: 80.0 bps, 0.00 Mbps, 1.33 pps Statistics for network device: eth0 Attempted packets: 4 Successful packets: 4 Failed packets: 0 Retried packets (ENOBUFS): 0 Retried packets (EAGAIN): None of the listeners on a given multicast sees that traffic. I am sure there is a pretty good reason for that but I cannot figure this out. :-/ I have check that: - last 3 bytes at of the destination MAC address correspond to last three bytes of the destination IP address. - destination IP is OK - destination port is OK If anybody has some good advice what I did wrong, any help would be most welcome. Thanks in advance.
/* Compatible listeners: * - ~/work/net/udp-multicast/2/listener ... works on the local machine as well as on the remote one * - sudo tcpdump -i eth0 -X dst 225.0.0.37 ... works on the local machine * works on a remote machine if some of its processes subscribed to a given multicast * (tcpdump does not subscribe itself) * To subscribe the remote machine to our multicast, we can either run the aforementioned listener, * or execute this command: * - iperf -s -u -B 225.0.0.37 */ #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 HELLO_PORT 64968 #define HELLO_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 HELLO_GROUP ... the IP-address of the multicast group to which we want to multicast HELLO_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(HELLO_GROUP); addr.sin_port=htons(HELLO_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); } }
/* * Compatible senders: * - ~/work/net/udp-multicast/2/sender * - ~/doc/ocaml/net/udp-multicast/1/sender */ /* sudo tcpdump -X -vv -i eth0 'dst 225.0.0.37' */ #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 HELLO_PORT 64968 #define HELLO_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; /*** MODIFICATION TO ORIGINAL */ /* 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(HELLO_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(HELLO_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"); } }
Attachment:
0.pcap
Description: application/vnd.tcpdump.pcap