318 freeif(ifs); |
318 freeif(ifs); |
319 |
319 |
320 return obj; |
320 return obj; |
321 } |
321 } |
322 |
322 |
323 /* |
323 // Return the interface in ifs that iaObj is bound to, if any - otherwise NULL |
324 * Class: java_net_NetworkInterface |
324 static netif* find_bound_interface(JNIEnv *env, netif* ifs, jobject iaObj, int family) { |
325 * Method: getByInetAddress0 |
325 netif* curr = ifs; |
326 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; |
|
327 */ |
|
328 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 |
|
329 (JNIEnv *env, jclass cls, jobject iaObj) |
|
330 { |
|
331 netif *ifs, *curr; |
|
332 jobject obj = NULL; |
|
333 jboolean match = JNI_FALSE; |
|
334 int family = getInetAddress_family(env, iaObj); |
|
335 JNU_CHECK_EXCEPTION_RETURN(env, NULL); |
|
336 |
|
337 if (family == java_net_InetAddress_IPv4) { |
|
338 family = AF_INET; |
|
339 } else if (family == java_net_InetAddress_IPv6) { |
|
340 family = AF_INET6; |
|
341 } else { |
|
342 return NULL; // Invalid family |
|
343 } |
|
344 ifs = enumInterfaces(env); |
|
345 if (ifs == NULL) { |
|
346 return NULL; |
|
347 } |
|
348 |
|
349 curr = ifs; |
|
350 while (curr != NULL) { |
326 while (curr != NULL) { |
351 netaddr *addrP = curr->addr; |
327 netaddr *addrP = curr->addr; |
352 |
328 |
353 // iterate through each address on the interface |
329 // iterate through each address on the interface |
354 while (addrP != NULL) { |
330 while (addrP != NULL) { |
357 if (family == AF_INET) { |
333 if (family == AF_INET) { |
358 int address1 = htonl( |
334 int address1 = htonl( |
359 ((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr); |
335 ((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr); |
360 int address2 = getInetAddress_addr(env, iaObj); |
336 int address2 = getInetAddress_addr(env, iaObj); |
361 if ((*env)->ExceptionCheck(env)) { |
337 if ((*env)->ExceptionCheck(env)) { |
362 goto cleanup; |
338 return NULL; |
363 } |
339 } |
364 if (address1 == address2) { |
340 if (address1 == address2) { |
365 match = JNI_TRUE; |
341 return curr; |
366 break; |
|
367 } |
342 } |
368 } else if (family == AF_INET6) { |
343 } else if (family == AF_INET6) { |
369 jbyte *bytes = (jbyte *)&( |
344 jbyte *bytes = (jbyte *)&( |
370 ((struct sockaddr_in6*)addrP->addr)->sin6_addr); |
345 ((struct sockaddr_in6*)addrP->addr)->sin6_addr); |
371 jbyte caddr[16]; |
346 jbyte caddr[16]; |
381 break; |
356 break; |
382 } |
357 } |
383 i++; |
358 i++; |
384 } |
359 } |
385 if (i >= 16) { |
360 if (i >= 16) { |
386 match = JNI_TRUE; |
361 return curr; |
387 break; |
|
388 } |
362 } |
389 } |
363 } |
390 } |
364 } |
391 |
365 |
392 if (match) { |
366 addrP = addrP->next; |
393 break; |
367 } |
|
368 curr = curr->next; |
|
369 } |
|
370 |
|
371 return NULL; |
|
372 } |
|
373 |
|
374 /* |
|
375 * Class: java_net_NetworkInterface |
|
376 * Method: boundInetAddress0 |
|
377 * Signature: (Ljava/net/InetAddress;)boundInetAddress; |
|
378 */ |
|
379 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0 |
|
380 (JNIEnv *env, jclass cls, jobject iaObj) |
|
381 { |
|
382 netif *ifs = NULL; |
|
383 jboolean bound = JNI_FALSE; |
|
384 int sock; |
|
385 |
|
386 int family = getInetAddress_family(env, iaObj); |
|
387 JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); |
|
388 |
|
389 if (family == java_net_InetAddress_IPv4) { |
|
390 family = AF_INET; |
|
391 } else if (family == java_net_InetAddress_IPv6) { |
|
392 family = AF_INET6; |
|
393 } else { |
|
394 return JNI_FALSE; // Invalid family |
|
395 } |
|
396 |
|
397 if (family == AF_INET) { |
|
398 sock = openSocket(env, AF_INET); |
|
399 if (sock < 0 && (*env)->ExceptionOccurred(env)) { |
|
400 return JNI_FALSE; |
|
401 } |
|
402 |
|
403 // enumerate IPv4 addresses |
|
404 if (sock >= 0) { |
|
405 ifs = enumIPv4Interfaces(env, sock, ifs); |
|
406 close(sock); |
|
407 |
|
408 if ((*env)->ExceptionOccurred(env)) { |
|
409 goto cleanup; |
394 } |
410 } |
395 addrP = addrP->next; |
411 } |
396 } |
412 if (find_bound_interface(env, ifs, iaObj, family) != NULL) |
397 |
413 bound = JNI_TRUE; |
398 if (match) { |
414 } else if (ipv6_available()) { |
399 break; |
415 // If IPv6 is available then enumerate IPv6 addresses. |
400 } |
416 // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true, |
401 curr = curr->next; |
417 // so we have to call ipv6_available() |
402 } |
418 sock = openSocket(env, AF_INET6); |
|
419 if (sock < 0) { |
|
420 return JNI_FALSE; |
|
421 } |
|
422 |
|
423 ifs = enumIPv6Interfaces(env, sock, ifs); |
|
424 close(sock); |
|
425 |
|
426 if ((*env)->ExceptionOccurred(env)) { |
|
427 goto cleanup; |
|
428 } |
|
429 |
|
430 if (find_bound_interface(env, ifs, iaObj, family) != NULL) |
|
431 bound = JNI_TRUE; |
|
432 } |
|
433 |
|
434 cleanup: |
|
435 freeif(ifs); |
|
436 |
|
437 return bound; |
|
438 } |
|
439 |
|
440 /* |
|
441 * Class: java_net_NetworkInterface |
|
442 * Method: getByInetAddress0 |
|
443 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; |
|
444 */ |
|
445 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 |
|
446 (JNIEnv *env, jclass cls, jobject iaObj) |
|
447 { |
|
448 netif *ifs, *curr; |
|
449 jobject obj = NULL; |
|
450 int family = getInetAddress_family(env, iaObj); |
|
451 JNU_CHECK_EXCEPTION_RETURN(env, NULL); |
|
452 |
|
453 if (family == java_net_InetAddress_IPv4) { |
|
454 family = AF_INET; |
|
455 } else if (family == java_net_InetAddress_IPv6) { |
|
456 family = AF_INET6; |
|
457 } else { |
|
458 return NULL; // Invalid family |
|
459 } |
|
460 ifs = enumInterfaces(env); |
|
461 if (ifs == NULL) { |
|
462 return NULL; |
|
463 } |
|
464 |
|
465 curr = find_bound_interface(env, ifs, iaObj, family); |
403 |
466 |
404 // if found create a NetworkInterface |
467 // if found create a NetworkInterface |
405 if (match) { |
468 if (curr != NULL) { |
406 obj = createNetworkInterface(env, curr); |
469 obj = createNetworkInterface(env, curr); |
407 } |
470 } |
408 |
471 |
409 cleanup: |
|
410 // release the interface list |
472 // release the interface list |
411 freeif(ifs); |
473 freeif(ifs); |
412 |
474 |
413 return obj; |
475 return obj; |
414 } |
476 } |