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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to