/* * Class: java_net_NetworkInterface * Method: getByIndex * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex (JNIEnv *env, jclass cls, jint index) { netif *ifs, *curr; jobject obj = NULL; if (index <= 0) { return NULL; } ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } /* * Search the list of interface based on index */ curr = ifs; while (curr != NULL) { if (index == curr->index) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) {; obj = createNetworkInterface(env, curr); } freeif(ifs); return obj; }
/* * Class: NetworkInterface * Method: getByIndex0 * Signature: (I)LNetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0 (JNIEnv *env, jclass cls, jint index) { netif *ifList, *curr; jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByIndex0_XP (env, cls, index); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* search by index */ curr = ifList; while (curr != NULL) { if (index == curr->index) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) { netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the interface list */ free_netif(ifList); return netifObj; }
/* * Class: java_net_NetworkInterface * Method: getByName0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 (JNIEnv *env, jclass cls, jstring name) { netif *ifs, *curr; jboolean isCopy; const char* name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); jobject obj = NULL; ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } /* * Search the list of interface based on name */ curr = ifs; while (curr != NULL) { if (strcmp(name_utf, curr->name) == 0) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) {; obj = createNetworkInterface(env, curr); } /* release the UTF string and interface list */ (*env)->ReleaseStringUTFChars(env, name, name_utf); freeif(ifs); return obj; }
/* * Class: java_net_NetworkInterface * Method: getAll * Signature: ()[Ljava/net/NetworkInterface; */ JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll (JNIEnv *env, jclass cls) { int count; netif *ifList, *curr; jobjectArray netIFArr; jint arr_index; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getAll_XP (env, cls); } /* * Get list of interfaces */ count = enumInterfaces(env, &ifList); if (count < 0) { return NULL; } /* allocate a NetworkInterface array */ netIFArr = (*env)->NewObjectArray(env, count, cls, NULL); if (netIFArr == NULL) { return NULL; } /* * Iterate through the interfaces, create a NetworkInterface instance * for each array element and populate the object. */ curr = ifList; arr_index = 0; while (curr != NULL) { jobject netifObj; netifObj = createNetworkInterface(env, curr, -1, NULL); if (netifObj == NULL) { return NULL; } /* put the NetworkInterface into the array */ (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj); curr = curr->next; } /* release the interface list */ free_netif(ifList); return netIFArr; }
/* * Class: java_net_NetworkInterface * Method: getAll * Signature: ()[Ljava/net/NetworkInterface; */ JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll (JNIEnv *env, jclass cls) { netif *ifs, *curr; jobjectArray netIFArr; jint arr_index, ifCount; ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } /* count the interface */ ifCount = 0; curr = ifs; while (curr != NULL) { ifCount++; curr = curr->next; } /* allocate a NetworkInterface array */ netIFArr = (*env)->NewObjectArray(env, ifCount, cls, NULL); if (netIFArr == NULL) { freeif(ifs); return NULL; } /* * Iterate through the interfaces, create a NetworkInterface instance * for each array element and populate the object. */ curr = ifs; arr_index = 0; while (curr != NULL) { jobject netifObj; netifObj = createNetworkInterface(env, curr); if (netifObj == NULL) { freeif(ifs); return NULL; } /* put the NetworkInterface into the array */ (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj); curr = curr->next; } freeif(ifs); return netIFArr; }
/* * Class: java_net_NetworkInterface * Method: getByName0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 (JNIEnv *env, jclass cls, jstring name) { netif *ifList, *curr; jboolean isCopy; const char *name_utf; jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByName0_XP (env, cls, name); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* get the name as a C string */ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); if (name_utf != NULL) { /* Search by name */ curr = ifList; while (curr != NULL) { if (strcmp(name_utf, curr->name) == 0) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) { ; netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the UTF string */ (*env)->ReleaseStringUTFChars(env, name, name_utf); } else { if (!(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, NULL); } /* release the interface list */ free_netif(ifList); return netifObj; }
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP) { DWORD ret; IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL; ULONG len=ipinflen, count=0; netif *nif=NULL, *dup_nif, *last=NULL, *loopif=NULL, *curr; int tun=0, net=0; *netifPP = NULL; /* * Get the IPv4 interfaces. This information is the same * as what previous JDK versions would return. */ ret = enumInterfaces(env, netifPP); if (ret == -1) { return -1; } else { count = ret; } /* locate the loopback (and the last) interface */ for (nif=*netifPP, last=nif; nif!=NULL; nif=nif->next) { if (nif->ifType == MIB_IF_TYPE_LOOPBACK) { loopif = nif; } last = nif; } // Retrieve IPv4 addresses with the IP Helper API curr = *netifPP; while (curr != NULL) { netaddr *netaddrP; ret = enumAddresses_win(env, curr, &netaddrP); if (ret == -1) { return -1; } curr->addrs = netaddrP; curr->naddrs += ret; curr = curr->next; } ret = getAdapters (env, &adapters); if (ret != ERROR_SUCCESS) { goto err; } /* Now get the IPv6 information. This includes: * (a) IPv6 information associated with interfaces already found * (b) IPv6 information for IPv6 only interfaces (probably tunnels) * * For compatibility with previous releases we use the naming * information gotten from enumInterfaces() for (a) entries * However, the index numbers are taken from the new API. * * The procedure is to go through the list of adapters returned * by the new API looking for entries that correspond to IPv4 interfaces * already found. */ ptr = adapters; while (ptr != NULL) { int c; netif *nif0; if (ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK && (loopif != NULL)) { c = getAddrsFromAdapter(ptr, &loopif->addrs); if (c == -1) { goto err; } loopif->naddrs += c; } else { int index = ptr->IfIndex; if (index != 0) { /* This entry is associated with an IPv4 interface */ for (nif=*netifPP; nif!=NULL; nif=nif->next) { if (nif->index == index) { /* found the interface entry * set the index to the IPv6 index and add the * IPv6 addresses */ nif->ipv6Index = ptr->Ipv6IfIndex; c = getAddrsFromAdapter(ptr, &nif->addrs); nif->naddrs += c; break; } } } else { /* This entry is IPv6 only */ char newname [128]; int c; /* Windows allocates duplicate adapter entries * for tunnel interfaces when there are multiple * physical adapters. Need to check * if this is a duplicate (ipv6Index is the same) */ dup_nif = 0; for (nif0=*netifPP; nif0!=NULL; nif0=nif0->next) { if (nif0->hasIpv6Address && ptr->Ipv6IfIndex == nif0->ipv6Index) { dup_nif = nif0; break; } } if (dup_nif == 0) { /* new interface */ nif = (netif *) calloc (1, sizeof(netif)); if (nif == 0) { goto err; } if (ptr->IfType == IF_TYPE_TUNNEL) { sprintf (newname, "tun%d", tun); tun ++; } else { sprintf (newname, "net%d", net); net ++; } nif->name = malloc (strlen(newname)+1); nif->displayName = malloc (wcslen(ptr->FriendlyName)*2+2); if (nif->name == 0 || nif->displayName == 0) { goto err; } strcpy (nif->name, newname); wcscpy ((PWCHAR)nif->displayName, ptr->FriendlyName); nif->dNameIsUnicode = TRUE; // the java.net.NetworkInterface abstraction only has index // so the Ipv6IfIndex needs to map onto index nif->index = ptr->Ipv6IfIndex; nif->ipv6Index = ptr->Ipv6IfIndex; nif->hasIpv6Address = TRUE; last->next = nif; last = nif; count++; c = getAddrsFromAdapter(ptr, &nif->addrs); if (c == -1) { goto err; } nif->naddrs += c; } else { /* add the addresses from this adapter to the * original (dup_nif) */ c = getAddrsFromAdapter(ptr, &dup_nif->addrs); if (c == -1) { goto err; } dup_nif->naddrs += c; } } } ptr=ptr->Next; } free (adapters); return count; err: if (*netifPP) { free_netif (*netifPP); } if (adapters) { free (adapters); } return -1; }
/* * Class: java_net_NetworkInterface * Method: getByInetAddress0 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 (JNIEnv *env, jclass cls, jobject iaObj) { netif *ifList, *curr; jint addr = getInetAddress_addr(env, iaObj); jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* * Enumerate the addresses on each interface until we find a * matching address. */ curr = ifList; while (curr != NULL) { int count; netaddr *addrList; netaddr *addrP; /* enumerate the addresses on this interface */ count = enumAddresses_win(env, curr, &addrList); if (count < 0) { free_netif(ifList); return NULL; } /* iterate through each address */ addrP = addrList; while (addrP != NULL) { if ((unsigned long)addr == ntohl(addrP->addr.him4.sin_addr.s_addr)) { break; } addrP = addrP->next; } /* * Address matched so create NetworkInterface for this interface * and address list. */ if (addrP != NULL) { /* createNetworkInterface will free addrList */ netifObj = createNetworkInterface(env, curr, count, addrList); break; } /* on next interface */ curr = curr->next; } /* release the interface list */ free_netif(ifList); return netifObj; }
/* * Class: java_net_NetworkInterface * Method: getByInetAddress0 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 (JNIEnv *env, jclass cls, jobject iaObj) { netif *ifs, *curr; int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6; jobject obj = NULL; jboolean match = JNI_FALSE; ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } curr = ifs; while (curr != NULL) { netaddr *addrP = curr->addr; /* * Iterate through each address on the interface */ while (addrP != NULL) { if (family == addrP->family) { if (family == AF_INET) { int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); int address2 = getInetAddress_addr(env, iaObj); if (address1 == address2) { match = JNI_TRUE; break; } } #ifdef AF_INET6 if (family == AF_INET6) { jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr); jbyte caddr[16]; int i; getInet6Address_ipaddress(env, iaObj, (char *)caddr); i = 0; while (i < 16) { if (caddr[i] != bytes[i]) { break; } i++; } if (i >= 16) { match = JNI_TRUE; break; } } #endif } if (match) { break; } addrP = addrP->next; } if (match) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (match) {; obj = createNetworkInterface(env, curr); } freeif(ifs); return obj; }
/* * Class: java_net_NetworkInterface * Method: getByInetAddress0 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 (JNIEnv *env, jclass cls, jobject iaObj) { netif *ifs, *curr; int family = KAfInet; jobject obj = NULL; jboolean match = JNI_FALSE; jint jfamily = (*env)->GetIntField(env, iaObj, ni_iafamilyID); if (jfamily != IPv4) { family = KAfInet6; } ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } curr = ifs; while (curr != NULL) { netaddr *addrP = curr->addr; /* * Iterate through each address on the interface */ while (addrP != NULL) { if (family == addrP->family) { if (family == KAfInet) { int address1 = addrP->ia.Address(); int address2 = (*env)->GetIntField(env, iaObj, ni_iaaddressID); if (address1 == address2) { match = JNI_TRUE; break; } } if (family == KAfInet6) { const TIp6Addr &ipv6address = addrP->ia.Ip6Address(); jbyte *bytes = (jbyte *)ipv6address.u.iAddr8; jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ni_ia6ipaddressID); jbyte caddr[16]; int i; (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); i = 0; while (i < 16) { if (caddr[i] != bytes[i]) { break; } i++; } if (i >= 16) { match = JNI_TRUE; break; } } } if (match) { break; } addrP = addrP->next; } if (match) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (match) {; obj = createNetworkInterface(env, curr); } freeif(ifs); return obj; }