[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Unable to connect to a multicast session in Fedora 9 with realtek RTL8111/8168B



Hi,

I have been debugging this issue for quite some time and think I have
reproducible evidence that localizes this to the hardware.

I have a single nic, lspci lists it as:
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.
RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 02)

I want to connect to a multicast session using my Fedora 9. I have
successfully connected to the same multicast session using other PCs,
some running Fedora 9, some running other distos, and some running
Windows. If I put a 3com nic into my box, I am able to successfully
connect to the multicast session using my box.

I broke this down to a very simple program. I now just do the bare
minimum to connect to the stream. I am going to attach the c file of
the program. When I run this on a working computer, it gets through
the loop grabbing data off the multicast session. When I run this on
my box with the realtek chip, the program block on the call recvfrom()
forever.

I am left to conclude this is a bug in the realtek driver that is
preventing proper joining of a multicast session.

Any idea about how to resolve this or test it further?

Thanks,
Jon
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>


#define BUF_LEN 256
#define MADDR "235.0.0.3"
#define PORT 17000

int main(int argc, char *argv[])
{
	struct sockaddr_in sin;
	struct ip_mreq mreq;
	socklen_t sin_len;
	int sock_fd;
	char buf[BUF_LEN];
	int bytes_received;
	int i;

	sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock_fd < 0) {
		perror("unable to open socket fd\n");
		exit(1);
	}

	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = INADDR_ANY;
	sin_len = sizeof(sin);
	if(bind(sock_fd, (struct sockaddr *)&sin, sin_len)) {
		perror("unable to bind socket\n");
		close(sock_fd);
		exit(1);
	}

	mreq.imr_multiaddr.s_addr = inet_addr(MADDR);
	mreq.imr_interface.s_addr = INADDR_ANY;
	if(setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
        perror("unable to add membership\n");
        close(sock_fd);
        exit(1);
	}

	for (i = 0; i < 10; i++) {
		struct timespec sleeptime = {
			.tv_sec = 1,
			.tv_nsec = 0,
		};


        printf("loop %d:\n", i);
		bytes_received = recvfrom(sock_fd, buf, BUF_LEN, 0, NULL, NULL);
		printf("\treceived %d bytes\n", bytes_received);
		nanosleep(&sleeptime, NULL);
	}

	setsockopt(sock_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
	close(sock_fd);
	return 0;
}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]