1 /* VMInetAddress.c - Native methods for InetAddress class
2 Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 /* do not move; needed here because of some macro definitions */
52 #include "java_net_VMInetAddress.h"
54 /*************************************************************************/
57 * Function to return the local hostname
59 JNIEXPORT jstring JNICALL
60 Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env,
62 __attribute__ ((__unused__)))
68 #ifndef WITHOUT_NETWORK
69 result = cpnet_getHostname (env, hostname, sizeof (hostname));
70 if (result != CPNATIVE_OK)
72 strcpy (hostname, "localhost");
74 #else /* not WITHOUT_NETWORK */
75 strcpy (hostname, "localhost");
76 #endif /* not WITHOUT_NETWORK */
78 retval = (*env)->NewStringUTF (env, hostname);
83 /*************************************************************************/
86 * Returns the value of the special IP address INADDR_ANY
88 JNIEXPORT jarray JNICALL
89 Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
91 __attribute__ ((__unused__)))
97 /* Allocate an array for the IP address */
98 IParray = (*env)->NewByteArray (env, 4);
101 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
102 return (jarray) NULL;
105 /* Copy in the values */
106 octets = (*env)->GetByteArrayElements (env, IParray, 0);
108 #ifndef WITHOUT_NETWORK
109 addr = cpnet_newIPV4Address (env);
110 cpnet_setIPV4Any (addr);
111 cpnet_IPV4AddressToBytes (addr, octets);
112 cpnet_freeAddress (env, addr);
113 #else /* not WITHOUT_NETWORK */
118 #endif /* not WITHOUT_NETWORK */
120 (*env)->ReleaseByteArrayElements (env, IParray, octets, 0);
125 /*************************************************************************/
128 * Function to return the canonical hostname for a given IP address passed
131 JNIEXPORT jstring JNICALL
132 Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
134 __attribute__ ((__unused__)),
137 #ifndef WITHOUT_NETWORK
145 /* Grab the byte[] array with the IP out of the input data */
146 len = (*env)->GetArrayLength (env, arr);
147 if (len != 4 && len != 16)
149 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
150 return (jstring) NULL;
153 octets = (*env)->GetByteArrayElements (env, arr, 0);
156 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
157 return (jstring) NULL;
163 addr = cpnet_newIPV4Address(env);
164 cpnet_bytesToIPV4Address (addr, octets);
167 addr = cpnet_newIPV6Address(env);
168 cpnet_bytesToIPV6Address (addr, octets);
171 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
172 return (jstring) NULL;
176 /* Release some memory */
177 (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
179 /* Resolve the address and return the name */
180 result = cpnet_getHostByAddr (env, addr, hostname, sizeof (hostname));
181 if (result != CPNATIVE_OK)
183 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION,
184 cpnative_getErrorString (result));
185 return (jstring) NULL;
188 retval = (*env)->NewStringUTF (env, hostname);
191 #else /* not WITHOUT_NETWORK */
192 return (jstring) NULL;
193 #endif /* not WITHOUT_NETWORK */
196 /*************************************************************************/
198 JNIEXPORT jobjectArray JNICALL
199 Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
201 __attribute__ ((__unused__)),
204 #ifndef WITHOUT_NETWORK
205 const char *hostname;
206 cpnet_address **addresses;
207 jsize addresses_count;
215 /* Grab the hostname string */
216 hostname = (*env)->GetStringUTFChars (env, host, 0);
219 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
220 return (jobjectArray) NULL;
223 result = cpnet_getHostByName (env, hostname, &addresses, &addresses_count);
224 if (result != CPNATIVE_OK || addresses_count == 0)
226 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, (char *) hostname);
227 return (jobjectArray) NULL;
229 (*env)->ReleaseStringUTFChars (env, host, hostname);
231 arr_class = (*env)->FindClass (env, "[B");
234 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
235 return (jobjectArray) NULL;
238 addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0);
241 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
242 return (jobjectArray) NULL;
245 /* Now loop and copy in each address */
246 for (i = 0; i < addresses_count; i++)
248 if (cpnet_isIPV6Address (addresses[i]))
250 ret_octets = (*env)->NewByteArray (env, 16);
254 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
255 cpnet_freeAddresses (env, addresses, addresses_count);
256 return (jobjectArray) NULL;
259 octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
261 cpnet_IPV6AddressToBytes (addresses[i], octets);
263 (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
265 (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
267 else if (cpnet_isIPV4Address (addresses[i]))
269 ret_octets = (*env)->NewByteArray (env, 4);
273 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
274 cpnet_freeAddresses (env, addresses, addresses_count);
275 return (jobjectArray) NULL;
278 octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
280 cpnet_IPV4AddressToBytes (addresses[i], octets);
282 (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
284 (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
288 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
289 cpnet_freeAddresses (env, addresses, addresses_count);
290 return (jobjectArray) NULL;
294 cpnet_freeAddresses (env, addresses, addresses_count);
297 #else /* not WITHOUT_NETWORK */
298 return (jobjectArray) NULL;
299 #endif /* not WITHOUT_NETWORK */
302 /*************************************************************************/
305 * Return the IP address represented by a literal address.
306 * Will return null if the literal address is not valid.
308 JNIEXPORT jbyteArray JNICALL
309 Java_java_net_VMInetAddress_aton (JNIEnv *env,
311 __attribute__ ((__unused__)),
314 #ifndef WITHOUT_NETWORK
315 const char *hostname;
316 cpnet_address *address;
319 jbyteArray ret_octets;
321 hostname = (*env)->GetStringUTFChars (env, host, 0);
324 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
325 return (jbyteArray) NULL;
328 result = cpnet_aton (env, hostname, &address);
329 if (result != CPNATIVE_OK)
331 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
333 cpnet_freeAddress (env, address);
334 return (jbyteArray) NULL;
337 return (jbyteArray) NULL;
339 if (cpnet_isIPV6Address (address))
341 ret_octets = (jbyteArray) (*env)->NewByteArray (env, 16);
345 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
346 cpnet_freeAddress (env, address);
347 return (jbyteArray) NULL;
350 octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
352 cpnet_IPV6AddressToBytes (address, octets);
354 (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
356 else if (cpnet_isIPV4Address (address))
358 ret_octets = (jbyteArray) (*env)->NewByteArray (env, 4);
362 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
363 cpnet_freeAddress (env, address);
364 return (jbyteArray) NULL;
367 octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
369 cpnet_IPV4AddressToBytes (address, octets);
371 (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
375 JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
376 cpnet_freeAddress (env, address);
377 return (jbyteArray) NULL;
380 cpnet_freeAddress (env, address);
384 #else /* not WITHOUT_NETWORK */
385 return (jbyteArray) NULL;
386 #endif /* not WITHOUT_NETWORK */