OSDN Git Service

Merged gcj-eclipse branch to trunk.
[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     case 16:
167       addr = cpnet_newIPV6Address(env);
168       cpnet_bytesToIPV6Address (addr, octets);
169       break;
170     default:
171       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
172       return (jstring) NULL;
173
174    }
175
176   /* Release some memory */
177   (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
178
179   /* Resolve the address and return the name */
180   result = cpnet_getHostByAddr (env, addr, hostname, sizeof (hostname));
181   if (result != CPNATIVE_OK)
182     {
183       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION,
184                           cpnative_getErrorString (result));
185       return (jstring) NULL;
186     }
187
188   retval = (*env)->NewStringUTF (env, hostname);
189
190   return (retval);
191 #else /* not WITHOUT_NETWORK */
192   return (jstring) NULL;
193 #endif /* not WITHOUT_NETWORK */
194 }
195
196 /*************************************************************************/
197
198 JNIEXPORT jobjectArray JNICALL
199 Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
200                                            jclass class
201                                            __attribute__ ((__unused__)),
202                                            jstring host)
203 {
204 #ifndef WITHOUT_NETWORK
205   const char *hostname;
206   cpnet_address **addresses;
207   jsize addresses_count;
208   int result;
209   jclass arr_class;
210   jobjectArray addrs;
211   jint i;
212   jbyte *octets;
213   jarray ret_octets;
214
215   /* Grab the hostname string */
216   hostname = (*env)->GetStringUTFChars (env, host, 0);
217   if (!hostname)
218     {
219       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
220       return (jobjectArray) NULL;
221     }
222
223   result = cpnet_getHostByName (env, hostname, &addresses, &addresses_count);
224   if (result != CPNATIVE_OK || addresses_count == 0)
225     {
226       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, (char *) hostname);
227       return (jobjectArray) NULL;
228     }
229   (*env)->ReleaseStringUTFChars (env, host, hostname);
230
231   arr_class = (*env)->FindClass (env, "[B");
232   if (!arr_class)
233     {
234       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
235       return (jobjectArray) NULL;
236     }
237
238   addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0);
239   if (!addrs)
240     {
241       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
242       return (jobjectArray) NULL;
243     }
244
245   /* Now loop and copy in each address */
246   for (i = 0; i < addresses_count; i++)
247     {
248       if (cpnet_isIPV6Address (addresses[i]))
249         {
250           ret_octets = (*env)->NewByteArray (env, 16);
251
252           if (!ret_octets)
253             {
254               JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
255               cpnet_freeAddresses (env, addresses, addresses_count);
256               return (jobjectArray) NULL;
257             }
258           
259           octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
260
261           cpnet_IPV6AddressToBytes (addresses[i], octets);
262
263           (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
264
265           (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
266         }
267       else if (cpnet_isIPV4Address (addresses[i]))
268         {
269           ret_octets = (*env)->NewByteArray (env, 4);
270
271           if (!ret_octets)
272             {
273               JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
274               cpnet_freeAddresses (env, addresses, addresses_count);
275               return (jobjectArray) NULL;
276             }
277           
278           octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
279
280           cpnet_IPV4AddressToBytes (addresses[i], octets);
281
282           (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
283
284           (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
285         }
286       else
287         {
288           JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
289           cpnet_freeAddresses (env, addresses, addresses_count);
290           return (jobjectArray) NULL;
291         }
292     }
293
294   cpnet_freeAddresses (env, addresses, addresses_count);
295
296   return (addrs);
297 #else /* not WITHOUT_NETWORK */
298   return (jobjectArray) NULL;
299 #endif /* not WITHOUT_NETWORK */
300 }
301
302 /*************************************************************************/
303
304 /*
305  * Return the IP address represented by a literal address.
306  * Will return null if the literal address is not valid.
307  */
308 JNIEXPORT jbyteArray JNICALL
309 Java_java_net_VMInetAddress_aton (JNIEnv *env,
310                                   jclass class
311                                   __attribute__ ((__unused__)),
312                                   jstring host)
313 {
314 #ifndef WITHOUT_NETWORK
315   const char *hostname;
316   cpnet_address *address;
317   int result;
318   jbyte *octets;
319   jbyteArray ret_octets;
320
321   hostname = (*env)->GetStringUTFChars (env, host, 0);
322   if (!hostname)
323     {
324       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
325       return (jbyteArray) NULL;
326     }
327
328   result = cpnet_aton (env, hostname, &address);
329   if (result != CPNATIVE_OK)
330     {
331       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
332       if (address)
333         cpnet_freeAddress (env, address);
334       return (jbyteArray) NULL;
335     }
336   if (!address)
337     return (jbyteArray) NULL;
338
339   if (cpnet_isIPV6Address (address))
340     {
341       ret_octets = (jbyteArray) (*env)->NewByteArray (env, 16);
342
343       if (!ret_octets)
344         {
345           JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
346           cpnet_freeAddress (env, address);
347           return (jbyteArray) NULL;
348         }
349           
350       octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
351
352       cpnet_IPV6AddressToBytes (address, octets);
353
354       (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
355     }
356   else if (cpnet_isIPV4Address (address))
357     {
358       ret_octets = (jbyteArray) (*env)->NewByteArray (env, 4);
359
360       if (!ret_octets)
361         {
362           JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
363           cpnet_freeAddress (env, address);
364           return (jbyteArray) NULL;
365         }
366           
367       octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
368
369       cpnet_IPV4AddressToBytes (address, octets);
370
371       (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
372     }
373   else
374     {
375       JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
376       cpnet_freeAddress (env, address);
377       return (jbyteArray) NULL;
378     }
379
380   cpnet_freeAddress (env, address);
381
382   return (ret_octets);
383   
384 #else /* not WITHOUT_NETWORK */
385   return (jbyteArray) NULL;
386 #endif /* not WITHOUT_NETWORK */
387 }
388
389 /* end of file */