0

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.

No One in Particular
  • 2,846
  • 4
  • 27
  • 32
  • 1
    Depends on what you are doing inside the sendto() function in the first code snippet (OSX) and read() function in the second snippet (Linux). Maybe you are missing to flush some output stream that is sent/received, which somehow gets flushed when you run tcpdump later? – Prahlad Yeri Feb 16 '13 at 16:33
  • The sendto on OSX is doing just fine when talking to another OSX box. – No One in Particular Feb 22 '13 at 21:17
  • Hmmn. Which particular Linux distribution are you using? If possible, could you try connecting to an alternate fresh distribution (other than the one you are using)? (This will be easier if you are doing this in a virtual machine). This will tell you whether there is any configuration issue on the linux end. – Prahlad Yeri Feb 23 '13 at 13:56

0 Answers0