OSDN Git Service

libjava/
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / java-net / java_net_VMInetAddress.c
1 /* VMInetAddress.c - Native methods for InetAddress class
2    Copyright (C) 1998, 2002, 2005, 2006  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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)
9 any later version.
10  
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.
15
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
19 02110-1301 USA.
20
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
24 combination.
25
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. */
37
38 /* do not move; needed here because of some macro definitions */
39 #include <config.h>
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44
45 #include <jni.h>
46 #include <jcl.h>
47
48 #include "cpnative.h"
49 #include "cpnet.h"
50 #include "javanet.h"
51
52 #include "java_net_VMInetAddress.h"
53
54 /*************************************************************************/
55
56 /*
57  * Function to return the local hostname
58  */
59 JNIEXPORT jstring JNICALL
60 Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env,
61                                               jclass class
62                                               __attribute__ ((__unused__)))
63 {
64   char hostname[256];
65   int result;
66   jstring retval;
67
68 #ifndef WITHOUT_NETWORK
69   result = cpnet_getHostname (env, hostname, sizeof (hostname));
70   if (result != CPNATIVE_OK)
71     {
72       strcpy (hostname, "localhost");
73     }
74 #else /* not WITHOUT_NETWORK */
75   strcpy (hostname, "localhost");
76 #endif /* not WITHOUT_NETWORK */
77
78   retval = (*env)->NewStringUTF (env, hostname);
79
80   return (retval);
81 }
82
83 /*************************************************************************/
84
85 /*
86  * Returns the value of the special IP address INADDR_ANY 
87  */
88 JNIEXPORT jarray JNICALL
89 Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
90                                              jclass class
91                                              __attribute__ ((__unused__)))
92 {
93   jarray IParray;
94   cpnet_address *addr;
95   jbyte *octets;
96
97   /* Allocate an array for the IP address */
98   IParray = (*env)->NewByteArray (env, 4);
99   if (IParray == NULL)
100     {
101       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
102       return (jarray) NULL;
103     }
104
105   /* Copy in the values */
106   octets = (*env)->GetByteArrayElements (env, IParray, 0);
107
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 */
114   octets[0] = 0;
115   octets[1] = 0;
116   octets[2] = 0;
117   octets[3] = 0;
118 #endif /* not WITHOUT_NETWORK */
119
120   (*env)->ReleaseByteArrayElements (env, IParray, octets, 0);
121
122   return (IParray);
123 }
124
125 /*************************************************************************/
126
127 /*
128  * Function to return the canonical hostname for a given IP address passed
129  * in as a byte array
130  */
131 JNIEXPORT jstring JNICALL
132 Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
133                                            jclass class
134                                            __attribute__ ((__unused__)),
135                                            jarray arr)
136 {
137 #ifndef WITHOUT_NETWORK
138   jbyte *octets;
139   jsize len;
140   cpnet_address *addr;
141   char hostname[255];
142   int result;
143   jstring retval;
144
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)
148     {
149       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
150       return (jstring) NULL;
151     }
152
153   octets = (*env)->GetByteArrayElements (env, arr, 0);
154   if (!octets)
155     {
156       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
157       return (jstring) NULL;
158     }
159
160   switch (len)
161     {
162     case 4:
163       addr = cpnet_newIPV4Address(env);
164       cpnet_bytesToIPV4Address (addr, octets);      
165       break;
166 #ifdef HAVE_INET6
167     case 16:
168       addr = cpnet_newIPV6Address(env);
169       cpnet_bytesToIPV6Address (addr, octets);
170       break;
171 #endif
172     default:
173       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
174       return (jstring) NULL;
175
176    }
177
178   /* Release some memory */
179   (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
180
181   /* Resolve the address and return the name */
182   result = cpnet_getHostByAddr (env, addr, hostname, sizeof (hostname));
183   if (result != CPNATIVE_OK)
184     {
185       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION,
186                           cpnative_getErrorString (result));
187       return (jstring) NULL;
188     }
189
190   retval = (*env)->NewStringUTF (env, hostname);
191
192   return (retval);
193 #else /* not WITHOUT_NETWORK */
194   return (jstring) NULL;
195 #endif /* not WITHOUT_NETWORK */
196 }
197
198 /*************************************************************************/
199
200 JNIEXPORT jobjectArray JNICALL
201 Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
202                                            jclass class
203                                            __attribute__ ((__unused__)),
204                                            jstring host)
205 {
206 #ifndef WITHOUT_NETWORK
207   const char *hostname;
208   cpnet_address **addresses;
209   jsize addresses_count;
210   int result;
211   jclass arr_class;
212   jobjectArray addrs;
213   jint i;
214   jbyte *octets;
215   jarray ret_octets;
216
217   /* Grab the hostname string */
218   hostname = (*env)->GetStringUTFChars (env, host, 0);
219   if (!hostname)
220     {
221       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
222       return (jobjectArray) NULL;
223     }
224
225   result = cpnet_getHostByName (env, hostname, &addresses, &addresses_count);
226   if (result != CPNATIVE_OK || addresses_count == 0)
227     {
228       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, hostname);
229       return (jobjectArray) NULL;
230     }
231   (*env)->ReleaseStringUTFChars (env, host, hostname);
232
233   arr_class = (*env)->FindClass (env, "[B");
234   if (!arr_class)
235     {
236       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
237       return (jobjectArray) NULL;
238     }
239
240   addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0);
241   if (!addrs)
242     {
243       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
244       return (jobjectArray) NULL;
245     }
246
247   /* Now loop and copy in each address */
248   for (i = 0; i < addresses_count; i++)
249     {
250       if (cpnet_isIPV4Address (addresses[i]))
251         {
252           ret_octets = (*env)->NewByteArray (env, 4);
253
254           if (!ret_octets)
255             {
256               JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
257               cpnet_freeAddresses (env, addresses, addresses_count);
258               return (jobjectArray) NULL;
259             }
260           
261           octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
262
263           cpnet_IPV4AddressToBytes (addresses[i], octets);
264
265           (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
266
267           (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
268         }
269 #ifdef HAVE_INET6
270       else if (cpnet_isIPV6Address (addresses[i]))
271         {
272           ret_octets = (*env)->NewByteArray (env, 16);
273
274           if (!ret_octets)
275             {
276               JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
277               cpnet_freeAddresses (env, addresses, addresses_count);
278               return (jobjectArray) NULL;
279             }
280           
281           octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
282
283           cpnet_IPV6AddressToBytes (addresses[i], octets);
284
285           (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
286
287           (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
288         }
289 #endif
290       else
291         {
292           JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
293           cpnet_freeAddresses (env, addresses, addresses_count);
294           return (jobjectArray) NULL;
295         }
296     }
297
298   cpnet_freeAddresses (env, addresses, addresses_count);
299
300   return (addrs);
301 #else /* not WITHOUT_NETWORK */
302   return (jobjectArray) NULL;
303 #endif /* not WITHOUT_NETWORK */
304 }
305
306 /*************************************************************************/
307
308 /*
309  * Return the IP address represented by a literal address.
310  * Will return null if the literal address is not valid.
311  */
312 JNIEXPORT jbyteArray JNICALL
313 Java_java_net_VMInetAddress_aton (JNIEnv *env,
314                                   jclass class
315                                   __attribute__ ((__unused__)),
316                                   jstring host)
317 {
318 #ifndef WITHOUT_NETWORK
319   const char *hostname;
320   cpnet_address *address;
321   int result;
322   jbyte *octets;
323   jbyteArray ret_octets;
324
325   hostname = (*env)->GetStringUTFChars (env, host, 0);
326   if (!hostname)
327     {
328       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
329       return (jbyteArray) NULL;
330     }
331
332   result = cpnet_aton (env, hostname, &address);
333   if (result != CPNATIVE_OK)
334     {
335       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
336       if (address)
337         cpnet_freeAddress (env, address);
338       return (jbyteArray) NULL;
339     }
340   if (!address)
341     return (jbyteArray) NULL;
342
343   if (cpnet_isIPV4Address (address))
344     {
345       ret_octets = (jbyteArray) (*env)->NewByteArray (env, 4);
346
347       if (!ret_octets)
348         {
349           JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
350           cpnet_freeAddress (env, address);
351           return (jbyteArray) NULL;
352         }
353           
354       octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
355
356       cpnet_IPV4AddressToBytes (address, octets);
357
358       (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
359     }
360 #ifdef HAVE_INET6
361   else if (cpnet_isIPV6Address (address))
362     {
363       ret_octets = (jbyteArray) (*env)->NewByteArray (env, 16);
364
365       if (!ret_octets)
366         {
367           JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
368           cpnet_freeAddress (env, address);
369           return (jbyteArray) NULL;
370         }
371           
372       octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
373
374       cpnet_IPV6AddressToBytes (address, octets);
375
376       (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
377     }
378 #endif
379   else
380     {
381       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
382       cpnet_freeAddress (env, address);
383       return (jbyteArray) NULL;
384     }
385
386   cpnet_freeAddress (env, address);
387
388   return (ret_octets);
389   
390 #else /* not WITHOUT_NETWORK */
391   return (jbyteArray) NULL;
392 #endif /* not WITHOUT_NETWORK */
393 }
394
395 /* end of file */