]> git.sesse.net Git - vlc/blobdiff - src/misc/netutils.c
* include/common.h and input_ext-plugins.h, src/misc/modules_plugin.h : export...
[vlc] / src / misc / netutils.c
index 1c4ae12a925bd2cd1ef234967eb08e64a2d574dd..08d2b6a0a2f6d4e3a9f7b6e95da882c4817f1635 100644 (file)
@@ -2,7 +2,7 @@
  * netutils.c: various network functions
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: netutils.c,v 1.52 2001/11/28 15:08:06 massiot Exp $
+ * $Id: netutils.c,v 1.62 2002/04/23 14:16:21 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Benoit Steiner <benny@via.ecp.fr>
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include "defs.h"
-
 #include <stdlib.h>                             /* free(), realloc(), atoi() */
 #include <errno.h>                                                /* errno() */
 #include <string.h>                                              /* memset() */
 
-#ifdef STRNCASECMP_IN_STRINGS_H
-#   include <strings.h>
-#endif
+#include <videolan/vlc.h>
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>                                      /* gethostname() */
@@ -51,7 +47,7 @@
 
 #ifdef WIN32
 #   include <winsock2.h>
-#elif !defined( SYS_BEOS ) && !defined( SYS_NTO )
+#else
 #   include <netdb.h>                                         /* hostent ... */
 #   include <sys/socket.h>                           /* BSD: struct sockaddr */
 #   include <netinet/in.h>                            /* BSD: struct in_addr */
@@ -67,6 +63,7 @@
 #if defined( WIN32 )                    /* tools to get the MAC adress from  */
 #include <windows.h>                    /* the interface under Windows       */
 #include <stdio.h>
+#include <nb30.h>
 #endif
 
 #ifdef HAVE_NET_IF_H
 #include <sys/sockio.h>
 #endif
 
-#include "config.h"
-#include "common.h"
-#include "mtime.h"
-#include "intf_msg.h"
-#include "threads.h"
-#include "main.h"
+#include "netutils.h"
 
 #include "intf_playlist.h"
-
-#include "netutils.h"
+#include "network.h"
 
 /*****************************************************************************
  * input_channel_t: channel library data
@@ -110,53 +101,6 @@ static int GetMacAddress   ( int i_fd, char *psz_mac );
 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 defined( SYS_BEOS )
-    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
  *****************************************************************************
@@ -166,7 +110,10 @@ int network_BuildAddr( struct sockaddr_in * p_socket,
  *****************************************************************************/
 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 ) );
@@ -182,12 +129,6 @@ int network_ChannelCreate( void )
 
     intf_WarnMsg( 2, "network: channels initialized" );
     return( 0 );
-
-#else
-    intf_ErrMsg( "network error : channels not supported on this platform" );
-    return( 1 );
-
-#endif
 }
 
 /*****************************************************************************
@@ -203,22 +144,20 @@ int network_ChannelCreate( void )
  *****************************************************************************/
 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;
 
-    if( !main_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR,
-                              INPUT_NETWORK_CHANNEL_DEFAULT  ) )
+    if( !config_GetIntVariable( "network-channel" ) )
     {
         intf_ErrMsg( "network: channels disabled, to enable them, use the"
                      "--channels option" );
@@ -230,58 +169,50 @@ int network_ChannelJoin( int i_channel )
     {
         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( "ipv4" ) )
     {
-        intf_ErrMsg( "network error: unable to create vlcs socket (%s)",
-                     strerror( errno ) );
-        return -1;
+        psz_network = "ipv4";
+    }
+    if( config_GetIntVariable( "ipv6" ) )
+    {
+        psz_network = "ipv6";
     }
 
-    i_dummy = 1;
-    if( setsockopt( i_fd, SOL_SOCKET, SO_REUSEADDR,
-                    (void *) &i_dummy, sizeof( i_dummy ) ) == -1 )
+    /* Getting information about the channel server */
+    if( !(psz_vlcs = config_GetPszVariable( "channel-server" )) )
     {
-        intf_ErrMsg( "network error: can't SO_REUSEADDR vlcs socket (%s)",
-                     strerror(errno));
-        close( i_fd );
+        intf_ErrMsg( "network: configuration variable channel_server empty" );
         return -1;
     }
 
-    /* Getting information about the channel server */
-    psz_vlcs = main_GetPszVariable( INPUT_CHANNEL_SERVER_VAR,
-                                    INPUT_CHANNEL_SERVER_DEFAULT );
-    i_port = main_GetIntVariable( INPUT_CHANNEL_PORT_VAR,
-                                  INPUT_CHANNEL_PORT_DEFAULT );
-
-    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
+    i_port = config_GetIntVariable( "channel-port" );
+
+    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 = "";
+    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 ) )
@@ -299,8 +230,7 @@ int network_ChannelJoin( int i_channel )
                        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 );
 
@@ -329,10 +259,8 @@ int network_ChannelJoin( int 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 ) )
     {
@@ -368,12 +296,6 @@ int network_ChannelJoin( int i_channel )
     close( i_fd );
 
     return 0;
-
-#else
-    intf_ErrMsg( "network error: channels not supported on this platform" );
-    return -1; 
-
-#endif
 }
 
 /* Following functions are local */
@@ -386,13 +308,19 @@ static int GetMacAddress( int i_fd, char *psz_mac )
 #if defined( SYS_LINUX )
     struct ifreq interface;
     int i_ret;
+    char *psz_interface;
 
     /*
      * Looking for information about the eth0 interface
      */
     interface.ifr_addr.sa_family = AF_INET;
-    strcpy( interface.ifr_name, 
-            main_GetPszVariable( INPUT_IFACE_VAR, INPUT_IFACE_DEFAULT ) );
+    if( !(psz_interface = config_GetPszVariable( "iface" )) )
+    {
+        intf_ErrMsg( "network error: configuration variable iface empty" );
+        return -1;
+    }
+    strcpy( interface.ifr_name, psz_interface );
+    free( psz_interface );
 
     i_ret = ioctl( i_fd, SIOCGIFHWADDR, &interface );
 
@@ -439,7 +367,8 @@ static int GetMacAddress( int i_fd, char *psz_mac )
     return( i_ret );
 
 #else
-    return( -1);
+    strcpy( psz_mac, "00:00:00:00:00:00" );
+    return( 0 );
 
 #endif
 }