src/solaris/native/java/net/NetworkInterface.c

Print this page
rev 8822 : 8024854: PPC64: Basic changes and files to build the class library on AIX
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan, art
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com

*** 1,7 **** /* ! * Copyright (c) 2000, 2012, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 50,59 **** --- 50,66 ---- #include <bits/ioctls.h> #include <sys/utsname.h> #include <stdio.h> #endif + #if defined(_AIX) + #include <sys/ioctl.h> + #include <netinet/in6_var.h> + #include <sys/ndd_var.h> + #include <sys/kinfo.h> + #endif + #ifdef __linux__ #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" #endif #if defined(_ALLBSD_SOURCE)
*** 1039,1050 **** return sock; } ! /** Linux **/ ! #ifdef __linux__ /* Open socket for further ioct calls, try v4 socket first and * if it falls return v6 socket */ #ifdef AF_INET6 --- 1046,1057 ---- return sock; } ! /** Linux, AIX **/ ! #if defined(__linux__) || defined(_AIX) /* Open socket for further ioct calls, try v4 socket first and * if it falls return v6 socket */ #ifdef AF_INET6
*** 1078,1115 **** #endif static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) { struct ifconf ifc; struct ifreq *ifreqP; ! char *buf; int numifs; unsigned i; /* need to do a dummy SIOCGIFCONF to determine the buffer size. * SIOCGIFCOUNT doesn't work */ ifc.ifc_buf = NULL; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed"); return ifs; } CHECKED_MALLOC3(buf,char *, ifc.ifc_len); ifc.ifc_buf = buf; ! if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed"); (void) free(buf); return ifs; } /* * Iterate through each interface */ ifreqP = ifc.ifc_req; for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) { /* * Add to the list */ ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0); --- 1085,1137 ---- #endif static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) { struct ifconf ifc; struct ifreq *ifreqP; ! 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 */ ifc.ifc_buf = NULL; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { 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 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; } /* * Iterate through each interface */ ifreqP = ifc.ifc_req; for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) { + #if defined(_AIX) + if (ifreqP->ifr_addr.sa_family != AF_INET) continue; + #endif /* * Add to the list */ ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
*** 1133,1143 **** /* * Enumerates and returns all IPv6 interfaces on Linux */ ! #ifdef AF_INET6 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { FILE *f; char addr6[40], devname[21]; char addr6p[8][5]; int plen, scope, dad_status, if_idx; --- 1155,1165 ---- /* * Enumerates and returns all IPv6 interfaces on Linux */ ! #if defined(AF_INET6) && defined(__linux__) static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { FILE *f; char addr6[40], devname[21]; char addr6p[8][5]; int plen, scope, dad_status, if_idx;
*** 1177,1199 **** 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) */ struct ifreq if2; strcpy(if2.ifr_name, name); if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) { return -1; } return if2.ifr_ifindex; } /** * Returns the IPv4 broadcast address of a named interface, if it exists. * Returns 0 if it doesn't have one. --- 1199,1314 ---- return ifs; } #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 */ + #if defined(_AIX) + return if_nametoindex(name); + #else struct ifreq if2; strcpy(if2.ifr_name, name); if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) { return -1; } return if2.ifr_ifindex; + #endif } /** * Returns the IPv4 broadcast address of a named interface, if it exists. * Returns 0 if it doesn't have one.
*** 1256,1265 **** --- 1371,1420 ---- * Get the Hardware address (usually MAC address) for the named interface. * return puts the data in buf, and returns the length, in byte, of the * 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; strcpy(ifr.ifr_name, ifname); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
*** 1277,1286 **** --- 1432,1442 ---- if (buf[i] != 0) return IFHWADDRLEN; } return -1; + #endif } static int getMTU(JNIEnv *env, int sock, const char *ifname) { struct ifreq if2;