src/java.base/unix/native/libnet/NetworkInterface.c
changeset 55596 d01b345865d7
parent 54889 53d51822f287
child 55753 b9798272720b
equal deleted inserted replaced
55595:cf5a438b3c41 55596:d01b345865d7
   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 }