natVMNetworkInterfaceWin32.cc 4.2 KB

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