如何以编程方式捕获多播数据包

时间:2018-03-20 16:36:50

标签: python c macos raspberry-pi3 packet-capture

我使用tcpdump从捕获中获取了多播数据包。我可以使用tcpreplay -i eth0 on.pcap重播数据包,我可以使用tcpdump在另一台机器上接收它。

我已经尝试了c代码和python代码来尝试捕获此数据包但没有成功。我在MacOS和Raspian(Rpi 3b)上都试过了。

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

这是一个c代码示例:

/*
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);
     }
   }
}

这是一个python示例:

#!/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()

0 个答案:

没有答案