2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / net / natNetworkInterfaceWin32.cc
blobd4c2b173f8931177a72ee5f919e4062d3d40d7d8
1 /* Copyright (C) 2003 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
7 details. */
9 #include <config.h>
10 #include <platform.h>
12 #undef STRICT
14 #include <java/net/NetworkInterface.h>
15 #include <java/net/Inet4Address.h>
16 #include <java/net/SocketException.h>
17 #include <java/util/Vector.h>
19 /* As of this writing, NetworkInterface.java has
20 getName() == getDisplayName() and only one IP address
21 per interface. If this changes, we'll need to use
22 iphlpapi (not supported on Win95) to retrieve richer
23 adapter information via GetAdaptersInfo(). In this
24 module, we provide the necessary hooks to detect the
25 presence of iphlpapi and use it if necessary, but
26 comment things out for now to avoid compiler warnings. */
28 enum {MAX_INTERFACES = 50};
30 typedef int
31 (*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
32 java::net::InetAddress** ppAddress);
34 static int
35 winsock2GetRealNetworkInterfaces (jstring* pjstrName,
36 java::net::InetAddress** ppAddress)
38 // FIXME: Add IPv6 support.
40 INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
42 // Open a (random) socket to have a file descriptor for the WSAIoctl call.
43 SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
44 if (skt == INVALID_SOCKET)
45 _Jv_ThrowSocketException ();
47 DWORD dwOutBufSize;
48 int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
49 NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
50 &dwOutBufSize, NULL, NULL);
52 if (nRetCode == SOCKET_ERROR)
54 DWORD dwLastErrorCode = WSAGetLastError ();
55 ::closesocket (skt);
56 _Jv_ThrowSocketException (dwLastErrorCode);
59 // Get addresses of all interfaces.
60 int nNbInterfaces = dwOutBufSize / sizeof(INTERFACE_INFO);
61 int nCurETHInterface = 0;
62 for (int i=0; i < nNbInterfaces; ++i)
64 int len = 4;
65 jbyteArray baddr = JvNewByteArray (len);
66 SOCKADDR_IN* pAddr = (SOCKADDR_IN*) &arInterfaceInfo[i].iiAddress;
67 memcpy (elements (baddr), &(pAddr->sin_addr), len);
69 // Concoct a name for this interface. Since we don't
70 // have access to the real name under Winsock 2, we use
71 // "lo" for the loopback interface and ethX for the
72 // real ones.
73 TCHAR szName[30];
74 u_long lFlags = arInterfaceInfo[i].iiFlags;
76 if (lFlags & IFF_LOOPBACK)
77 _tcscpy (szName, _T("lo"));
78 else
80 _tcscpy (szName, _T("eth"));
81 wsprintf(szName+3, _T("%d"), nCurETHInterface++);
84 jstring if_name = _Jv_Win32NewString (szName);
85 java::net::Inet4Address* address =
86 new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
87 pjstrName[i] = if_name;
88 ppAddress[i] = address;
91 ::closesocket (skt);
93 return nNbInterfaces;
97 static int
98 iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
99 java::net::InetAddress** ppAddress)
101 return 0;
105 static PfnGetRealNetworkInterfaces
106 determineGetRealNetworkInterfacesFN ()
108 /* FIXME: Try to dynamically load iphlpapi.dll and
109 detect the presence of GetAdaptersInfo() using
110 GetProcAddress(). If successful, return
111 iphlpapiGetRealNetworkInterfaces; if not,
112 return winsock2GetRealNetworkInterfaces */
113 return &winsock2GetRealNetworkInterfaces;
116 ::java::util::Vector*
117 java::net::NetworkInterface::getRealNetworkInterfaces ()
119 static PfnGetRealNetworkInterfaces pfn =
120 determineGetRealNetworkInterfacesFN ();
122 jstring arIFName[MAX_INTERFACES];
123 InetAddress* arpInetAddress[MAX_INTERFACES];
124 ::java::util::Vector* ht = new ::java::util::Vector ();
126 int nNbInterfaces = (*pfn) (arIFName, arpInetAddress);
127 for (int i=0; i < nNbInterfaces; ++i)
129 ht->add (new java::net::NetworkInterface (arIFName[i],
130 arpInetAddress[i]));
133 return ht;