I have a small network consisting of 2 hosts (OS X and linux) with a switch between them. When I run the following pair of programs, the receiver (linux) doesn't see any multicast packets. However, when I run
tcpdump -i eth0 -s 512 udp
on the linux box, everything starts to work. Can someone tell me why running tcpdump enables this to work?
Note that both machines have IPv6 enabled (if that matters). The host addresses in the code are the IPv4 addresses of the local interfaces.
On the OS X machine, I run:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define BUFLEN 256
int s;
int count;
struct in_addr local_address;
struct sockaddr_in multicast_address;
char buffer[BUFLEN];
int
main (int argc, char *argv[]) {
int port = 12345;
int retval = 0;
char *host_ip = "192.168.1.31";
char *multicast_ip = "224.0.0.251";
count = (int)time(NULL);
s = socket(AF_INET, SOCK_DGRAM, 0);
printf("s=%d\n", s);
local_address.s_addr = inet_addr(host_ip);
retval = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&local_address, sizeof(local_address));
printf("setsockopt=%d\n", retval);
memset((char *)&multicast_address, 0, sizeof(multicast_address));
multicast_address.sin_family = AF_INET;
multicast_address.sin_addr.s_addr = inet_addr(multicast_ip);
multicast_address.sin_port = htons(port);
while (1) {
sprintf(buffer, "Message number %d", count);
count++;
retval = sendto(s, buffer, BUFLEN, 0, (struct sockaddr*)&multicast_address, sizeof(multicast_address));
printf("sendto=%d\n", retval);
sleep(3);
}
return 0;
}
On the linux box, I run:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define BUFLEN 256
int s;
struct ip_mreq multicast_group;
struct sockaddr_in localSock;
char buffer[BUFLEN];
int
main(int argc, char *argv[]) {
int reuse = 1;
int retval = 0;
int port = 12345;
char *host_ip = "192.168.1.131";
char *multicast_ip = "224.0.0.251";
s = socket(AF_INET, SOCK_DGRAM, 0);
printf("s = %d\n", s);
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
printf("REUSEADDR = %d\n", retval);
memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(port);
localSock.sin_addr.s_addr = INADDR_ANY;
retval = bind(s, (struct sockaddr*)&localSock, sizeof(localSock));
printf("bind = %d\n", retval);
multicast_group.imr_multiaddr.s_addr = inet_addr(multicast_ip);
multicast_group.imr_interface.s_addr = inet_addr(host_ip);
retval = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&multicast_group, sizeof(multicast_group));
printf("ADD_MEMBERSHIP = %d\n", retval);
while (1) {
retval = read(s, buffer, BUFLEN);
printf("%d => [%s]\n", retval, buffer);
}
return 0;
}
Thanks.