< prev index next >

src/java.base/unix/native/libnet/NetworkInterface.c

Print this page
rev 59383 : [mq]: final

@@ -35,16 +35,10 @@
 #include <sys/ndd_var.h>
 #include <sys/kinfo.h>
 #include <strings.h>
 #endif
 
-#if defined(__solaris__)
-#include <stropts.h>
-#include <sys/dlpi.h>
-#include <sys/sockio.h>
-#endif
-
 #if defined(_ALLBSD_SOURCE)
 #include <net/ethernet.h>
 #include <net/if_dl.h>
 #include <ifaddrs.h>
 #endif

@@ -53,15 +47,10 @@
 
 #include "java_net_InetAddress.h"
 
 #if defined(__linux__)
     #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
-#elif defined(__solaris__)
-    #ifndef SIOCGLIFHWADDR
-        #define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq)
-    #endif
-    #define DEV_PREFIX "/dev/"
 #endif
 
 #ifdef LIFNAMSIZ
     #define IFNAMESIZE LIFNAMSIZ
 #else

@@ -145,15 +134,10 @@
 static int     getFlags(int sock, const char *ifname, int *flags);
 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);
 
-#if defined(__solaris__)
-static int     getMacFromDevice(JNIEnv *env, const char *ifname,
-                                unsigned char *retbuf);
-#endif
-
 /******************* Java entry points *****************************/
 
 /*
  * Class:     java_net_NetworkInterface
  * Method:    init

@@ -1670,376 +1654,10 @@
     return 0;
 }
 
 #endif /* _AIX */
 
-/** Solaris **/
-#if defined(__solaris__)
-
-/*
- * Opens a socket for further ioctl calls. Tries AF_INET socket first and
- * if it fails return AF_INET6 socket.
- */
-static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
-    int sock, alreadyV6 = 0;
-    struct lifreq if2;
-
-    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) {
-            if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-                JNU_ThrowByNameWithMessageAndLastError
-                    (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                return -1;
-            }
-            alreadyV6 = 1;
-        } else { // errno is not NOSUPPORT
-            JNU_ThrowByNameWithMessageAndLastError
-                (env, JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-            return -1;
-        }
-    }
-
-    // Solaris requires that we have an IPv6 socket to query an  interface
-    // without an IPv4 address - check it here. POSIX 1 require the kernel to
-    // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK
-    // for a device having IPv6 only address but not all devices follow the
-    // standard so fall back on any error. It's not an ecologically friendly
-    // gesture but more reliable.
-    if (!alreadyV6) {
-        memset((char *)&if2, 0, sizeof(if2));
-        strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
-        if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-            close(sock);
-            if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-                JNU_ThrowByNameWithMessageAndLastError
-                    (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                return -1;
-            }
-        }
-    }
-
-    return sock;
-}
-
-/*
- * Enumerates and returns all IPv4 interfaces on Solaris.
- */
-static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
-    struct lifconf ifc;
-    struct lifreq *ifreqP;
-    struct lifnum numifs;
-    char *buf = NULL;
-    unsigned i;
-
-    // call SIOCGLIFNUM to get the interface count
-    numifs.lifn_family = AF_INET;
-    numifs.lifn_flags = 0;
-    if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFNUM) failed");
-        return ifs;
-    }
-
-    // call SIOCGLIFCONF to enumerate the interfaces
-    ifc.lifc_len = numifs.lifn_count * sizeof(struct lifreq);
-    CHECKED_MALLOC3(buf, char *, ifc.lifc_len);
-    ifc.lifc_buf = buf;
-    ifc.lifc_family = AF_INET;
-    ifc.lifc_flags = 0;
-    if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFCONF) failed");
-        free(buf);
-        return ifs;
-    }
-
-    // iterate through each interface
-    ifreqP = ifc.lifc_req;
-    for (i = 0; i < numifs.lifn_count; i++, ifreqP++) {
-        struct sockaddr addr, *broadaddrP = NULL;
-
-        // ignore non IPv4 addresses
-        if (ifreqP->lifr_addr.ss_family != AF_INET) {
-            continue;
-        }
-
-        // save socket address
-        memcpy(&addr, &(ifreqP->lifr_addr), sizeof(struct sockaddr));
-
-        // determine broadcast address, if applicable
-        if ((ioctl(sock, SIOCGLIFFLAGS, ifreqP) == 0) &&
-            ifreqP->lifr_flags & IFF_BROADCAST) {
-
-            // restore socket address to ifreqP
-            memcpy(&(ifreqP->lifr_addr), &addr, sizeof(struct sockaddr));
-
-            // query broadcast address and set pointer to it
-            if (ioctl(sock, SIOCGLIFBRDADDR, ifreqP) == 0) {
-                broadaddrP = (struct sockaddr *)&(ifreqP->lifr_broadaddr);
-            }
-        }
-
-        // add to the list
-        ifs = addif(env, sock, ifreqP->lifr_name, ifs,
-                    &addr, broadaddrP, AF_INET, (short)ifreqP->lifr_addrlen);
-
-        // if an exception occurred we return immediately
-        if ((*env)->ExceptionOccurred(env)) {
-            free(buf);
-            return ifs;
-        }
-   }
-
-    // free buffer
-    free(buf);
-    return ifs;
-}
-
-/*
- * Enumerates and returns all IPv6 interfaces on Solaris.
- */
-static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
-    struct lifconf ifc;
-    struct lifreq *ifreqP;
-    struct lifnum numifs;
-    char *buf = NULL;
-    unsigned i;
-
-    // call SIOCGLIFNUM to get the interface count
-    numifs.lifn_family = AF_INET6;
-    numifs.lifn_flags = 0;
-    if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFNUM) failed");
-        return ifs;
-    }
-
-    // call SIOCGLIFCONF to enumerate the interfaces
-    ifc.lifc_len = numifs.lifn_count * sizeof(struct lifreq);
-    CHECKED_MALLOC3(buf, char *, ifc.lifc_len);
-    ifc.lifc_buf = buf;
-    ifc.lifc_family = AF_INET6;
-    ifc.lifc_flags = 0;
-    if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFCONF) failed");
-        free(buf);
-        return ifs;
-    }
-
-    // iterate through each interface
-    ifreqP = ifc.lifc_req;
-    for (i = 0; i < numifs.lifn_count; i++, ifreqP++) {
-
-        // ignore non IPv6 addresses
-        if (ifreqP->lifr_addr.ss_family != AF_INET6) {
-            continue;
-        }
-
-        // set scope ID to interface index
-        ((struct sockaddr_in6 *)&(ifreqP->lifr_addr))->sin6_scope_id =
-            getIndex(sock, ifreqP->lifr_name);
-
-        // add to the list
-        ifs = addif(env, sock, ifreqP->lifr_name, ifs,
-                    (struct sockaddr *)&(ifreqP->lifr_addr),
-                    NULL, AF_INET6, (short)ifreqP->lifr_addrlen);
-
-        // if an exception occurred we return immediately
-        if ((*env)->ExceptionOccurred(env)) {
-            free(buf);
-            return ifs;
-        }
-    }
-
-    // free buffer
-    free(buf);
-    return ifs;
-}
-
-/*
- * Try to get the interface index.
- * (Not supported on Solaris 2.6 or 7)
- */
-static int getIndex(int sock, const char *name) {
-    struct lifreq if2;
-    memset((char *)&if2, 0, sizeof(if2));
-    strncpy(if2.lifr_name, name, sizeof(if2.lifr_name) - 1);
-
-    if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) {
-        return -1;
-    }
-
-    return if2.lifr_index;
-}
-
-/*
- * Solaris specific DLPI code to get hardware address from a device.
- * Unfortunately, at least up to Solaris X, you have to have special
- * privileges (i.e. be root).
- */
-static int getMacFromDevice
-  (JNIEnv *env, const char *ifname, unsigned char *retbuf)
-{
-    char style1dev[MAXPATHLEN];
-    int fd;
-    dl_phys_addr_req_t dlpareq;
-    dl_phys_addr_ack_t *dlpaack;
-    dl_error_ack_t     *dlerack;
-    struct strbuf msg;
-    char buf[128];
-    int flags = 0;
-
-    // Device is in /dev.  e.g.: /dev/bge0
-    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;
-    }
-
-    dlpareq.dl_primitive = DL_PHYS_ADDR_REQ;
-    dlpareq.dl_addr_type = DL_CURR_PHYS_ADDR;
-
-    msg.buf = (char *)&dlpareq;
-    msg.len = DL_PHYS_ADDR_REQ_SIZE;
-
-    if (putmsg(fd, &msg, NULL, 0) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "putmsg() failed");
-        return -1;
-    }
-
-    dlpaack = (dl_phys_addr_ack_t *)buf;
-
-    msg.buf = (char *)buf;
-    msg.len = 0;
-    msg.maxlen = sizeof (buf);
-    if (getmsg(fd, &msg, NULL, &flags) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "getmsg() failed");
-        return -1;
-    }
-
-    if (dlpaack->dl_primitive == DL_ERROR_ACK) {
-        dlerack = (dl_error_ack_t *)buf;
-        if (dlerack->dl_error_primitive != DL_PHYS_ADDR_REQ) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                           "Couldn't obtain physical address\n");
-            return -1;
-        }
-        if (dlerack->dl_errno == DL_UNSUPPORTED) {
-            // fallback to lookup in the ARP table
-            return 0;
-        }
-    }
-
-    if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Couldn't obtain phys addr\n");
-        return -1;
-    }
-
-    memcpy(retbuf, &buf[dlpaack->dl_addr_offset], dlpaack->dl_addr_length);
-    return dlpaack->dl_addr_length;
-}
-
-/*
- * Gets the Hardware address (usually MAC address) for the named interface.
- * On 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, const char *ifname, const struct in_addr *addr,
-   unsigned char *buf)
-{
-    struct lifreq if2;
-    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.
-    memset((char *)&if2, 0, sizeof(if2));
-    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
-
-    if (ioctl(sock, SIOCGLIFHWADDR, &if2) != -1) {
-        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) && (addr != NULL)) {
-        struct arpreq arpreq;
-        struct sockaddr_in *sin;
-        struct sockaddr_in ipAddr;
-
-        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;
-
-        if (ioctl(sock, SIOCGARP, &arpreq) < 0) {
-            close(sock);
-            return -1;
-        }
-
-        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++) {
-        if (buf[i] != 0)
-            return len;
-    }
-
-    return -1;
-}
-
-static int getMTU(JNIEnv *env, int sock, const char *ifname) {
-    struct lifreq if2;
-    memset((char *)&if2, 0, sizeof(if2));
-    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
-
-    if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) {
-        JNU_ThrowByNameWithMessageAndLastError
-            (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFMTU) failed");
-        return -1;
-    }
-
-    return if2.lifr_mtu;
-}
-
-static int getFlags(int sock, const char *ifname, int *flags) {
-    struct lifreq if2;
-    memset((char *)&if2, 0, sizeof(if2));
-    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
-
-    if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) {
-        return -1;
-    }
-
-    *flags = if2.lifr_flags;
-    return 0;
-}
-
-#endif /* __solaris__ */
-
 /** BSD **/
 #if defined(_ALLBSD_SOURCE)
 
 /*
  * Opens a socket for further ioctl calls. Tries AF_INET socket first and
< prev index next >