src/solaris/native/java/net/NetworkInterface.c
Print this page
rev 8725 : 8024854: Basic changes and files to build the class library on AIX
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan
*** 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;