#if defined (WIN32) || defined (UNDER_CE)
else
{
- typedef DWORD (CALLBACK * GETBESTINTERFACE) ( IPAddr, PDWORD );
- typedef DWORD (CALLBACK * GETIPADDRTABLE) ( PMIB_IPADDRTABLE, PULONG, BOOL );
+ typedef DWORD (CALLBACK * GETBESTINTERFACE) ( IPAddr, PDWORD );
+ typedef DWORD (CALLBACK * GETIPADDRTABLE) ( PMIB_IPADDRTABLE, PULONG, BOOL );
GETBESTINTERFACE OurGetBestInterface;
- GETIPADDRTABLE OurGetIpAddrTable;
+ GETIPADDRTABLE OurGetIpAddrTable;
HINSTANCE hiphlpapi = LoadLibrary(_T("Iphlpapi.dll"));
DWORD i_index;
#include <errno.h>
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
#ifdef WIN32
# include <winsock2.h>
# include <ws2tcpip.h>
-#elif !defined( SYS_BEOS ) && !defined( SYS_NTO )
+# define if_nametoindex( str ) atoi( str )
+#else
+# include <sys/types.h>
+# include <unistd.h>
# include <netdb.h> /* hostent ... */
# include <sys/socket.h>
# include <netinet/in.h>
+# include <net/if.h>
#endif
#include "network.h"
if( *psz_server_addr )
{
- int ttl = p_socket->i_ttl;
- if( ttl <= 0 )
- ttl = config_GetInt( p_this, "ttl" );
+ int ttl;
/* Build socket for remote connection */
if ( BuildAddr( p_this, &sock, psz_server_addr, i_server_port ) == -1 )
}
/* Set the time-to-live */
+ ttl = p_socket->i_ttl;
+ if( ttl <= 0 )
+ ttl = config_GetInt( p_this, "ttl" );
+
if( ttl > 0 )
{
-#if defined( WIN32 ) || defined( HAVE_IF_NAMETOINDEX )
if( IN6_IS_ADDR_MULTICAST(&sock.sin6_addr) )
{
if( setsockopt( i_handle, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
}
}
else
-#endif
{
if( setsockopt( i_handle, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
(void *)&ttl, sizeof( ttl ) ) < 0 )
}
}
}
+
+ /* Set multicast output interface */
+ if( IN6_IS_ADDR_MULTICAST(&sock.sin6_addr) )
+ {
+ char *psz_mif = config_GetPsz( p_this, "miface" );
+ if( psz_mif != NULL )
+ {
+ int intf = if_nametoindex( psz_mif );
+ free( psz_mif );
+
+ if( intf != 0 )
+ {
+ if( setsockopt( i_handle, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ &intf, sizeof( intf ) ) < 0 )
+ {
+ msg_Err( p_this, "%s as multicast interface: %s",
+ psz_mif, strerror(errno) );
+ close( i_handle );
+ return 0;
+ }
+ }
+ else
+ {
+ msg_Err( p_this, "%s: bad IPv6 interface spefication",
+ psz_mif );
+ close( i_handle );
+ return 0;
+ }
+ }
+ }
}
p_socket->i_handle = i_handle;
/*****************************************************************************
* libvlc.h: main libvlc header
*****************************************************************************
- * Copyright (C) 1998-2005 VideoLAN (Centrale Réseaux) and its contributors
+ * Copyright (C) 1998-2006 the VideoLAN team
* $Id$
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
#define SERVER_PORT_TEXT N_("UDP port")
#define SERVER_PORT_LONGTEXT N_( \
- "This is the port used for UDP streams. By default, we chose 1234.")
+ "This is the port used for UDP streams. 1234 by default.")
#define MTU_TEXT N_("MTU of the network interface")
#define MTU_LONGTEXT N_( \
"Specify the hop limit (TTL) of the multicast packets sent by " \
"the stream output.")
-#define MIFACE_TEXT N_("Multicast output interface")
+#define MIFACE_TEXT N_("IPv6 multicast output interface")
#define MIFACE_LONGTEXT N_( \
"Indicate here the multicast output interface. " \
"This overrides the routing table.")
+#define MIFACE_ADDR_TEXT N_("IPv4 multicast output interface address")
+#define MIFACE_ADDR_LONGTEXT N_( \
+ "Specify the IPv4 address of the networking interface. " \
+ "This overrides the routing table.")
+
#define INPUT_PROGRAM_TEXT N_("Program to select")
#define INPUT_PROGRAM_LONGTEXT N_( \
"Choose the program to select by giving its Service ID.\n" \
add_module( "access_output", "sout access", NULL, NULL,
ACCESS_OUTPUT_TEXT, ACCESS_OUTPUT_LONGTEXT, VLC_TRUE );
add_integer( "ttl", 1, NULL, TTL_TEXT, TTL_LONGTEXT, VLC_TRUE );
- add_string( "miface-addr", NULL, NULL, MIFACE_TEXT, MIFACE_LONGTEXT, VLC_TRUE );
+ add_string( "miface", NULL, NULL, MIFACE_TEXT, MIFACE_LONGTEXT, VLC_TRUE );
+ add_string( "miface-addr", NULL, NULL, MIFACE_ADDR_TEXT, MIFACE_ADDR_LONGTEXT, VLC_TRUE );
set_subcategory( SUBCAT_SOUT_PACKETIZER );
add_module( "packetizer","packetizer", NULL, NULL,
/*****************************************************************************
* udp.c:
*****************************************************************************
- * Copyright (C) 2004-2005 the VideoLAN team
+ * Copyright (C) 2004-2006 the VideoLAN team
* $Id$
*
* Authors: Laurent Aimar <fenrir@videolan.org>
#include <errno.h>
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
#include "network.h"
# define IP_ADD_MEMBERSHIP 5
# endif
# define EAFNOSUPPORT WSAEAFNOSUPPORT
+# define if_nametoindex( str ) atoi( str )
+#else
+# include <unistd.h>
+# include <net/if.h>
#endif
#ifndef SOL_IP
}
-static int net_SetMcastSource( vlc_object_t *p_this,
- int fd, int family, const char *str )
+static int net_SetMcastIface( vlc_object_t *p_this,
+ int fd, int family, const char *str )
{
-#ifndef SYS_BEOS
switch( family )
{
+#ifndef SYS_BEOS
case AF_INET:
{
struct in_addr addr;
if( inet_pton( AF_INET, str, &addr) <= 0 )
{
- msg_Err( p_this, "Invalid multicast interface %s",
- str );
+ msg_Err( p_this, "Invalid multicast interface %s", str );
return VLC_EGENERIC;
}
- if( setsockopt( fd, IPPROTO_IP, IP_MULTICAST_IF, &addr,
+ if( setsockopt( fd, SOL_IP, IP_MULTICAST_IF, &addr,
sizeof( addr ) ) < 0 )
{
- msg_Dbg( p_this, "Cannot set multicast interface (%s)",
+ msg_Err( p_this, "Cannot use %s as multicast interface: %s",
strerror(errno) );
return VLC_EGENERIC;
}
break;
}
+#endif /* SYS_BEOS */
#ifdef IPV6_MULTICAST_IF
-/* FIXME: TODO */
+ case AF_INET6:
+ {
+ int scope = if_nametoindex( str );
+
+ if( scope == 0 )
+ {
+ msg_Err( p_this, "Invalid multicast interface %s", str );
+ return VLC_EGENERIC;
+ }
+
+ if( setsockopt( fd, SOL_IPV6, IPV6_MULTICAST_IF,
+ &scope, sizeof( scope ) ) < 0 )
+ {
+ msg_Err( p_this, "Cannot use %s as multicast interface: %s",
+ str, strerror( errno ) );
+ return VLC_EGENERIC;
+ }
+ break;
+ }
#endif
+
default:
msg_Warn( p_this, "%s", strerror( EAFNOSUPPORT ) );
return VLC_EGENERIC;
}
-#endif
return VLC_SUCCESS;
}
for( ptr = res; ptr != NULL; ptr = ptr->ai_next )
{
int fd;
- char *psz_mif_addr;
+ char *psz_mif;
fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol );
if( i_hlim > 0 )
net_SetMcastHopLimit( p_this, fd, ptr->ai_family, i_hlim );
- psz_mif_addr = config_GetPsz( p_this, "miface-addr" );
- if( psz_mif_addr != NULL )
+ psz_mif = config_GetPsz( p_this, (ptr->ai_family != AF_INET)
+ ? "miface" : "miface-addr" );
+ if( psz_mif != NULL )
{
- net_SetMcastSource( p_this, fd, ptr->ai_family, psz_mif_addr );
- free( psz_mif_addr );
+ net_SetMcastIface( p_this, fd, ptr->ai_family, psz_mif );
+ free( psz_mif );
}
if( connect( fd, ptr->ai_addr, ptr->ai_addrlen ) == 0 )