Merge from mainline
[official-gcc.git] / libjava / java / net / natVMNetworkInterfacePosix.cc
blobb840907ccab3c8d589a98050294365a2fb3a03c8
1 /* Copyright (C) 2003, 2005 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 #ifdef HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15 #include <string.h>
16 #include <errno.h>
17 #include <stdlib.h>
19 #include <sys/param.h>
20 #include <sys/types.h>
21 #ifdef HAVE_NETINET_IN_H
22 #include <netinet/in.h>
23 #endif
24 #ifdef HAVE_ARPA_INET_H
25 #include <arpa/inet.h>
26 #endif
27 #ifdef HAVE_NETDB_H
28 #include <netdb.h>
29 #endif
30 #ifdef HAVE_SYS_IOCTL_H
31 #define BSD_COMP /* Get FIONREAD on Solaris2. */
32 #include <sys/ioctl.h>
33 #endif
34 #ifdef HAVE_NET_IF_H
35 #include <net/if.h>
36 #endif
38 #include <gcj/cni.h>
39 #include <jvm.h>
40 #include <java/net/Inet4Address.h>
41 #include <java/net/NetworkInterface.h>
42 #include <java/net/SocketException.h>
43 #include <java/net/VMNetworkInterface.h>
44 #include <java/util/Vector.h>
46 ::java::util::Vector*
47 java::net::VMNetworkInterface::getInterfaces ()
49 int fd;
50 int num_interfaces = 0;
51 struct ifconf if_data;
52 struct ifreq* if_record;
53 ::java::util::Vector* ht = new ::java::util::Vector ();
55 if_data.ifc_len = 0;
56 if_data.ifc_buf = NULL;
58 // Open a (random) socket to have a file descriptor for the ioctl calls.
59 fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
61 if (fd < 0)
62 throw new ::java::net::SocketException;
64 // Get all interfaces. If not enough buffers are available try it
65 // with a bigger buffer size.
68 num_interfaces += 16;
70 if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
71 if_data.ifc_buf =
72 (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
74 // Try to get all local interfaces.
75 if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
76 throw new java::net::SocketException;
78 while (if_data.ifc_len >= (int) (sizeof (struct ifreq) * num_interfaces));
80 // Get addresses of all interfaces.
81 if_record = if_data.ifc_req;
83 for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq))
85 struct ifreq ifr;
87 memset (&ifr, 0, sizeof (ifr));
88 strcpy (ifr.ifr_name, if_record->ifr_name);
90 // Try to get the IPv4-address of the local interface
91 if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
92 throw new java::net::SocketException;
94 int len = 4;
95 struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
97 jbyteArray baddr = JvNewByteArray (len);
98 memcpy (elements (baddr), &(sa.sin_addr), len);
99 jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
100 Inet4Address* address =
101 new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
102 ht->add (new NetworkInterface (if_name, address));
103 if_record++;
106 #ifdef HAVE_INET6
107 // FIXME: read /proc/net/if_inet6 (on Linux 2.4)
108 #endif
110 _Jv_Free (if_data.ifc_buf);
112 if (fd >= 0)
113 _Jv_close (fd);
115 return ht;