1

I have a multicast packet from a capture using tcpdump. I can replay the packet using tcpreplay -i eth0 on.pcap and I can receive it on another machine using tcpdump.

I have tried c code and python code to try and capture this packet without success. I've tried both on MacOS and Raspian (Rpi 3b).

https://mega.nz/#!ELAgBSDL!XZ3EXCkDBsLLwFn8J1ofWuMm4Z7sssOZPuZVEpmRqvs

here is a c code example:

/*
multicast.c

The following program sends or receives multicast packets. If invoked
with one argument, it sends a packet containing the current time to an
arbitrarily chosen multicast group and UDP port. If invoked with no
arguments, it receives and prints these packets. Start it as a sender on
just one host and as a receiver on all the other hosts

*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>

#define EXAMPLE_PORT 2068
#define EXAMPLE_GROUP "226.2.2.2"

main(int argc)
{
   struct sockaddr_in addr;
   int addrlen, sock, cnt;
   struct ip_mreq mreq;
   char message[50];

   /* set up socket */
   sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (sock < 0) 
   {
     perror("socket");
     exit(1);
   }

   bzero((char *)&addr, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = htonl(INADDR_ANY);
   addr.sin_port = htons(EXAMPLE_PORT);
   addrlen = sizeof(addr);

   if (argc > 1) 
   {
      /* send */
     addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
     while (1) 
     {
         time_t t = time(0);
         sprintf(message, "time is %-24.24s", ctime(&t));
         printf("sending: %s\n", message);
         cnt = sendto(sock, message, sizeof(message), 0,
                  (struct sockaddr *) &addr, addrlen);
         if (cnt < 0) 
         {
            perror("sendto");
            exit(1);
         }
         sleep(5);
     }
   } 
   else 
   {

      /* receive */
     if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) 
     {        
         perror("bind");
         exit(1);
     }

     mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);         
     mreq.imr_interface.s_addr = htonl(INADDR_ANY);         
     if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
             &mreq, sizeof(mreq)) < 0) 
     {
         perror("setsockopt mreq");
         exit(1);
     } 

     while (1) 
     {
         cnt = recvfrom(sock, message, sizeof(message), 0, 
                (struct sockaddr *) &addr, &addrlen);
         if (cnt < 0) 
         {
            perror("recvfrom");
            exit(1);
         } 
         else if (cnt == 0) 
         {
            break;
         }
         printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
     }
   }
}

Here is a python example:

#!/usr/bin/env python

import socket
import binascii
import sys

MCAST_GRP = '226.2.2.2'
MCAST_PORT = 2068 
MCAST_IFACE = '192.168.168.200'

def joinMcast(mcast_addr,port,if_ip):
  """
  Returns a live multicast socket
  mcast_addr is a dotted string format of the multicast group
  port is an integer of the UDP port you want to receive
  if_ip is a dotted string format of the interface you will use
  """

  #create a UDP socket
  mcastsock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

  #allow other sockets to bind this port too
  mcastsock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

  #explicitly join the multicast group on the interface specified
  mcastsock.setsockopt(socket.SOL_IP,socket.IP_ADD_MEMBERSHIP,
      socket.inet_aton(mcast_addr)+socket.inet_aton(if_ip))

  #finally bind the socket to start getting data into your socket
  mcastsock.bind((mcast_addr,port))

  return mcastsock

def main():
  sock = joinMcast(MCAST_GRP, MCAST_PORT, MCAST_IFACE)

  while True:
    print >>sys.stderr, '\nwaiting to receive message'
    print sock.recv(1024)

if __name__ == '__main__':
  main()
John Smith
  • 3,493
  • 3
  • 25
  • 52
  • 1
    Assuming you're sending correctly, both of these should work. The only thing you need to do is set the interface IP where you'll receive multicast. In the python code, that would be `MCAST_IFACE`. In the C code you want to change `mreq.imr_interface.s_addr`. – dbush Mar 20 '18 at 16:47
  • That was the problem. I had two interfaces and didn't know how to actually force an interface. – John Smith Mar 23 '18 at 00:23

0 Answers0