Commit c1b4f483 authored by Alexis de Lattre's avatar Alexis de Lattre

* ipv4.c: IGMPv3 support for Linux

  Differences with the patch I posted in vlc-devel yesterday:
  - took into account the suggestions of gibalou
  - removed the "#if !defined( SYS_DARWIN )", because it should compile
    fine on Mac OS X, even if IGMPv3 won't work
  - added a warning about non-IGMPv3 OSes
parent a11a1831
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ipv4.c: IPv4 network abstraction layer * ipv4.c: IPv4 network abstraction layer
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: ipv4.c,v 1.23 2004/01/31 18:02:32 alexis Exp $ * $Id: ipv4.c,v 1.24 2004/02/01 14:43:08 alexis Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Mathias Kretschmer <mathias@research.att.com> * Mathias Kretschmer <mathias@research.att.com>
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
# define IN_MULTICAST(a) IN_CLASSD(a) # define IN_MULTICAST(a) IN_CLASSD(a)
#endif #endif
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -153,6 +154,18 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -153,6 +154,18 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
socklen_t i_opt_size; socklen_t i_opt_size;
struct sockaddr_in sock; struct sockaddr_in sock;
/* If IP_ADD_SOURCE_MEMBERSHIP is not defined in the headers
(because it's not in glibc for example), we have to define the
headers required for IGMPv3 here */
#ifndef IP_ADD_SOURCE_MEMBERSHIP
#define IP_ADD_SOURCE_MEMBERSHIP 39
struct ip_mreq_source {
struct in_addr imr_multiaddr;
struct in_addr imr_interface;
struct in_addr imr_sourceaddr;
};
#endif
/* Open a SOCK_DGRAM (UDP) socket, in the AF_INET domain, automatic (0) /* Open a SOCK_DGRAM (UDP) socket, in the AF_INET domain, automatic (0)
* protocol */ * protocol */
if( (i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 ) if( (i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 )
...@@ -282,10 +295,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -282,10 +295,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
} }
} }
#if defined( WIN32 ) #if !defined( UNDER_CE ) && !defined( SYS_BEOS )
/* Only Win32 has the support for IP_ADD_SOURCE_MEMBERSHIP
with the headers that are included */
/* Join the multicast group if the socket is a multicast address */ /* Join the multicast group if the socket is a multicast address */
if( IN_MULTICAST( ntohl(sock.sin_addr.s_addr) ) ) if( IN_MULTICAST( ntohl(sock.sin_addr.s_addr) ) )
{ {
...@@ -316,13 +326,16 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -316,13 +326,16 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
msg_Dbg( p_this, "IP_ADD_SOURCE_MEMBERSHIP multicast request" ); msg_Dbg( p_this, "IP_ADD_SOURCE_MEMBERSHIP multicast request" );
/* Join Multicast group with source filter */ /* Join Multicast group with source filter */
if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
(char*)&imr, sizeof(struct ip_mreq_source) ) == -1 ) (char*)&imr,
sizeof(struct ip_mreq_source) ) == -1 )
{ {
#ifdef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H
msg_Err( p_this, "failed to join IP multicast group (%s)", msg_Err( p_this, "failed to join IP multicast group (%s)",
strerror(errno) ); strerror(errno) );
msg_Err( p_this, "are you sure your OS supports IGMPv3?" );
#else #else
msg_Err( p_this, "failed to join IP multicast group" ); msg_Err( p_this, "failed to join IP multicast group" );
msg_Err( p_this, "are you sure your OS supports IGMPv3?" );
#endif #endif
close( i_handle ); close( i_handle );
return( -1 ); return( -1 );
...@@ -363,46 +376,6 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -363,46 +376,6 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
} }
#endif #endif
#if !defined( UNDER_CE ) && !defined( SYS_BEOS ) && !defined( WIN32 )
/* This code is for the OSes that have multicast support but
don't have IP_ADD_SOURCE_MEMBERSHIP with the headers included */
/* Join the multicast group if the socket is a multicast address */
if( IN_MULTICAST( ntohl(sock.sin_addr.s_addr) ) )
{
struct ip_mreq imr;
/* Determine interface to be used for multicast */
char * psz_if_addr = config_GetPsz( p_this, "iface-addr" );
imr.imr_multiaddr.s_addr = sock.sin_addr.s_addr;
if( psz_if_addr != NULL && *psz_if_addr
&& inet_addr(psz_if_addr) != INADDR_NONE )
{
imr.imr_interface.s_addr = inet_addr(psz_if_addr);
}
else
{
imr.imr_interface.s_addr = INADDR_ANY;
}
if( psz_if_addr != NULL ) free( psz_if_addr );
msg_Dbg( p_this, "IP_ADD_MEMBERSHIP multicast request" );
/* Join Multicast group */
if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*)&imr, sizeof(struct ip_mreq) ) == -1 )
{
#ifdef HAVE_ERRNO_H
msg_Err( p_this, "failed to join IP multicast group (%s)",
strerror(errno) );
#else
msg_Err( p_this, "failed to join IP multicast group" );
#endif
close( i_handle );
return( -1 );
}
}
#endif
if( *psz_server_addr ) if( *psz_server_addr )
{ {
/* Build socket for remote connection */ /* Build socket for remote connection */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment