| 1 | // natNetworkInterface.cc
|
|---|
| 2 |
|
|---|
| 3 | /* Copyright (C) 2002 Free Software Foundation
|
|---|
| 4 |
|
|---|
| 5 | This file is part of libgcj.
|
|---|
| 6 |
|
|---|
| 7 | This software is copyrighted work licensed under the terms of the
|
|---|
| 8 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|---|
| 9 | details. */
|
|---|
| 10 |
|
|---|
| 11 | #include <config.h>
|
|---|
| 12 | #include <platform.h>
|
|---|
| 13 |
|
|---|
| 14 | #ifdef WIN32
|
|---|
| 15 |
|
|---|
| 16 | #include <windows.h>
|
|---|
| 17 | #include <winsock.h>
|
|---|
| 18 | #undef STRICT
|
|---|
| 19 |
|
|---|
| 20 | #else /* WIN32 */
|
|---|
| 21 |
|
|---|
| 22 | #ifdef HAVE_UNISTD_H
|
|---|
| 23 | #include <unistd.h>
|
|---|
| 24 | #endif
|
|---|
| 25 | #include <string.h>
|
|---|
| 26 | #include <errno.h>
|
|---|
| 27 | #include <stdlib.h>
|
|---|
| 28 |
|
|---|
| 29 | #include <sys/param.h>
|
|---|
| 30 | #include <sys/types.h>
|
|---|
| 31 | #ifdef HAVE_NETINET_IN_H
|
|---|
| 32 | #include <netinet/in.h>
|
|---|
| 33 | #endif
|
|---|
| 34 | #ifdef HAVE_ARPA_INET_H
|
|---|
| 35 | #include <arpa/inet.h>
|
|---|
| 36 | #endif
|
|---|
| 37 | #ifdef HAVE_NETDB_H
|
|---|
| 38 | #include <netdb.h>
|
|---|
| 39 | #endif
|
|---|
| 40 | #ifdef HAVE_SYS_IOCTL_H
|
|---|
| 41 | #define BSD_COMP /* Get FIONREAD on Solaris2. */
|
|---|
| 42 | #include <sys/ioctl.h>
|
|---|
| 43 | #endif
|
|---|
| 44 | #ifdef HAVE_NET_IF_H
|
|---|
| 45 | #include <net/if.h>
|
|---|
| 46 | #endif
|
|---|
| 47 |
|
|---|
| 48 | #endif /* WIN32 */
|
|---|
| 49 |
|
|---|
| 50 | #include <gcj/cni.h>
|
|---|
| 51 | #include <jvm.h>
|
|---|
| 52 | #include <java/net/NetworkInterface.h>
|
|---|
| 53 | #include <java/net/Inet4Address.h>
|
|---|
| 54 | #include <java/net/SocketException.h>
|
|---|
| 55 | #include <java/util/Vector.h>
|
|---|
| 56 |
|
|---|
| 57 | #ifdef DISABLE_JAVA_NET
|
|---|
| 58 |
|
|---|
| 59 | ::java::util::Vector*
|
|---|
| 60 | java::net::NetworkInterface::getRealNetworkInterfaces ()
|
|---|
| 61 | {
|
|---|
| 62 | ::java::util::Vector* ht = new ::java::util::Vector();
|
|---|
| 63 | return ht;
|
|---|
| 64 | }
|
|---|
| 65 |
|
|---|
| 66 | #else /* DISABLE_JAVA_NET */
|
|---|
| 67 |
|
|---|
| 68 | ::java::util::Vector*
|
|---|
| 69 | java::net::NetworkInterface::getRealNetworkInterfaces ()
|
|---|
| 70 | {
|
|---|
| 71 | #ifdef WIN32
|
|---|
| 72 | throw new ::java::net::SocketException;
|
|---|
| 73 | #else
|
|---|
| 74 | int fd;
|
|---|
| 75 | int num_interfaces = 0;
|
|---|
| 76 | struct ifconf if_data;
|
|---|
| 77 | struct ifreq* if_record;
|
|---|
| 78 | ::java::util::Vector* ht = new ::java::util::Vector ();
|
|---|
| 79 |
|
|---|
| 80 | if_data.ifc_len = 0;
|
|---|
| 81 | if_data.ifc_buf = NULL;
|
|---|
| 82 |
|
|---|
| 83 | // Open a (random) socket to have a file descriptor for the ioctl calls.
|
|---|
| 84 | fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
|
|---|
| 85 |
|
|---|
| 86 | if (fd < 0)
|
|---|
| 87 | throw new ::java::net::SocketException;
|
|---|
| 88 |
|
|---|
| 89 | // Get all interfaces. If not enough buffers are available try it
|
|---|
| 90 | // with a bigger buffer size.
|
|---|
| 91 | do
|
|---|
| 92 | {
|
|---|
| 93 | num_interfaces += 16;
|
|---|
| 94 |
|
|---|
| 95 | if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
|
|---|
| 96 | if_data.ifc_buf =
|
|---|
| 97 | (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
|
|---|
| 98 |
|
|---|
| 99 | // Try to get all local interfaces.
|
|---|
| 100 | if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
|
|---|
| 101 | throw new java::net::SocketException;
|
|---|
| 102 | }
|
|---|
| 103 | while (if_data.ifc_len >= (sizeof (struct ifreq) * num_interfaces));
|
|---|
| 104 |
|
|---|
| 105 | // Get addresses of all interfaces.
|
|---|
| 106 | if_record = if_data.ifc_req;
|
|---|
| 107 |
|
|---|
| 108 | for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq))
|
|---|
| 109 | {
|
|---|
| 110 | struct ifreq ifr;
|
|---|
| 111 |
|
|---|
| 112 | memset (&ifr, 0, sizeof (ifr));
|
|---|
| 113 | strcpy (ifr.ifr_name, if_record->ifr_name);
|
|---|
| 114 |
|
|---|
| 115 | // Try to get the IPv4-address of the local interface
|
|---|
| 116 | if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
|
|---|
| 117 | throw new java::net::SocketException;
|
|---|
| 118 |
|
|---|
| 119 | int len = 4;
|
|---|
| 120 | struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
|
|---|
| 121 |
|
|---|
| 122 | jbyteArray baddr = JvNewByteArray (len);
|
|---|
| 123 | memcpy (elements (baddr), &(sa.sin_addr), len);
|
|---|
| 124 | jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
|
|---|
| 125 | Inet4Address* address =
|
|---|
| 126 | new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
|
|---|
| 127 | ht->add (new NetworkInterface (if_name, address));
|
|---|
| 128 | if_record++;
|
|---|
| 129 | }
|
|---|
| 130 |
|
|---|
| 131 | #ifdef HAVE_INET6
|
|---|
| 132 | // FIXME: read /proc/net/if_inet6 (on Linux 2.4)
|
|---|
| 133 | #endif
|
|---|
| 134 |
|
|---|
| 135 | _Jv_Free (if_data.ifc_buf);
|
|---|
| 136 |
|
|---|
| 137 | if (fd >= 0)
|
|---|
| 138 | _Jv_close (fd);
|
|---|
| 139 |
|
|---|
| 140 | return ht;
|
|---|
| 141 | #endif /* WIN32 */
|
|---|
| 142 | }
|
|---|
| 143 |
|
|---|
| 144 | #endif // DISABLE_JAVA_NET //
|
|---|