lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Tue, 19 Feb 2008 09:40:03 +0100
From:	"Reither Robert" <Robert.Reither@...digital.at>
To:	"David Stevens" <dlstevens@...ibm.com>
CC:	<netdev@...r.kernel.org>
Subject: AW: Problem receiving multicast/promiscuous-mode with kernel.2.6.24

Visit AVD on prolight+sound in Frankfurt from 12.-15. March 2008 - Hall 8.0, Stand G16
________________________________________________________________________



Hi,

ok, i managed to shrink down my code to show the behaviour in small size ;-)

It shows the same effect as my app, sometimes i get all the packets after a mc_join, sometimes i get only the timeouts.
I find no predictive behaviour, i'm really desperate ...
Hope you can see the effect too .. Do u need an app sending the multicast VLAN packets ?

Robert

-----------------------------------------

#include <stdint.h>
#include <sys/select.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <errno.h>
#include <netdb.h>

//#include <linux/if.h>
#include <linux/sockios.h>
#include <sys/ioctl.h>

//#define JOIN_SINGLE_IF
#undef JOIN_SINGLE_IF


#define PORT 10500

/*
** Try to receive VLAN-tagged UDP multicast packets 
** VLAN-ID:3, VLAN_PRI=6, Addr: 224.1.9.0, dstnport 10500
**
** Kernel used: 2.6.24
**
** HW: VIA Epia 5000, VIA Epia LT (VIA Rhine II and VIA VT6107)
**
** Additional network settings:
** vconfig add eth0 3
** vconfig set_egress_map eth0.3 6 6
** ifconfig eth0.3 10.0.0.1
** route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0.3
**
*/

#define MAX_PAYLOAD 1000

/* 
 * Network representation of the rtp header.
 */

struct rtp_header {
#ifdef WORDS_BIGENDIAN
        uint16_t version:2;
        uint16_t padbit:1;
        uint16_t extbit:1;
        uint16_t cc:4;
        uint16_t markbit:1;
        uint16_t paytype:7;
#else
        uint16_t cc:4;
        uint16_t extbit:1;
        uint16_t padbit:1;
        uint16_t version:2;
        uint16_t paytype:7;
        uint16_t markbit:1;
#endif
        uint16_t seq_number;
        uint32_t timestamp;
        uint32_t ssrc;

	/* In fact we rely on rtp_header being not larger than 
	 * the minimum header length. So, there's no contributing
	 * sync source field here. */
};

struct rtp_packet {
	struct rtp_header header;
	unsigned char payload[MAX_PAYLOAD];
};


#ifdef WORDS_BIGENDIAN
#error Sorry this is not supported on bigendian targets.
#endif

#define BYTE0(x) ((x) & 0xff)
#define BYTE1(x) (((x) >> 8)  & 0xff)
#define BYTE2(x) (((x) >> 16)  & 0xff)
#define BYTE3(x) (((x) >> 24)  & 0xff)

static char *my_inet_ntoa (char *buf, size_t n, struct in_addr in)
{
	if (snprintf (buf, n, "%u.%u.%u.%u", BYTE0(in.s_addr), BYTE1(in.s_addr), BYTE2(in.s_addr), BYTE3(in.s_addr))  >= n) {
		return NULL;
	}
	return buf;
}

static int set_non_blocking (int fd)
{
	int flags;

	if ((flags = fcntl (fd, F_GETFL)) < 0) {
		perror ("fcntl getflags ()");
		return -1;
	}
	if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0) {
		perror ("fcntl setflags ()");
		return -1;
	}

	return fd;
}

int main()
{
  int fd;
  fd_set read_fds;
  struct timespec timeout;
  
  while(1)
  {
    int i, ret;

  	if ((fd = subscribe_udp (PORT)) < 0) {
  		printf("Could not register UDP port.\n");
   		return 1;
    }
    	
  
  	if (join_multicast_group (fd, "224.1.9.0") < 0)
  	{
  	  printf("Error joining multicast !\n");
  	  return 1;  
  	}

    for(i=0;i<10;i++)
    {

      FD_ZERO (&read_fds);
    	FD_SET (fd, &read_fds);
    	timeout.tv_sec = 1;
    	timeout.tv_nsec = 0;
  
  
  		ret = pselect (fd+1, &read_fds, NULL, NULL, &timeout, NULL);
  
  
  		if (ret < 0) {
  			if (errno == EINTR) {
  				continue;
  			} else {
  				printf("select failed.\n");
  				return 1;
  			}
  		}

      if (FD_ISSET(fd, &read_fds))
      {
        ssize_t len;
      	struct rtp_packet p; 
      	struct sockaddr_in from;
      	socklen_t fromlen;
      	char from_ip[20];
        
    	  len = recvfrom (fd, &p, sizeof (p), 0, (struct sockaddr*) &from, &fromlen);
      	my_inet_ntoa (from_ip, sizeof (from_ip), from.sin_addr);
    
        printf("Received data packet from %s, length %u\n", from_ip, len);
      }
      else
      {
        printf("Got timeout receiving Multicast packets !\n");  
      }
    } /* loop 10 */
  
    if (leave_multicast_group(fd, "224.1.9.0") < 0)
  	{
  	  printf("Error leaving multicast !\n");
  	  return 1;  
  	}
    close(fd);	
  }
}

int subscribe_udp (int port)
{
	int s; 

	s = create_listening_socket (port, 1);
	return s;
}

int create_listening_socket (int listen_port, int udp) 
{
	struct sockaddr_in a;
	int s;
	int yes;
	if ((s = socket (AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) {
		perror ("socket");
		return -1;
	}
	yes = 1;
	if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR,
		 (char *) &yes, sizeof (yes)) < 0) {
		perror ("setsockopt reuseaddr");
		close (s);
		return -1;
	}

	memset (&a, 0, sizeof (a));

	a.sin_port = htons (listen_port);
	a.sin_family = AF_INET;
	if (bind (s, (struct sockaddr *) &a, sizeof (a)) < 0) {
		perror ("bind");
		close (s);
		return -1;
	}
	if (set_non_blocking (s) < 0) {
		close (s);
		return -1;
	}

	if (!udp) {
		listen (s, 10);
	}
	return s;
}

int join_multicast_group (int fd, const char *mc_address)
{
	struct ip_mreqn imr;

  printf("In join_mc_group: %s\n",mc_address);


  if (inet_pton(AF_INET, mc_address, &imr.imr_multiaddr) != 1) {
//old	if (inet_aton (mc_address, &imr.imr_multiaddr) == 0) {
		printf ( "join_mc:Bad IP address format: %s\n", mc_address);
		return -1;
	}

	imr.imr_address.s_addr = INADDR_ANY;

#ifdef JOIN_SINGLE_IF
	imr.imr_ifindex = if_nametoindex("eth0.3"); // 0;
//	imr.imr_ifindex = if_nametoindex("eth0"); // Testing
  if (imr.imr_ifindex == 0)
  {
		printf ("join_mc:Got no interface-number from name !\n");
		return -1;    
  }
#else
	imr.imr_ifindex = 0;
#endif

  // Check if already member
	if (setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof (imr)) < 0)
	{
	  if (errno == EADDRINUSE) // Address already joined for IP_ADD_MEMBERSHIP
	    printf("Already joined IP_ADD_MEMBERSHIP for %s.\n", mc_address);
    else
    {
  		perror ("getsockopt ip_add_membership");
  		return -1;
	  }
	}
	return 0;
}

int leave_multicast_group(int fd, const char *mc_address)
{
	struct ip_mreqn imr;

  printf("In leave_mc_group: %s\n",mc_address);

  if (inet_pton(AF_INET, mc_address, &imr.imr_multiaddr) != 1) {
//	if (inet_aton (mc_address, &imr.imr_multiaddr) == 0) {
		printf ("leave_mc:Bad IP address format: %s\n", mc_address);
		return -1;
	}

	imr.imr_address.s_addr = INADDR_ANY;

#ifdef JOIN_SINGLE_IF
	imr.imr_ifindex = if_nametoindex("eth0.3"); // 0 VLAN_ID ist aber vernderbar !!!!!
//	imr.imr_ifindex = if_nametoindex("eth0"); // 0
  if (imr.imr_ifindex == 0)
  {
		printf ("leave_mc:Got no interface-namber from name !\n");
		return -1;    
  }
#else
	imr.imr_ifindex = 0;
#endif

	if (setsockopt (fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof (imr)) < 0) {
		perror ("setsockopt ip_drop_membership");
		return -1;
	}
  return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists