95 error = (*getnameinfo_ptr)(res->ai_addr,
96 res->ai_addrlen,
97 hostname,
98 NI_MAXHOST,
99 NULL,
100 0,
101 NI_NAMEREQD);
102
103 /* if getnameinfo fails hostname is still the value
104 from gethostname */
105
106 (*freeaddrinfo_ptr)(res);
107 }
108 }
109 #endif /* AF_INET6 */
110 #endif /* __linux__ */
111 }
112 return (*env)->NewStringUTF(env, hostname);
113 }
114
115 static jclass ni_iacls;
116 static jclass ni_ia4cls;
117 static jclass ni_ia6cls;
118 static jmethodID ni_ia4ctrID;
119 static jmethodID ni_ia6ctrID;
120 static jfieldID ni_iaaddressID;
121 static jfieldID ni_iahostID;
122 static jfieldID ni_iafamilyID;
123 static jfieldID ni_ia6ipaddressID;
124 static int initialized = 0;
125
126 /*
127 * Find an internet address for a given hostname. Not this this
128 * code only works for addresses of type INET. The translation
129 * of %d.%d.%d.%d to an address (int) occurs in java now, so the
130 * String "host" shouldn't *ever* be a %d.%d.%d.%d string
131 *
132 * Class: java_net_Inet6AddressImpl
133 * Method: lookupAllHostAddr
134 * Signature: (Ljava/lang/String;)[[B
135 */
136
137 JNIEXPORT jobjectArray JNICALL
138 Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
139 jstring host) {
140 const char *hostname;
141 jobjectArray ret = 0;
142 int retLen = 0;
143 jboolean preferIPv6Address;
144
145 int error=0;
146 #ifdef AF_INET6
147 struct addrinfo hints, *res, *resNew = NULL;
148 #endif /* AF_INET6 */
149
150 if (!initialized) {
151 ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
152 ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
153 ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
154 ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
155 ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
156 ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
157 ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
158 ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
159 ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
160 ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
161 ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
162 ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
163 initialized = 1;
164 }
165
166 if (IS_NULL(host)) {
167 JNU_ThrowNullPointerException(env, "host is null");
168 return 0;
169 }
170 hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
171 CHECK_NULL_RETURN(hostname, NULL);
172
173 #ifdef AF_INET6
174 if (NET_addrtransAvailable()) {
175 static jfieldID ia_preferIPv6AddressID;
176 if (ia_preferIPv6AddressID == NULL) {
177 jclass c = (*env)->FindClass(env,"java/net/InetAddress");
178 if (c) {
179 ia_preferIPv6AddressID =
180 (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
181 }
182 if (ia_preferIPv6AddressID == NULL) {
183 JNU_ReleaseStringPlatformChars(env, host, hostname);
184 return NULL;
185 }
186 }
187 /* get the address preference */
188 preferIPv6Address
189 = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
190
191 /* Try once, with our static buffer. */
192 bzero(&hints, sizeof(hints));
193 hints.ai_flags = AI_CANONNAME;
194 hints.ai_family = AF_UNSPEC;
195
196 #ifdef __solaris__
197 /*
198 * Workaround for Solaris bug 4160367 - if a hostname contains a
199 * white space then 0.0.0.0 is returned
200 */
201 if (isspace((unsigned char)hostname[0])) {
202 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
203 (char *)hostname);
204 JNU_ReleaseStringPlatformChars(env, host, hostname);
205 return NULL;
206 }
273 memcpy(next, iterator, sizeof(struct addrinfo));
274 next->ai_next = NULL;
275 if (resNew == NULL) {
276 resNew = next;
277 } else {
278 last->ai_next = next;
279 }
280 last = next;
281 i++;
282 if (iterator->ai_family == AF_INET) {
283 inetCount ++;
284 } else if (iterator->ai_family == AF_INET6) {
285 inet6Count ++;
286 }
287 }
288 iterator = iterator->ai_next;
289 }
290 retLen = i;
291 iterator = resNew;
292
293 ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
294
295 if (IS_NULL(ret)) {
296 /* we may have memory to free at the end of this */
297 goto cleanupAndReturn;
298 }
299
300 if (preferIPv6Address) {
301 /* AF_INET addresses will be offset by inet6Count */
302 inetIndex = inet6Count;
303 inet6Index = 0;
304 } else {
305 /* AF_INET6 addresses will be offset by inetCount */
306 inetIndex = 0;
307 inet6Index = inetCount;
308 }
309
310 while (iterator != NULL) {
311 if (iterator->ai_family == AF_INET) {
312 jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
313 if (IS_NULL(iaObj)) {
314 ret = NULL;
315 goto cleanupAndReturn;
316 }
317 (*env)->SetIntField(env, iaObj, ni_iaaddressID,
318 ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
319 (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
320 (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
321 inetIndex++;
322 } else if (iterator->ai_family == AF_INET6) {
323 jint scope = 0;
324 jbyteArray ipaddress;
325
326 jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
327 if (IS_NULL(iaObj)) {
328 ret = NULL;
329 goto cleanupAndReturn;
330 }
331 ipaddress = (*env)->NewByteArray(env, 16);
332 if (IS_NULL(ipaddress)) {
333 ret = NULL;
334 goto cleanupAndReturn;
335 }
336 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
337 (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
338 #ifdef __linux__
339 if (!kernelIsV22()) {
340 scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
341 }
342 #else
343 scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
344 #endif
345 if (scope != 0) { /* zero is default value, no need to set */
346 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
347 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
348 }
349 (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
350 (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
351 (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
352 inet6Index++;
353 }
354 iterator = iterator->ai_next;
355 }
356 }
357 }
358
359 cleanupAndReturn:
360 {
361 struct addrinfo *iterator, *tmp;
362 iterator = resNew;
363 while (iterator != NULL) {
364 tmp = iterator;
365 iterator = iterator->ai_next;
366 free(tmp);
367 }
368 JNU_ReleaseStringPlatformChars(env, host, hostname);
369 }
370
|
95 error = (*getnameinfo_ptr)(res->ai_addr,
96 res->ai_addrlen,
97 hostname,
98 NI_MAXHOST,
99 NULL,
100 0,
101 NI_NAMEREQD);
102
103 /* if getnameinfo fails hostname is still the value
104 from gethostname */
105
106 (*freeaddrinfo_ptr)(res);
107 }
108 }
109 #endif /* AF_INET6 */
110 #endif /* __linux__ */
111 }
112 return (*env)->NewStringUTF(env, hostname);
113 }
114
115 /*
116 * Find an internet address for a given hostname. Not this this
117 * code only works for addresses of type INET. The translation
118 * of %d.%d.%d.%d to an address (int) occurs in java now, so the
119 * String "host" shouldn't *ever* be a %d.%d.%d.%d string
120 *
121 * Class: java_net_Inet6AddressImpl
122 * Method: lookupAllHostAddr
123 * Signature: (Ljava/lang/String;)[[B
124 */
125
126 JNIEXPORT jobjectArray JNICALL
127 Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
128 jstring host) {
129 const char *hostname;
130 jobjectArray ret = 0;
131 int retLen = 0;
132 jboolean preferIPv6Address;
133
134 int error=0;
135 #ifdef AF_INET6
136 struct addrinfo hints, *res, *resNew = NULL;
137 #endif /* AF_INET6 */
138
139 init(env);
140
141 if (IS_NULL(host)) {
142 JNU_ThrowNullPointerException(env, "host is null");
143 return 0;
144 }
145 hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
146 CHECK_NULL_RETURN(hostname, NULL);
147
148 #ifdef AF_INET6
149 if (NET_addrtransAvailable()) {
150 /* get the address preference */
151 preferIPv6Address
152 = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
153
154 /* Try once, with our static buffer. */
155 bzero(&hints, sizeof(hints));
156 hints.ai_flags = AI_CANONNAME;
157 hints.ai_family = AF_UNSPEC;
158
159 #ifdef __solaris__
160 /*
161 * Workaround for Solaris bug 4160367 - if a hostname contains a
162 * white space then 0.0.0.0 is returned
163 */
164 if (isspace((unsigned char)hostname[0])) {
165 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
166 (char *)hostname);
167 JNU_ReleaseStringPlatformChars(env, host, hostname);
168 return NULL;
169 }
236 memcpy(next, iterator, sizeof(struct addrinfo));
237 next->ai_next = NULL;
238 if (resNew == NULL) {
239 resNew = next;
240 } else {
241 last->ai_next = next;
242 }
243 last = next;
244 i++;
245 if (iterator->ai_family == AF_INET) {
246 inetCount ++;
247 } else if (iterator->ai_family == AF_INET6) {
248 inet6Count ++;
249 }
250 }
251 iterator = iterator->ai_next;
252 }
253 retLen = i;
254 iterator = resNew;
255
256 ret = (*env)->NewObjectArray(env, retLen, ia_class, NULL);
257
258 if (IS_NULL(ret)) {
259 /* we may have memory to free at the end of this */
260 goto cleanupAndReturn;
261 }
262
263 if (preferIPv6Address) {
264 /* AF_INET addresses will be offset by inet6Count */
265 inetIndex = inet6Count;
266 inet6Index = 0;
267 } else {
268 /* AF_INET6 addresses will be offset by inetCount */
269 inetIndex = 0;
270 inet6Index = inetCount;
271 }
272
273 while (iterator != NULL) {
274 if (iterator->ai_family == AF_INET) {
275 jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
276 if (IS_NULL(iaObj)) {
277 ret = NULL;
278 goto cleanupAndReturn;
279 }
280 (*env)->SetIntField(env, iaObj, ia_addressID,
281 ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
282 (*env)->SetObjectField(env, iaObj, ia_hostNameID, host);
283 (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
284 inetIndex++;
285 } else if (iterator->ai_family == AF_INET6) {
286 jint scope = 0;
287 jbyteArray ipaddress;
288
289 jobject iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
290 if (IS_NULL(iaObj)) {
291 ret = NULL;
292 goto cleanupAndReturn;
293 }
294 ipaddress = (*env)->NewByteArray(env, 16);
295 if (IS_NULL(ipaddress)) {
296 ret = NULL;
297 goto cleanupAndReturn;
298 }
299 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
300 (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
301 #ifdef __linux__
302 if (!kernelIsV22()) {
303 scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
304 }
305 #else
306 scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
307 #endif
308 if (scope != 0) { /* zero is default value, no need to set */
309 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
310 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
311 }
312 (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
313 (*env)->SetObjectField(env, iaObj, ia_hostNameID, host);
314 (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
315 inet6Index++;
316 }
317 iterator = iterator->ai_next;
318 }
319 }
320 }
321
322 cleanupAndReturn:
323 {
324 struct addrinfo *iterator, *tmp;
325 iterator = resNew;
326 while (iterator != NULL) {
327 tmp = iterator;
328 iterator = iterator->ai_next;
329 free(tmp);
330 }
331 JNU_ReleaseStringPlatformChars(env, host, hostname);
332 }
333
|