[vlc-devel] [patch] IGMPv3 support for Linux
Alexis de Lattre
alexis at via.ecp.fr
Sun Feb 1 02:15:13 CET 2004
After I commited the support of IGMPv3 support for Win32, I started
working on IGMPv3 support for Linux. As the required headers are not
part of glibc, Gibalou suggested to write the required headers
inside the code of ipv4.c, i.e. :
- #define IP_ADD_SOURCE_MEMBERSHIP 39
- create a vlc_ip_mreq_source structure to remplace the missing
ip_mreq_source structure.
With that code, IGMPv3 was working fine on Linux but not on Win32 any
more. After some tests, I figured out that Win32 didn't like the new
vlc_ip_mreq_source, but wanted to have the ip_mreq_source structure, even
if the definition is the same ! I don't understand why...
So I decided to put :
#if defined( SYS_LINUX )
struct ip_mreq_source {
struct in_addr imr_multiaddr;
struct in_addr imr_interface;
struct in_addr imr_sourceaddr;
};
#define IP_ADD_SOURCE_MEMBERSHIP 39
#endif
so that ip_mreq_source is defined by this code under Linux, but Win32
uses it's headers to define the structure. With that solution, it works
under Win32 and Linux. I have also put some #if defined( SYS_DARWIN ) to
avoid all code duplication, as suggested by Gibalou.
Here is a new package for win32:
http://vthr.via.ecp.fr/~alexis/vlc-0.7.1-igmpv3-11.zip
Here is an example of an IGMPv3 request under Linux:
http://vthr.via.ecp.fr/~alexis/ethereal-igmpv3-linux-1.png
I would like to have some comments on my patch enclosed before I commit
it.
Moreover, can someone check if OSX implements IP_ADD_SOURCE_MEMBERSHIP
or not ? If the answer is yes, I would then remove my #if defined(
SYS_DARWIN ) to enable IGMPv3 support for OSX...
--
Alexis
-------------- next part --------------
diff -Nru vlc/modules/misc/network/ipv4.c vlc-igmpv3/modules/misc/network/ipv4.c
--- vlc/modules/misc/network/ipv4.c 2004-01-31 19:02:32.000000000 +0100
+++ vlc-igmpv3/modules/misc/network/ipv4.c 2004-02-01 01:47:31.000000000 +0100
@@ -74,6 +74,7 @@
# define IN_MULTICAST(a) IN_CLASSD(a)
#endif
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
@@ -153,6 +154,18 @@
socklen_t i_opt_size;
struct sockaddr_in sock;
+ /* As IGMPv3 headers are not part of glibc yet, we have to define the
+ headers for Linux here */
+#if defined( SYS_LINUX )
+ struct ip_mreq_source {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+ struct in_addr imr_sourceaddr;
+ };
+
+ #define IP_ADD_SOURCE_MEMBERSHIP 39
+#endif
+
/* Open a SOCK_DGRAM (UDP) socket, in the AF_INET domain, automatic (0)
* protocol */
if( (i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 )
@@ -282,16 +295,14 @@
}
}
-#if defined( WIN32 )
-/* Only Win32 has the support for IP_ADD_SOURCE_MEMBERSHIP
- with the headers that are included */
-
+#if !defined( UNDER_CE ) && !defined( SYS_BEOS )
/* Join the multicast group if the socket is a multicast address */
if( IN_MULTICAST( ntohl(sock.sin_addr.s_addr) ) )
{
/* Determine interface to be used for multicast */
char * psz_if_addr = config_GetPsz( p_this, "iface-addr" );
+#if !defined( SYS_DARWIN )
/* If we have a source address, we use IP_ADD_SOURCE_MEMBERSHIP
so that IGMPv3 aware OSes running on IGMPv3 aware networks
will do an IGMPv3 query on the network */
@@ -316,7 +327,8 @@
msg_Dbg( p_this, "IP_ADD_SOURCE_MEMBERSHIP multicast request" );
/* Join Multicast group with source filter */
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
msg_Err( p_this, "failed to join IP multicast group (%s)",
@@ -331,6 +343,7 @@
/* If there is no source address, we use IP_ADD_MEMBERSHIP */
else
{
+#endif
struct ip_mreq imr;
imr.imr_multiaddr.s_addr = sock.sin_addr.s_addr;
@@ -359,47 +372,9 @@
close( i_handle );
return( -1 );
}
+#if !defined( SYS_DARWIN )
}
- }
#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
More information about the vlc-devel
mailing list