mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			145 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
/* Copyright (C) 2003, 2005  Free Software Foundation
 | 
						|
 | 
						|
   This file is part of libgcj.
 | 
						|
 | 
						|
This software is copyrighted work licensed under the terms of the
 | 
						|
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | 
						|
details.  */
 | 
						|
 | 
						|
#include <config.h>
 | 
						|
#include <platform.h>
 | 
						|
 | 
						|
#undef STRICT
 | 
						|
 | 
						|
#include <java/net/NetworkInterface.h>
 | 
						|
#include <java/net/InetAddress.h>
 | 
						|
#include <java/net/SocketException.h>
 | 
						|
#include <java/net/VMNetworkInterface.h>
 | 
						|
#include <java/util/Vector.h>
 | 
						|
 | 
						|
/* As of this writing, NetworkInterface.java has
 | 
						|
   getName() == getDisplayName() and only one IP address
 | 
						|
   per interface. If this changes, we'll need to use
 | 
						|
   iphlpapi (not supported on Win95) to retrieve richer
 | 
						|
   adapter information via GetAdaptersInfo(). In this
 | 
						|
   module, we provide the necessary hooks to detect the
 | 
						|
   presence of iphlpapi and use it if necessary, but
 | 
						|
   comment things out for now to avoid compiler warnings. */
 | 
						|
 | 
						|
enum {MAX_INTERFACES = 50};
 | 
						|
 | 
						|
typedef int
 | 
						|
(*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
 | 
						|
  java::net::InetAddress** ppAddress);
 | 
						|
 | 
						|
static int
 | 
						|
winsock2GetRealNetworkInterfaces (jstring* pjstrName,
 | 
						|
  java::net::InetAddress** ppAddress)
 | 
						|
{
 | 
						|
  // FIXME: Add IPv6 support.
 | 
						|
  
 | 
						|
  INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
 | 
						|
 | 
						|
  // Open a (random) socket to have a file descriptor for the WSAIoctl call.
 | 
						|
  SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
 | 
						|
  if (skt == INVALID_SOCKET) 
 | 
						|
    _Jv_ThrowSocketException ();
 | 
						|
    
 | 
						|
  DWORD dwOutBufSize;
 | 
						|
  int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
 | 
						|
    NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
 | 
						|
    &dwOutBufSize, NULL, NULL);
 | 
						|
    
 | 
						|
  if (nRetCode == SOCKET_ERROR)
 | 
						|
  {
 | 
						|
    DWORD dwLastErrorCode = WSAGetLastError ();
 | 
						|
    ::closesocket (skt);
 | 
						|
    _Jv_ThrowSocketException (dwLastErrorCode);
 | 
						|
  }
 | 
						|
  
 | 
						|
  // Get addresses of all interfaces.
 | 
						|
  int nNbInterfaces = dwOutBufSize / sizeof(INTERFACE_INFO);
 | 
						|
  int nCurETHInterface = 0;
 | 
						|
  for (int i=0; i < nNbInterfaces; ++i) 
 | 
						|
    {
 | 
						|
      int len = 4;
 | 
						|
      jbyteArray baddr = JvNewByteArray (len);
 | 
						|
      SOCKADDR_IN* pAddr = (SOCKADDR_IN*) &arInterfaceInfo[i].iiAddress;
 | 
						|
      memcpy (elements (baddr), &(pAddr->sin_addr), len);
 | 
						|
 | 
						|
      // Concoct a name for this interface. Since we don't
 | 
						|
      // have access to the real name under Winsock 2, we use
 | 
						|
      // "lo" for the loopback interface and ethX for the
 | 
						|
      // real ones.
 | 
						|
      TCHAR szName[30];
 | 
						|
      u_long lFlags = arInterfaceInfo[i].iiFlags;
 | 
						|
 | 
						|
      if (lFlags & IFF_LOOPBACK)
 | 
						|
        _tcscpy (szName, _T("lo"));
 | 
						|
      else
 | 
						|
        {
 | 
						|
          _tcscpy (szName, _T("eth"));
 | 
						|
          wsprintf(szName+3, _T("%d"), nCurETHInterface++);
 | 
						|
        }
 | 
						|
 | 
						|
      jstring if_name = _Jv_Win32NewString (szName);
 | 
						|
      java::net::InetAddress* address =
 | 
						|
        java::net::InetAddress::getByAddress (baddr);
 | 
						|
      pjstrName[i] = if_name;
 | 
						|
      ppAddress[i] = address;
 | 
						|
    }
 | 
						|
 | 
						|
  ::closesocket (skt);
 | 
						|
  
 | 
						|
  return nNbInterfaces;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
static int
 | 
						|
iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
 | 
						|
  java::net::InetAddress** ppAddress)
 | 
						|
{
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
*/
 | 
						|
 | 
						|
static PfnGetRealNetworkInterfaces
 | 
						|
determineGetRealNetworkInterfacesFN ()
 | 
						|
{
 | 
						|
  /* FIXME: Try to dynamically load iphlpapi.dll and
 | 
						|
     detect the presence of GetAdaptersInfo() using
 | 
						|
     GetProcAddress(). If successful, return
 | 
						|
     iphlpapiGetRealNetworkInterfaces; if not,
 | 
						|
     return winsock2GetRealNetworkInterfaces */
 | 
						|
  return &winsock2GetRealNetworkInterfaces;
 | 
						|
}
 | 
						|
 | 
						|
::java::util::Vector*
 | 
						|
java::net::VMNetworkInterface::getInterfaces ()
 | 
						|
{
 | 
						|
  // This next declaration used to be a static local,
 | 
						|
  // but this introduced a dependency on libsupc++ due
 | 
						|
  // to _cxa_guard_acquire and _cxa_guard_release.
 | 
						|
  // When Win95 is gone and we eventually get rid of
 | 
						|
  // winsock2GetRealNetworkInterfaces, we can rework
 | 
						|
  // all of this. Alternatively, we could move this all
 | 
						|
  // to win32.cc and initialize this at startup time,
 | 
						|
  // but that seems more trouble than it's worth at
 | 
						|
  // the moment.
 | 
						|
  PfnGetRealNetworkInterfaces pfn =
 | 
						|
    determineGetRealNetworkInterfacesFN ();
 | 
						|
    
 | 
						|
  jstring arIFName[MAX_INTERFACES];
 | 
						|
  InetAddress* arpInetAddress[MAX_INTERFACES];
 | 
						|
  ::java::util::Vector* ht = new ::java::util::Vector ();
 | 
						|
  
 | 
						|
  int nNbInterfaces = (*pfn) (arIFName, arpInetAddress);
 | 
						|
  for (int i=0; i < nNbInterfaces; ++i) 
 | 
						|
    {
 | 
						|
      ht->add (new java::net::NetworkInterface (arIFName[i],
 | 
						|
        arpInetAddress[i]));
 | 
						|
    }
 | 
						|
    
 | 
						|
  return ht;
 | 
						|
}
 |