* netutils.c: various network functions
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: netutils.c,v 1.58 2002/02/27 04:49:55 sam Exp $
+ * $Id: netutils.c,v 1.59 2002/03/04 23:56:38 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Benoit Steiner <benny@via.ecp.fr>
#include <videolan/vlc.h>
-#ifdef STRNCASECMP_IN_STRINGS_H
-# include <strings.h>
-#endif
-
#ifdef HAVE_UNISTD_H
# include <unistd.h> /* gethostname() */
#elif defined( _MSC_VER ) && defined( _WIN32 )
#include "netutils.h"
#include "intf_playlist.h"
+#include "network.h"
/*****************************************************************************
* input_channel_t: channel library data
static int GetAdapterInfo ( int i_adapter, char *psz_string );
#endif
-/*****************************************************************************
- * network_BuildAddr : fill a sockaddr_in structure
- *****************************************************************************/
-int network_BuildAddr( struct sockaddr_in * p_socket,
- char * psz_address, int i_port )
-{
-#if 0
- intf_ErrMsg( "error: networking is not yet supported under BeOS" );
- return( 1 );
-
-#else
- /* Reset struct */
- memset( p_socket, 0, sizeof( struct sockaddr_in ) );
- p_socket->sin_family = AF_INET; /* family */
- p_socket->sin_port = htons( i_port );
- if( psz_address == NULL )
- {
- p_socket->sin_addr.s_addr = INADDR_ANY;
- }
- else
- {
- struct hostent * p_hostent;
-
- /* Try to convert address directly from in_addr - this will work if
- * psz_broadcast is dotted decimal. */
-#ifdef HAVE_ARPA_INET_H
- if( !inet_aton( psz_address, &p_socket->sin_addr) )
-#else
- if( (p_socket->sin_addr.s_addr = inet_addr( psz_address )) == -1 )
-#endif
- {
- /* We have a fqdn, try to find its address */
- if ( (p_hostent = gethostbyname( psz_address )) == NULL )
- {
- intf_ErrMsg( "BuildLocalAddr: unknown host %s", psz_address );
- return( -1 );
- }
-
- /* Copy the first address of the host in the socket address */
- memcpy( &p_socket->sin_addr, p_hostent->h_addr_list[0],
- p_hostent->h_length );
- }
- }
- return( 0 );
-#endif
-}
-
/*****************************************************************************
* network_ChannelCreate: initialize global channel method data
*****************************************************************************
*****************************************************************************/
int network_ChannelCreate( void )
{
-#if defined( SYS_LINUX ) || defined( WIN32 )
+#if !defined( SYS_LINUX ) && !defined( WIN32 )
+ intf_ErrMsg( "channel warning: VLAN-based channels are not supported"
+ " under this architecture" );
+#endif
/* Allocate structure */
p_main->p_channel = malloc( sizeof( input_channel_t ) );
intf_WarnMsg( 2, "network: channels initialized" );
return( 0 );
-
-#else
- intf_ErrMsg( "network error : channels not supported on this platform" );
- return( 1 );
-
-#endif
}
/*****************************************************************************
*****************************************************************************/
int network_ChannelJoin( int i_channel )
{
-#if defined( SYS_LINUX ) || defined( WIN32 )
-
#define VLCS_VERSION 13
#define MESSAGE_LENGTH 256
+ struct module_s * p_network;
+ char * psz_network = NULL;
+ network_socket_t socket_desc;
char psz_mess[ MESSAGE_LENGTH ];
char psz_mac[ 40 ];
- int i_fd, i_dummy, i_port;
+ int i_fd, i_port;
char *psz_vlcs;
- struct sockaddr_in sa_server;
- struct sockaddr_in sa_client;
struct timeval delay;
fd_set fds;
{
intf_WarnMsg( 2, "network: waiting before changing channel" );
/* XXX Isn't this completely brain-damaged ??? -- Sam */
+ /* Yes it is. I don't think this is still justified with the new
+ * vlanserver --Meuuh */
mwait( p_main->p_channel->last_change + INPUT_CHANNEL_CHANGE_DELAY );
}
- /* Initializing the socket */
- i_fd = socket( AF_INET, SOCK_DGRAM, 0 );
- if( i_fd < 0 )
+ if( config_GetIntVariable( INPUT_IPV4_VAR ) )
{
- intf_ErrMsg( "network error: unable to create vlcs socket (%s)",
- strerror( errno ) );
- return -1;
+ psz_network = "ipv4";
}
-
- i_dummy = 1;
- if( setsockopt( i_fd, SOL_SOCKET, SO_REUSEADDR,
- (void *) &i_dummy, sizeof( i_dummy ) ) == -1 )
+ if( config_GetIntVariable( INPUT_IPV6_VAR ) )
{
- intf_ErrMsg( "network error: can't SO_REUSEADDR vlcs socket (%s)",
- strerror(errno));
- close( i_fd );
- return -1;
+ psz_network = "ipv6";
}
/* Getting information about the channel server */
i_port = config_GetIntVariable( INPUT_CHANNEL_PORT_VAR );
- intf_WarnMsg( 5, "network: socket %i, vlcs '%s', port %d",
- i_fd, psz_vlcs, i_port );
-
- memset( &sa_client, 0x00, sizeof(struct sockaddr_in) );
- memset( &sa_server, 0x00, sizeof(struct sockaddr_in) );
- sa_client.sin_family = AF_INET;
- sa_server.sin_family = AF_INET;
- sa_client.sin_port = htons( 4312 );
- sa_server.sin_port = htons( i_port );
- sa_client.sin_addr.s_addr = INADDR_ANY;
-#ifdef HAVE_ARPA_INET_H
- inet_aton( psz_vlcs, &sa_server.sin_addr );
-#else
- sa_server.sin_addr.s_addr = inet_addr( psz_vlcs );
-#endif
- free( psz_vlcs );
+ intf_WarnMsg( 5, "channel: connecting to %s:%d",
+ psz_vlcs, i_port );
- /* Bind the socket */
- if( bind( i_fd, (struct sockaddr*)(&sa_client), sizeof(sa_client) ) )
+ /* Prepare the network_socket_t structure */
+ socket_desc.i_type = NETWORK_UDP;
+ socket_desc.psz_bind_addr = NULL;
+ socket_desc.i_bind_port = 4321;
+ socket_desc.psz_server_addr = psz_vlcs;
+ socket_desc.i_server_port = i_port;
+
+ /* Find an appropriate network module */
+ p_network = module_Need( MODULE_CAPABILITY_NETWORK, psz_network,
+ &socket_desc );
+ if( p_network == NULL )
{
- intf_ErrMsg( "network: unable to bind vlcs socket (%s)",
- strerror( errno ) );
- close( i_fd );
- return -1;
+ return( -1 );
}
+ module_Unneed( p_network );
+
+ free( psz_vlcs ); /* Do we really need this ? -- Meuuh */
+ i_fd = socket_desc.i_handle;
/* Look for the interface MAC address */
if( GetMacAddress( i_fd, psz_mac ) )
psz_mac );
/* Send the message */
- sendto( i_fd, psz_mess, MESSAGE_LENGTH, 0,
- (struct sockaddr *)(&sa_server), sizeof(struct sockaddr) );
+ send( i_fd, psz_mess, MESSAGE_LENGTH, 0 );
intf_WarnMsg( 2, "network: attempting to join channel %d", i_channel );
break;
}
- i_dummy = sizeof( struct sockaddr );
- recvfrom( i_fd, psz_mess, MESSAGE_LENGTH, 0,
- (struct sockaddr *)(&sa_client), &i_dummy);
- psz_mess[ MESSAGE_LENGTH - 1 ] = 0;
+ recv( i_fd, psz_mess, MESSAGE_LENGTH, 0 );
+ psz_mess[ MESSAGE_LENGTH - 1 ] = '\0';
if( !strncasecmp( psz_mess, "E: ", 3 ) )
{
close( i_fd );
return 0;
-
-#else
- intf_ErrMsg( "network error: channels not supported on this platform" );
- return -1;
-
-#endif
}
/* Following functions are local */
return( i_ret );
#else
- return( -1);
+ strcpy( psz_mac, "00:00:00:00:00:00" );
+ return( 0 );
#endif
}