Hi,

I have two servers, one running linux 2.4.30, the other running 2.6.15.
I am having problems hearing multicast traffic on the one running
2.6.15. At the end of this posting is some simple code showing my
problem. On the 2.4.30 server, the program terminates as expected, but
on the 2.6.15 server, the program never returns from recv(). Multicast
is enabled in the kernel for both servers, they are plugged into the
same network switch, and the interface receiving multicast traffic on
both servers eth1.

Here is the output of ifconfig eth1 on my 2.6.15 server:
eth1 Link encap:Ethernet HWaddr 00:C0:9F:05:251
inet addr:192.168.6.7 Bcast:192.168.6.255
Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:46115978 errors:0 dropped:0 overruns:0 frame:0
TX packets:480 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3952568593 (3769.4 Mb) TX bytes:40140 (39.1 Kb)
Interrupt:7

Using tcpdump, I have verified that the multicast traffic is in fact
streaming over the eth1 interface:
purple ~ # tcpdump -i eth1 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol
decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
00:22:13.545253 IP 192.168.6.2.6517 > 255.255.255.255.6516: UDP, length
138
00:22:13.922034 IP 10.0.9.51 > 224.0.1.1: udp
00:22:13.933675 IP 10.0.9.51.32770 > 224.0.1.1.1201: UDP, length 1957
00:22:13.940815 IP 10.0.9.51 > 224.0.1.1: udp
00:22:13.945432 IP 10.0.9.51.32770 > 224.0.1.1.1201: UDP, length 1860
00:22:13.946038 IP 10.0.9.51 > 224.0.1.1: udp
00:22:13.947347 IP 10.0.9.51.32770 > 224.0.1.1.1201: UDP, length 2294
00:22:13.949881 IP 10.0.9.51.32770 > 224.0.1.1.1201: UDP, length 163
00:22:13.950742 IP 10.0.9.51 > 224.0.1.1: udp
00:22:13.962023 IP 10.0.9.51.32770 > 224.0.1.1.1201: UDP, length 2271
.....

What am I doing wrong?

Thanks for any help,
Nathan Bain



------ code segment ------
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[])
{
char *device_address = "192.168.6.7"; // address on eth1
char *group = "224.0.1.1";
int port = 1201;

struct hostent *h;
if ((h = gethostbyname(group)) == NULL)
{
fprintf(stderr, "unknown host '%s'\n", group);
return -1;
}

struct in_addr mcast_address;
memcpy(&mcast_address, h->h_addr_list[0], h->h_length);

int s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0)
{
perror("socket");
return -1;
}

struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(port);

if (bind(s, (struct sockaddr *) &server_address,
sizeof(server_address)) < 0)
{
perror("bind");
close(s);
return -1;
}

struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = mcast_address.s_addr;
h = gethostbyname(device_address);
memcpy((char *) &(mreq.imr_interface.s_addr),
h->h_addr_list[0], h->h_length);
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
{
perror("IP_ADD_MEMBERSHIP");
close(s);
return -1;
}

fprintf(stderr, "Listening on %s to %s:%d\n", device_address,
group, port);

int buffer_length = 4096;
unsigned char *buffer = (unsigned char *)
malloc(buffer_length);
int packet_length;
if ((packet_length = recv(s, (void *) buffer, buffer_length,
0)) < 0)
{
perror("recv");
close(s);
return -1;
}
fprintf(stderr, "Received %d-byte packet\n", packet_length);

free(buffer);

return 0;
}