# HG changeset patch # User clanger # Date 1470303228 -7200 # Thu Aug 04 11:33:48 2016 +0200 # Node ID 83ead3b3b6cefa0ebd299968efbad3a29286f6ba # Parent dd6e19a810cec2805fb3849c6343f42efc830197 Further networkinterface.c cleanups diff --git a/src/java.base/unix/native/libnet/NetworkInterface.c b/src/java.base/unix/native/libnet/NetworkInterface.c --- a/src/java.base/unix/native/libnet/NetworkInterface.c +++ b/src/java.base/unix/native/libnet/NetworkInterface.c @@ -80,6 +80,12 @@ #define DEV_PREFIX "/dev/" #endif +#ifdef LIFNAMSIZ + #define IFNAMESIZE LIFNAMSIZ +#else + #define IFNAMESIZE IFNAMSIZ +#endif + #define CHECKED_MALLOC3(_pointer, _type, _size) \ do { \ _pointer = (_type)malloc(_size); \ @@ -158,7 +164,7 @@ static int getIndex(int sock, const char *ifname); static int getFlags(int sock, const char *ifname, int *flags); -static int getMacAddress(JNIEnv *env, int sock, const char *ifname, +static int getMacAddress(JNIEnv *env, const char *ifname, const struct in_addr *addr, unsigned char *buf); static int getMTU(JNIEnv *env, int sock, const char *ifname); @@ -237,20 +243,25 @@ const char* name_utf; jobject obj = NULL; + if (name != NULL) { + name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); + } else { + JNU_ThrowNullPointerException(env, "network interface name is NULL"); + return NULL; + } + + if (name_utf == NULL) { + if (!(*env)->ExceptionCheck(env)) + JNU_ThrowOutOfMemoryError(env, NULL); + return NULL; + } + ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } - name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); - if (name_utf == NULL) { - if (!(*env)->ExceptionCheck(env)) - JNU_ThrowOutOfMemoryError(env, NULL); - freeif(ifs); - return NULL; - } - - // Search the list of interface based on name + // search the list of interfaces based on name curr = ifs; while (curr != NULL) { if (strcmp(name_utf, curr->name) == 0) { @@ -285,12 +296,13 @@ if (index <= 0) { return NULL; } + ifs = enumInterfaces(env); if (ifs == NULL) { return NULL; } - // Search the list of interface based on index + // search the list of interfaces based on index curr = ifs; while (curr != NULL) { if (index == curr->index) { @@ -304,7 +316,9 @@ obj = createNetworkInterface(env, curr); } + // release the interface list freeif(ifs); + return obj; } @@ -317,13 +331,11 @@ (JNIEnv *env, jclass cls, jobject iaObj) { netif *ifs, *curr; - #if defined(AF_INET6) int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6; #else int family = AF_INET; #endif - jobject obj = NULL; jboolean match = JNI_FALSE; @@ -342,7 +354,7 @@ if (family == addrP->family) { if (family == AF_INET) { int address1 = htonl( - ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); + ((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr); int address2 = getInetAddress_addr(env, iaObj); if (address1 == address2) { @@ -350,7 +362,6 @@ break; } } - #if defined(AF_INET6) if (family == AF_INET6) { jbyte *bytes = (jbyte *)&( @@ -390,7 +401,9 @@ obj = createNetworkInterface(env, curr); } + // release the interface list freeif(ifs); + return obj; } @@ -411,7 +424,7 @@ return NULL; } - // count the interface + // count the interfaces ifCount = 0; curr = ifs; while (curr != NULL) { @@ -426,8 +439,8 @@ return NULL; } - // Iterate through the interfaces, create a NetworkInterface instance - // for each array element and populate the object. + // iterate through the interfaces, create a NetworkInterface instance + // for each array element and populate the object curr = ifs; arr_index = 0; while (curr != NULL) { @@ -445,7 +458,9 @@ curr = curr->next; } + // release the interface list freeif(ifs); + return netIFArr; } @@ -511,46 +526,45 @@ jbyteArray ret = NULL; unsigned char mac[16]; int len; - int sock; jboolean isCopy; - const char* name_utf; + const char *name_utf; - name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); + if (name != NULL) { + name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); + } else { + JNU_ThrowNullPointerException(env, "network interface name is NULL"); + return NULL; + } + if (name_utf == NULL) { - if (!(*env)->ExceptionCheck(env)) - JNU_ThrowOutOfMemoryError(env, NULL); - return NULL; - } - if ((sock = openSocketWithFallback(env, name_utf)) < 0) { - (*env)->ReleaseStringUTFChars(env, name, name_utf); - return NULL; + if (!(*env)->ExceptionCheck(env)) + JNU_ThrowOutOfMemoryError(env, NULL); + return NULL; } if (!IS_NULL(addrArray)) { - (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr); - addr = ((caddr[0]<<24) & 0xff000000); - addr |= ((caddr[1] <<16) & 0xff0000); - addr |= ((caddr[2] <<8) & 0xff00); - addr |= (caddr[3] & 0xff); - iaddr.s_addr = htonl(addr); - len = getMacAddress(env, sock, name_utf, &iaddr, mac); + (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr); + addr = ((caddr[0]<<24) & 0xff000000); + addr |= ((caddr[1] <<16) & 0xff0000); + addr |= ((caddr[2] <<8) & 0xff00); + addr |= (caddr[3] & 0xff); + iaddr.s_addr = htonl(addr); + len = getMacAddress(env, name_utf, &iaddr, mac); } else { - len = getMacAddress(env, sock, name_utf, NULL, mac); + len = getMacAddress(env, name_utf, NULL, mac); } + if (len > 0) { - ret = (*env)->NewByteArray(env, len); - if (IS_NULL(ret)) { - /* we may have memory to free at the end of this */ - goto fexit; - } - (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *)(mac)); + ret = (*env)->NewByteArray(env, len); + if (!IS_NULL(ret)) { + (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *)(mac)); + } } - fexit: - // release the UTF string and interface list - (*env)->ReleaseStringUTFChars(env, name, name_utf); - close(sock); - return ret; + // release the UTF string and interface list + (*env)->ReleaseStringUTFChars(env, name, name_utf); + + return ret; } /* @@ -562,8 +576,7 @@ (JNIEnv *env, jclass cls, jstring name, jint index) { jboolean isCopy; - int ret = -1; - int sock; + int sock, ret = -1; const char* name_utf = NULL; if (name != NULL) { @@ -572,6 +585,7 @@ JNU_ThrowNullPointerException(env, "network interface name is NULL"); return ret; } + if (name_utf == NULL) { if (!(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, NULL); @@ -595,9 +609,8 @@ static int getFlags0(JNIEnv *env, jstring name) { jboolean isCopy; - int ret, sock; - const char* name_utf; - int flags = 0; + int ret, sock, flags = 0; + const char *name_utf; if (name != NULL) { name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); @@ -648,7 +661,7 @@ netif *childP; jobject tmp; - // Create a NetworkInterface object and populate it + // create a NetworkInterface object and populate it netifObj = (*env)->NewObject(env, ni_class, ni_ctrID); CHECK_NULL_RETURN(netifObj, NULL); name = (*env)->NewStringUTF(env, ifs->name); @@ -659,7 +672,7 @@ (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE); - //Count the number of address on this interface + // count the number of addresses on this interface addr_count = 0; addrP = ifs->addr; while (addrP != NULL) { @@ -667,7 +680,7 @@ addrP = addrP->next; } - // Create the array of InetAddresses + // create the array of InetAddresses addrArr = (*env)->NewObjectArray(env, addr_count, ia_class, NULL); if (addrArr == NULL) { return NULL; @@ -712,7 +725,6 @@ return NULL; } } - #if defined(AF_INET6) if (addrP->family == AF_INET6) { int scope=0; @@ -748,7 +760,7 @@ addrP = addrP->next; } - // See if there is any virtual interface attached to this one. + // see if there is any virtual interface attached to this one. child_count = 0; childP = ifs->childs; while (childP) { @@ -761,7 +773,7 @@ return NULL; } - // Create the NetworkInterface instances for the sub-interfaces as well. + // create the NetworkInterface instances for the sub-interfaces as well child_index = 0; childP = ifs->childs; while(childP) { @@ -785,46 +797,42 @@ * Enumerates all interfaces */ static netif *enumInterfaces(JNIEnv *env) { - netif *ifs; + netif *ifs = NULL; int sock; - // Enumerate IPv4 addresses sock = openSocket(env, AF_INET); if (sock < 0 && (*env)->ExceptionOccurred(env)) { return NULL; } + // enumerate IPv4 addresses ifs = enumIPv4Interfaces(env, sock, NULL); close(sock); + // return partial list if an exception occurs in the middle of process ??? if (ifs == NULL && (*env)->ExceptionOccurred(env)) { return NULL; } - // return partial list if an exception occurs in the middle of process ??? - // If IPv6 is available then enumerate IPv6 addresses. #if defined(AF_INET6) - // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true, // so we have to call ipv6_available() if (ipv6_available()) { + sock = openSocket(env, AF_INET6); + if (sock < 0 && (*env)->ExceptionOccurred(env)) { + freeif(ifs); + return NULL; + } - sock = openSocket(env, AF_INET6); - if (sock < 0 && (*env)->ExceptionOccurred(env)) { - freeif(ifs); - return NULL; - } + ifs = enumIPv6Interfaces(env, sock, ifs); + close(sock); - ifs = enumIPv6Interfaces(env, sock, ifs); - close(sock); - - if ((*env)->ExceptionOccurred(env)) { - freeif(ifs); - return NULL; - } - - } + if ((*env)->ExceptionOccurred(env)) { + freeif(ifs); + return NULL; + } + } #endif return ifs; @@ -845,7 +853,7 @@ addrP = next; } - // Don't forget to free the sub-interfaces. + // don't forget to free the sub-interfaces if (currif->childs != NULL) { freeif(currif->childs); } @@ -863,26 +871,17 @@ { netif *currif = ifs, *parent; netaddr *addrP; - -#ifdef LIFNAMSIZ - int ifnam_size = LIFNAMSIZ; - char name[LIFNAMSIZ], vname[LIFNAMSIZ]; -#else - int ifnam_size = IFNAMSIZ; - char name[IFNAMSIZ], vname[IFNAMSIZ]; -#endif - + char name[IFNAMESIZE], vname[IFNAMESIZE]; char *name_colonP; int isVirtual = 0; int addr_size; - int flags = 0; // If the interface name is a logical interface then we remove the unit // number so that we have the physical interface (eg: hme0:1 -> hme0). // NetworkInterface currently doesn't have any concept of physical vs. // logical interfaces. - strncpy(name, if_name, ifnam_size); - name[ifnam_size - 1] = '\0'; + strncpy(name, if_name, IFNAMESIZE); + name[IFNAMESIZE - 1] = '\0'; *vname = 0; // Create and populate the netaddr node. If allocation fails @@ -917,6 +916,7 @@ // Deal with virtual interface with colon notation e.g. eth0:1 name_colonP = strchr(name, ':'); if (name_colonP != NULL) { + int flags = 0; // This is a virtual interface. If we are able to access the parent // we need to create a new entry if it doesn't exist yet *and* update // the 'parent' interface with the new records. @@ -929,7 +929,7 @@ } else { // Got access to parent, so create it if necessary. // Save original name to vname and truncate name by ':' - memcpy(vname, name, sizeof(vname) ); + memcpy(vname, name, sizeof(vname)); vname[name_colonP - name] = ':'; } } @@ -943,12 +943,12 @@ currif = currif->next; } - // If "new" then create an netif structure and insert it into the list. + // If "new" then create a netif structure and insert it into the list. if (currif == NULL) { - CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size); + CHECKED_MALLOC3(currif, netif *, sizeof(netif) + IFNAMESIZE); currif->name = (char *)currif + sizeof(netif); - strncpy(currif->name, name, ifnam_size); - currif->name[ifnam_size - 1] = '\0'; + strncpy(currif->name, name, IFNAMESIZE); + currif->name[IFNAMESIZE - 1] = '\0'; currif->index = getIndex(sock, name); currif->addr = NULL; currif->childs = NULL; @@ -977,13 +977,12 @@ } if (currif == NULL) { - CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size); + CHECKED_MALLOC3(currif, netif *, sizeof(netif) + IFNAMESIZE); currif->name = (char *)currif + sizeof(netif); - strncpy(currif->name, vname, ifnam_size); - currif->name[ifnam_size - 1] = '\0'; + strncpy(currif->name, vname, IFNAMESIZE); + currif->name[IFNAMESIZE - 1] = '\0'; currif->index = getIndex(sock, vname); - currif->addr = NULL; - // Need to duplicate the addr entry? + currif->addr = NULL; // Need to duplicate the addr entry? currif->virtual = 1; currif->childs = NULL; currif->next = parent->childs; @@ -1264,19 +1263,26 @@ * MAC address. Returns -1 if there is no hardware address on that interface. */ static int getMacAddress - (JNIEnv *env, int sock, const char *ifname, const struct in_addr *addr, + (JNIEnv *env, const char *ifname, const struct in_addr *addr, unsigned char *buf) { static struct ifreq ifr; - int i; + int i, sock; + + if ((sock = openSocketWithFallback(env, ifname)) < 0) { + return -1; + } + memset((char *)&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { JNU_ThrowByNameWithMessageAndLastError (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGIFHWADDR) failed"); + close(sock); return -1; } + close(sock); memcpy(buf, &ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); // all bytes to 0 means no hardware address @@ -1527,7 +1533,7 @@ * MAC address. Returns -1 if there is no hardware address on that interface. */ static int getMacAddress - (JNIEnv *env, int sock, const char *ifname, const struct in_addr *addr, + (JNIEnv *env, const char *ifname, const struct in_addr *addr, unsigned char *buf) { int size; @@ -1586,20 +1592,20 @@ } static int getFlags(int sock, const char *ifname, int *flags) { - struct ifreq if2; - memset((char *)&if2, 0, sizeof(if2)); - strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); + struct ifreq if2; + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); - if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { - return -1; - } + if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { + return -1; + } - if (sizeof(if2.ifr_flags) == sizeof(short)) { - *flags = (if2.ifr_flags & 0xffff); - } else { - *flags = if2.ifr_flags; - } - return 0; + if (sizeof(if2.ifr_flags) == sizeof(short)) { + *flags = (if2.ifr_flags & 0xffff); + } else { + *flags = if2.ifr_flags; + } + return 0; } #endif /* _AIX */ @@ -1834,9 +1840,9 @@ strcpy(style1dev, DEV_PREFIX); strcat(style1dev, ifname); if ((fd = open(style1dev, O_RDWR)) < 0) { - // Can't open it. We probably are missing the privilege. - // We'll have to try something else - return 0; + // Can't open it. We probably are missing the privilege. + // We'll have to try something else + return 0; } dlpareq.dl_primitive = DL_PHYS_ADDR_REQ; @@ -1878,11 +1884,15 @@ * MAC address. Returns -1 if there is no hardware address on that interface. */ static int getMacAddress - (JNIEnv *env, int sock, const char *ifname, const struct in_addr *addr, + (JNIEnv *env, const char *ifname, const struct in_addr *addr, unsigned char *buf) { struct lifreq if2; - int len, i; + int len, i, sock; + + if ((sock = openSocketWithFallback(env, ifname)) < 0) { + return -1; + } // First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails // try the old way. @@ -1893,40 +1903,36 @@ struct sockaddr_dl *sp; sp = (struct sockaddr_dl *)&if2.lifr_addr; memcpy(buf, &sp->sdl_data[0], sp->sdl_alen); + close(sock); return sp->sdl_alen; } // On Solaris we have to use DLPI, but it will only work if we have // privileged access (i.e. root). If that fails, we try a lookup // in the ARP table, which requires an IPv4 address. - if ((len = getMacFromDevice(env, ifname, buf)) == 0) { - // DLPI failed - trying to do arp lookup - + if (((len = getMacFromDevice(env, ifname, buf)) == 0) && (addr != NULL)) { struct arpreq arpreq; struct sockaddr_in *sin; struct sockaddr_in ipAddr; - if (addr == NULL) { - // No IPv4 address for that interface, so can't do an ARP lookup. - return -1; - } + len = 6; //??? - len = 6; //??? + sin = (struct sockaddr_in *)&arpreq.arp_pa; + memset((char *)&arpreq, 0, sizeof(struct arpreq)); + ipAddr.sin_port = 0; + ipAddr.sin_family = AF_INET; + memcpy(&ipAddr.sin_addr, addr, sizeof(struct in_addr)); + memcpy(&arpreq.arp_pa, &ipAddr, sizeof(struct sockaddr_in)); + arpreq.arp_flags= ATF_PUBL; - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset((char *)&arpreq, 0, sizeof(struct arpreq)); - ipAddr.sin_port = 0; - ipAddr.sin_family = AF_INET; - memcpy(&ipAddr.sin_addr, addr, sizeof(struct in_addr)); - memcpy(&arpreq.arp_pa, &ipAddr, sizeof(struct sockaddr_in)); - arpreq.arp_flags= ATF_PUBL; + if (ioctl(sock, SIOCGARP, &arpreq) < 0) { + close(sock); + return -1; + } - if (ioctl(sock, SIOCGARP, &arpreq) < 0) { - return -1; - } - - memcpy(buf, &arpreq.arp_ha.sa_data[0], len); + memcpy(buf, &arpreq.arp_ha.sa_data[0], len); } + close(sock); // all bytes to 0 means no hardware address for (i = 0; i < len; i++) { @@ -2113,22 +2119,22 @@ * MAC address. Returns -1 if there is no hardware address on that interface. */ static int getMacAddress - (JNIEnv *env, int sock, const char *ifname, const struct in_addr *addr, + (JNIEnv *env, const char *ifname, const struct in_addr *addr, unsigned char *buf) { struct ifaddrs *ifa0, *ifa; struct sockaddr *saddr; int i; - // Grab the interface list + // grab the interface list if (!getifaddrs(&ifa0)) { - // Cycle through the interfaces + // cycle through the interfaces for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) { saddr = ifa->ifa_addr; - // Link layer contains the MAC address + // link layer contains the MAC address if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) { struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr; - // Check the address is the correct length + // check the address has the correct length if (sadl->sdl_alen == ETHER_ADDR_LEN) { memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN); freeifaddrs(ifa0);