diff -r 62542b8be764 -r 7515a991bb37 jdk/src/solaris/native/java/net/NetworkInterface.c --- a/jdk/src/solaris/native/java/net/NetworkInterface.c Thu Nov 21 12:28:16 2013 -0800 +++ b/jdk/src/solaris/native/java/net/NetworkInterface.c Tue Nov 26 16:40:31 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,13 @@ #include #endif +#if defined(_AIX) +#include +#include +#include +#include +#endif + #ifdef __linux__ #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" #endif @@ -1041,8 +1048,8 @@ } -/** Linux **/ -#ifdef __linux__ +/** Linux, AIX **/ +#if defined(__linux__) || defined(_AIX) /* Open socket for further ioct calls, try v4 socket first and * if it falls return v6 socket */ @@ -1080,11 +1087,13 @@ static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) { struct ifconf ifc; struct ifreq *ifreqP; - char *buf; + char *buf = NULL; int numifs; unsigned i; + int siocgifconfRequest = SIOCGIFCONF; +#if defined(__linux__) /* need to do a dummy SIOCGIFCONF to determine the buffer size. * SIOCGIFCOUNT doesn't work */ @@ -1093,11 +1102,21 @@ NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed"); return ifs; } +#elif defined(_AIX) + ifc.ifc_buf = NULL; + if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) { + NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGSIZIFCONF failed"); + return ifs; + } +#endif /* __linux__ */ CHECKED_MALLOC3(buf,char *, ifc.ifc_len); ifc.ifc_buf = buf; - if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { +#if defined(_AIX) + siocgifconfRequest = CSIOCGIFCONF; +#endif + if (ioctl(sock, siocgifconfRequest, (char *)&ifc) < 0) { NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed"); (void) free(buf); return ifs; @@ -1108,6 +1127,9 @@ */ ifreqP = ifc.ifc_req; for (i=0; iifr_addr.sa_family != AF_INET) continue; +#endif /* * Add to the list */ @@ -1135,7 +1157,7 @@ * Enumerates and returns all IPv6 interfaces on Linux */ -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(__linux__) static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { FILE *f; char addr6[40], devname[21]; @@ -1179,11 +1201,103 @@ #endif +/* + * Enumerates and returns all IPv6 interfaces on AIX + */ + +#if defined(AF_INET6) && defined(_AIX) +static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { + struct ifconf ifc; + struct ifreq *ifreqP; + char *buf; + int numifs; + unsigned i; + unsigned bufsize; + char *cp, *cplimit; + + /* use SIOCGSIZIFCONF to get size for SIOCGIFCONF */ + + ifc.ifc_buf = NULL; + if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) { + NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", + "ioctl SIOCGSIZIFCONF failed"); + return ifs; + } + bufsize = ifc.ifc_len; + + buf = (char *)malloc(bufsize); + if (!buf) { + JNU_ThrowOutOfMemoryError(env, "Network interface native buffer allocation failed"); + return ifs; + } + ifc.ifc_len = bufsize; + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { + NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", + "ioctl CSIOCGIFCONF failed"); + free(buf); + return ifs; + } + + /* + * Iterate through each interface + */ + ifreqP = ifc.ifc_req; + cp = (char *)ifc.ifc_req; + cplimit = cp + ifc.ifc_len; + + for ( ; cp < cplimit; cp += (sizeof(ifreqP->ifr_name) + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) { + ifreqP = (struct ifreq *)cp; + struct ifreq if2; + + memset((char *)&if2, 0, sizeof(if2)); + strcpy(if2.ifr_name, ifreqP->ifr_name); + + /* + * Skip interface that aren't UP + */ + if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) { + if (!(if2.ifr_flags & IFF_UP)) { + continue; + } + } + + if (ifreqP->ifr_addr.sa_family != AF_INET6) + continue; + + /* + * Add to the list + */ + ifs = addif(env, sock, ifreqP->ifr_name, ifs, + (struct sockaddr *)&(ifreqP->ifr_addr), + AF_INET6, 0); + + /* + * If an exception occurred then free the list + */ + if ((*env)->ExceptionOccurred(env)) { + free(buf); + freeif(ifs); + return NULL; + } + } + + /* + * Free socket and buffer + */ + free(buf); + return ifs; +} +#endif + + static int getIndex(int sock, const char *name){ /* * Try to get the interface index - * (Not supported on Solaris 2.6 or 7) */ +#if defined(_AIX) + return if_nametoindex(name); +#else struct ifreq if2; strcpy(if2.ifr_name, name); @@ -1192,6 +1306,7 @@ } return if2.ifr_ifindex; +#endif } /** @@ -1258,6 +1373,46 @@ * 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, unsigned char *buf) { +#if defined (_AIX) + int size; + struct kinfo_ndd *nddp; + void *end; + + size = getkerninfo(KINFO_NDD, 0, 0, 0); + if (size == 0) { + return -1; + } + + if (size < 0) { + perror("getkerninfo 1"); + return -1; + } + + nddp = (struct kinfo_ndd *)malloc(size); + + if (!nddp) { + return -1; + } + + if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) { + perror("getkerninfo 2"); + return -1; + } + + end = (void *)nddp + size; + while ((void *)nddp < end) { + if (!strcmp(nddp->ndd_alias, ifname) || + !strcmp(nddp->ndd_name, ifname)) { + bcopy(nddp->ndd_addr, buf, 6); + return 6; + } else { + nddp++; + } + } + + return -1; + +#elif defined(__linux__) static struct ifreq ifr; int i; @@ -1279,6 +1434,7 @@ } return -1; +#endif } static int getMTU(JNIEnv *env, int sock, const char *ifname) {