OSDN Git Service

2010-05-19 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / libjava / java / net / natVMNetworkInterfaceWin32.cc
1 /* Copyright (C) 2003, 2005  Free Software Foundation
2
3    This file is part of libgcj.
4
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8
9 #include <config.h>
10 #include <platform.h>
11
12 #undef STRICT
13
14 #include <java/net/NetworkInterface.h>
15 #include <java/net/InetAddress.h>
16 #include <java/net/SocketException.h>
17 #include <java/net/VMNetworkInterface.h>
18 #include <java/util/Vector.h>
19
20 /* As of this writing, NetworkInterface.java has
21    getName() == getDisplayName() and only one IP address
22    per interface. If this changes, we'll need to use
23    iphlpapi (not supported on Win95) to retrieve richer
24    adapter information via GetAdaptersInfo(). In this
25    module, we provide the necessary hooks to detect the
26    presence of iphlpapi and use it if necessary, but
27    comment things out for now to avoid compiler warnings. */
28
29 enum {MAX_INTERFACES = 50};
30
31 typedef int
32 (*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
33   java::net::InetAddress** ppAddress);
34
35 static int
36 winsock2GetRealNetworkInterfaces (jstring* pjstrName,
37   java::net::InetAddress** ppAddress)
38 {
39   // FIXME: Add IPv6 support.
40   
41   INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
42
43   // Open a (random) socket to have a file descriptor for the WSAIoctl call.
44   SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
45   if (skt == INVALID_SOCKET) 
46     _Jv_ThrowSocketException ();
47     
48   DWORD dwOutBufSize;
49   int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
50     NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
51     &dwOutBufSize, NULL, NULL);
52     
53   if (nRetCode == SOCKET_ERROR)
54   {
55     DWORD dwLastErrorCode = WSAGetLastError ();
56     ::closesocket (skt);
57     _Jv_ThrowSocketException (dwLastErrorCode);
58   }
59   
60   // Get addresses of all interfaces.
61   int nNbInterfaces = dwOutBufSize / sizeof(INTERFACE_INFO);
62   int nCurETHInterface = 0;
63   for (int i=0; i < nNbInterfaces; ++i) 
64     {
65       int len = 4;
66       jbyteArray baddr = JvNewByteArray (len);
67       SOCKADDR_IN* pAddr = (SOCKADDR_IN*) &arInterfaceInfo[i].iiAddress;
68       memcpy (elements (baddr), &(pAddr->sin_addr), len);
69
70       // Concoct a name for this interface. Since we don't
71       // have access to the real name under Winsock 2, we use
72       // "lo" for the loopback interface and ethX for the
73       // real ones.
74       TCHAR szName[30];
75       u_long lFlags = arInterfaceInfo[i].iiFlags;
76
77       if (lFlags & IFF_LOOPBACK)
78         _tcscpy (szName, _T("lo"));
79       else
80         {
81           _tcscpy (szName, _T("eth"));
82           wsprintf(szName+3, _T("%d"), nCurETHInterface++);
83         }
84
85       jstring if_name = _Jv_Win32NewString (szName);
86       java::net::InetAddress* address =
87         java::net::InetAddress::getByAddress (baddr);
88       pjstrName[i] = if_name;
89       ppAddress[i] = address;
90     }
91
92   ::closesocket (skt);
93   
94   return nNbInterfaces;
95 }
96
97 /*
98 static int
99 iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
100   java::net::InetAddress** ppAddress)
101 {
102   return 0;
103 }
104 */
105
106 static PfnGetRealNetworkInterfaces
107 determineGetRealNetworkInterfacesFN ()
108 {
109   /* FIXME: Try to dynamically load iphlpapi.dll and
110      detect the presence of GetAdaptersInfo() using
111      GetProcAddress(). If successful, return
112      iphlpapiGetRealNetworkInterfaces; if not,
113      return winsock2GetRealNetworkInterfaces */
114   return &winsock2GetRealNetworkInterfaces;
115 }
116
117 ::java::util::Vector*
118 java::net::VMNetworkInterface::getInterfaces ()
119 {
120   // This next declaration used to be a static local,
121   // but this introduced a dependency on libsupc++ due
122   // to _cxa_guard_acquire and _cxa_guard_release.
123   // When Win95 is gone and we eventually get rid of
124   // winsock2GetRealNetworkInterfaces, we can rework
125   // all of this. Alternatively, we could move this all
126   // to win32.cc and initialize this at startup time,
127   // but that seems more trouble than it's worth at
128   // the moment.
129   PfnGetRealNetworkInterfaces pfn =
130     determineGetRealNetworkInterfacesFN ();
131     
132   jstring arIFName[MAX_INTERFACES];
133   InetAddress* arpInetAddress[MAX_INTERFACES];
134   ::java::util::Vector* ht = new ::java::util::Vector ();
135   
136   int nNbInterfaces = (*pfn) (arIFName, arpInetAddress);
137   for (int i=0; i < nNbInterfaces; ++i) 
138     {
139       ht->add (new java::net::NetworkInterface (arIFName[i],
140         arpInetAddress[i]));
141     }
142     
143   return ht;
144 }