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;
 | |
| }
 |