20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 #include <arpa/inet.h>
26 #include <errno.h>
27 #include <net/if.h>
28 #include <net/if_arp.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/ioctl.h>
32
33 #if defined(_AIX)
34 #include <netinet/in6_var.h>
35 #include <sys/ndd_var.h>
36 #include <sys/kinfo.h>
37 #include <strings.h>
38 #endif
39
40 #if defined(__solaris__)
41 #include <stropts.h>
42 #include <sys/dlpi.h>
43 #include <sys/sockio.h>
44 #endif
45
46 #if defined(_ALLBSD_SOURCE)
47 #include <net/ethernet.h>
48 #include <net/if_dl.h>
49 #include <ifaddrs.h>
50 #endif
51
52 #include "net_util.h"
53
54 #include "java_net_InetAddress.h"
55
56 #if defined(__linux__)
57 #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
58 #elif defined(__solaris__)
59 #ifndef SIOCGLIFHWADDR
60 #define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq)
61 #endif
62 #define DEV_PREFIX "/dev/"
63 #endif
64
65 #ifdef LIFNAMSIZ
66 #define IFNAMESIZE LIFNAMSIZ
67 #else
68 #define IFNAMESIZE IFNAMSIZ
69 #endif
70
71 #define CHECKED_MALLOC3(_pointer, _type, _size) \
72 do { \
73 _pointer = (_type)malloc(_size); \
74 if (_pointer == NULL) { \
75 JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
76 return ifs; /* return untouched list */ \
77 } \
78 } while(0)
79
80 typedef struct _netaddr {
81 struct sockaddr *addr;
82 struct sockaddr *brdcast;
130 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
131
132 static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
133 struct sockaddr *ifr_addrP,
134 struct sockaddr *ifr_broadaddrP,
135 int family, short prefix);
136 static void freeif(netif *ifs);
137
138 static int openSocket(JNIEnv *env, int proto);
139 static int openSocketWithFallback(JNIEnv *env, const char *ifname);
140
141 static short translateIPv4AddressToPrefix(struct sockaddr_in *addr);
142 static short translateIPv6AddressToPrefix(struct sockaddr_in6 *addr);
143
144 static int getIndex(int sock, const char *ifname);
145 static int getFlags(int sock, const char *ifname, int *flags);
146 static int getMacAddress(JNIEnv *env, const char *ifname,
147 const struct in_addr *addr, unsigned char *buf);
148 static int getMTU(JNIEnv *env, int sock, const char *ifname);
149
150 #if defined(__solaris__)
151 static int getMacFromDevice(JNIEnv *env, const char *ifname,
152 unsigned char *retbuf);
153 #endif
154
155 /******************* Java entry points *****************************/
156
157 /*
158 * Class: java_net_NetworkInterface
159 * Method: init
160 * Signature: ()V
161 */
162 JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init
163 (JNIEnv *env, jclass cls)
164 {
165 ni_class = (*env)->FindClass(env, "java/net/NetworkInterface");
166 CHECK_NULL(ni_class);
167 ni_class = (*env)->NewGlobalRef(env, ni_class);
168 CHECK_NULL(ni_class);
169 ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
170 CHECK_NULL(ni_nameID);
171 ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
172 CHECK_NULL(ni_indexID);
173 ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs",
174 "[Ljava/net/InetAddress;");
1654 }
1655
1656 static int getFlags(int sock, const char *ifname, int *flags) {
1657 struct ifreq if2;
1658 memset((char *)&if2, 0, sizeof(if2));
1659 strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
1660
1661 if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
1662 return -1;
1663 }
1664
1665 if (sizeof(if2.ifr_flags) == sizeof(short)) {
1666 *flags = (if2.ifr_flags & 0xffff);
1667 } else {
1668 *flags = if2.ifr_flags;
1669 }
1670 return 0;
1671 }
1672
1673 #endif /* _AIX */
1674
1675 /** Solaris **/
1676 #if defined(__solaris__)
1677
1678 /*
1679 * Opens a socket for further ioctl calls. Tries AF_INET socket first and
1680 * if it fails return AF_INET6 socket.
1681 */
1682 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1683 int sock, alreadyV6 = 0;
1684 struct lifreq if2;
1685
1686 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1687 if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) {
1688 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1689 JNU_ThrowByNameWithMessageAndLastError
1690 (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
1691 return -1;
1692 }
1693 alreadyV6 = 1;
1694 } else { // errno is not NOSUPPORT
1695 JNU_ThrowByNameWithMessageAndLastError
1696 (env, JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
1697 return -1;
1698 }
1699 }
1700
1701 // Solaris requires that we have an IPv6 socket to query an interface
1702 // without an IPv4 address - check it here. POSIX 1 require the kernel to
1703 // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK
1704 // for a device having IPv6 only address but not all devices follow the
1705 // standard so fall back on any error. It's not an ecologically friendly
1706 // gesture but more reliable.
1707 if (!alreadyV6) {
1708 memset((char *)&if2, 0, sizeof(if2));
1709 strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
1710 if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
1711 close(sock);
1712 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1713 JNU_ThrowByNameWithMessageAndLastError
1714 (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
1715 return -1;
1716 }
1717 }
1718 }
1719
1720 return sock;
1721 }
1722
1723 /*
1724 * Enumerates and returns all IPv4 interfaces on Solaris.
1725 */
1726 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
1727 struct lifconf ifc;
1728 struct lifreq *ifreqP;
1729 struct lifnum numifs;
1730 char *buf = NULL;
1731 unsigned i;
1732
1733 // call SIOCGLIFNUM to get the interface count
1734 numifs.lifn_family = AF_INET;
1735 numifs.lifn_flags = 0;
1736 if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
1737 JNU_ThrowByNameWithMessageAndLastError
1738 (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFNUM) failed");
1739 return ifs;
1740 }
1741
1742 // call SIOCGLIFCONF to enumerate the interfaces
1743 ifc.lifc_len = numifs.lifn_count * sizeof(struct lifreq);
1744 CHECKED_MALLOC3(buf, char *, ifc.lifc_len);
1745 ifc.lifc_buf = buf;
1746 ifc.lifc_family = AF_INET;
1747 ifc.lifc_flags = 0;
1748 if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
1749 JNU_ThrowByNameWithMessageAndLastError
1750 (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFCONF) failed");
1751 free(buf);
1752 return ifs;
1753 }
1754
1755 // iterate through each interface
1756 ifreqP = ifc.lifc_req;
1757 for (i = 0; i < numifs.lifn_count; i++, ifreqP++) {
1758 struct sockaddr addr, *broadaddrP = NULL;
1759
1760 // ignore non IPv4 addresses
1761 if (ifreqP->lifr_addr.ss_family != AF_INET) {
1762 continue;
1763 }
1764
1765 // save socket address
1766 memcpy(&addr, &(ifreqP->lifr_addr), sizeof(struct sockaddr));
1767
1768 // determine broadcast address, if applicable
1769 if ((ioctl(sock, SIOCGLIFFLAGS, ifreqP) == 0) &&
1770 ifreqP->lifr_flags & IFF_BROADCAST) {
1771
1772 // restore socket address to ifreqP
1773 memcpy(&(ifreqP->lifr_addr), &addr, sizeof(struct sockaddr));
1774
1775 // query broadcast address and set pointer to it
1776 if (ioctl(sock, SIOCGLIFBRDADDR, ifreqP) == 0) {
1777 broadaddrP = (struct sockaddr *)&(ifreqP->lifr_broadaddr);
1778 }
1779 }
1780
1781 // add to the list
1782 ifs = addif(env, sock, ifreqP->lifr_name, ifs,
1783 &addr, broadaddrP, AF_INET, (short)ifreqP->lifr_addrlen);
1784
1785 // if an exception occurred we return immediately
1786 if ((*env)->ExceptionOccurred(env)) {
1787 free(buf);
1788 return ifs;
1789 }
1790 }
1791
1792 // free buffer
1793 free(buf);
1794 return ifs;
1795 }
1796
1797 /*
1798 * Enumerates and returns all IPv6 interfaces on Solaris.
1799 */
1800 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
1801 struct lifconf ifc;
1802 struct lifreq *ifreqP;
1803 struct lifnum numifs;
1804 char *buf = NULL;
1805 unsigned i;
1806
1807 // call SIOCGLIFNUM to get the interface count
1808 numifs.lifn_family = AF_INET6;
1809 numifs.lifn_flags = 0;
1810 if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
1811 JNU_ThrowByNameWithMessageAndLastError
1812 (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFNUM) failed");
1813 return ifs;
1814 }
1815
1816 // call SIOCGLIFCONF to enumerate the interfaces
1817 ifc.lifc_len = numifs.lifn_count * sizeof(struct lifreq);
1818 CHECKED_MALLOC3(buf, char *, ifc.lifc_len);
1819 ifc.lifc_buf = buf;
1820 ifc.lifc_family = AF_INET6;
1821 ifc.lifc_flags = 0;
1822 if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
1823 JNU_ThrowByNameWithMessageAndLastError
1824 (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFCONF) failed");
1825 free(buf);
1826 return ifs;
1827 }
1828
1829 // iterate through each interface
1830 ifreqP = ifc.lifc_req;
1831 for (i = 0; i < numifs.lifn_count; i++, ifreqP++) {
1832
1833 // ignore non IPv6 addresses
1834 if (ifreqP->lifr_addr.ss_family != AF_INET6) {
1835 continue;
1836 }
1837
1838 // set scope ID to interface index
1839 ((struct sockaddr_in6 *)&(ifreqP->lifr_addr))->sin6_scope_id =
1840 getIndex(sock, ifreqP->lifr_name);
1841
1842 // add to the list
1843 ifs = addif(env, sock, ifreqP->lifr_name, ifs,
1844 (struct sockaddr *)&(ifreqP->lifr_addr),
1845 NULL, AF_INET6, (short)ifreqP->lifr_addrlen);
1846
1847 // if an exception occurred we return immediately
1848 if ((*env)->ExceptionOccurred(env)) {
1849 free(buf);
1850 return ifs;
1851 }
1852 }
1853
1854 // free buffer
1855 free(buf);
1856 return ifs;
1857 }
1858
1859 /*
1860 * Try to get the interface index.
1861 * (Not supported on Solaris 2.6 or 7)
1862 */
1863 static int getIndex(int sock, const char *name) {
1864 struct lifreq if2;
1865 memset((char *)&if2, 0, sizeof(if2));
1866 strncpy(if2.lifr_name, name, sizeof(if2.lifr_name) - 1);
1867
1868 if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) {
1869 return -1;
1870 }
1871
1872 return if2.lifr_index;
1873 }
1874
1875 /*
1876 * Solaris specific DLPI code to get hardware address from a device.
1877 * Unfortunately, at least up to Solaris X, you have to have special
1878 * privileges (i.e. be root).
1879 */
1880 static int getMacFromDevice
1881 (JNIEnv *env, const char *ifname, unsigned char *retbuf)
1882 {
1883 char style1dev[MAXPATHLEN];
1884 int fd;
1885 dl_phys_addr_req_t dlpareq;
1886 dl_phys_addr_ack_t *dlpaack;
1887 dl_error_ack_t *dlerack;
1888 struct strbuf msg;
1889 char buf[128];
1890 int flags = 0;
1891
1892 // Device is in /dev. e.g.: /dev/bge0
1893 strcpy(style1dev, DEV_PREFIX);
1894 strcat(style1dev, ifname);
1895 if ((fd = open(style1dev, O_RDWR)) < 0) {
1896 // Can't open it. We probably are missing the privilege.
1897 // We'll have to try something else
1898 return 0;
1899 }
1900
1901 dlpareq.dl_primitive = DL_PHYS_ADDR_REQ;
1902 dlpareq.dl_addr_type = DL_CURR_PHYS_ADDR;
1903
1904 msg.buf = (char *)&dlpareq;
1905 msg.len = DL_PHYS_ADDR_REQ_SIZE;
1906
1907 if (putmsg(fd, &msg, NULL, 0) < 0) {
1908 JNU_ThrowByNameWithMessageAndLastError
1909 (env, JNU_JAVANETPKG "SocketException", "putmsg() failed");
1910 return -1;
1911 }
1912
1913 dlpaack = (dl_phys_addr_ack_t *)buf;
1914
1915 msg.buf = (char *)buf;
1916 msg.len = 0;
1917 msg.maxlen = sizeof (buf);
1918 if (getmsg(fd, &msg, NULL, &flags) < 0) {
1919 JNU_ThrowByNameWithMessageAndLastError
1920 (env, JNU_JAVANETPKG "SocketException", "getmsg() failed");
1921 return -1;
1922 }
1923
1924 if (dlpaack->dl_primitive == DL_ERROR_ACK) {
1925 dlerack = (dl_error_ack_t *)buf;
1926 if (dlerack->dl_error_primitive != DL_PHYS_ADDR_REQ) {
1927 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1928 "Couldn't obtain physical address\n");
1929 return -1;
1930 }
1931 if (dlerack->dl_errno == DL_UNSUPPORTED) {
1932 // fallback to lookup in the ARP table
1933 return 0;
1934 }
1935 }
1936
1937 if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
1938 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1939 "Couldn't obtain phys addr\n");
1940 return -1;
1941 }
1942
1943 memcpy(retbuf, &buf[dlpaack->dl_addr_offset], dlpaack->dl_addr_length);
1944 return dlpaack->dl_addr_length;
1945 }
1946
1947 /*
1948 * Gets the Hardware address (usually MAC address) for the named interface.
1949 * On return puts the data in buf, and returns the length, in byte, of the
1950 * MAC address. Returns -1 if there is no hardware address on that interface.
1951 */
1952 static int getMacAddress
1953 (JNIEnv *env, const char *ifname, const struct in_addr *addr,
1954 unsigned char *buf)
1955 {
1956 struct lifreq if2;
1957 int len, i, sock;
1958
1959 if ((sock = openSocketWithFallback(env, ifname)) < 0) {
1960 return -1;
1961 }
1962
1963 // First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
1964 // try the old way.
1965 memset((char *)&if2, 0, sizeof(if2));
1966 strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
1967
1968 if (ioctl(sock, SIOCGLIFHWADDR, &if2) != -1) {
1969 struct sockaddr_dl *sp;
1970 sp = (struct sockaddr_dl *)&if2.lifr_addr;
1971 memcpy(buf, &sp->sdl_data[0], sp->sdl_alen);
1972 close(sock);
1973 return sp->sdl_alen;
1974 }
1975
1976 // On Solaris we have to use DLPI, but it will only work if we have
1977 // privileged access (i.e. root). If that fails, we try a lookup
1978 // in the ARP table, which requires an IPv4 address.
1979 if (((len = getMacFromDevice(env, ifname, buf)) == 0) && (addr != NULL)) {
1980 struct arpreq arpreq;
1981 struct sockaddr_in *sin;
1982 struct sockaddr_in ipAddr;
1983
1984 len = 6; //???
1985
1986 sin = (struct sockaddr_in *)&arpreq.arp_pa;
1987 memset((char *)&arpreq, 0, sizeof(struct arpreq));
1988 ipAddr.sin_port = 0;
1989 ipAddr.sin_family = AF_INET;
1990 memcpy(&ipAddr.sin_addr, addr, sizeof(struct in_addr));
1991 memcpy(&arpreq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
1992 arpreq.arp_flags= ATF_PUBL;
1993
1994 if (ioctl(sock, SIOCGARP, &arpreq) < 0) {
1995 close(sock);
1996 return -1;
1997 }
1998
1999 memcpy(buf, &arpreq.arp_ha.sa_data[0], len);
2000 }
2001 close(sock);
2002
2003 // all bytes to 0 means no hardware address
2004 for (i = 0; i < len; i++) {
2005 if (buf[i] != 0)
2006 return len;
2007 }
2008
2009 return -1;
2010 }
2011
2012 static int getMTU(JNIEnv *env, int sock, const char *ifname) {
2013 struct lifreq if2;
2014 memset((char *)&if2, 0, sizeof(if2));
2015 strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
2016
2017 if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) {
2018 JNU_ThrowByNameWithMessageAndLastError
2019 (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFMTU) failed");
2020 return -1;
2021 }
2022
2023 return if2.lifr_mtu;
2024 }
2025
2026 static int getFlags(int sock, const char *ifname, int *flags) {
2027 struct lifreq if2;
2028 memset((char *)&if2, 0, sizeof(if2));
2029 strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
2030
2031 if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) {
2032 return -1;
2033 }
2034
2035 *flags = if2.lifr_flags;
2036 return 0;
2037 }
2038
2039 #endif /* __solaris__ */
2040
2041 /** BSD **/
2042 #if defined(_ALLBSD_SOURCE)
2043
2044 /*
2045 * Opens a socket for further ioctl calls. Tries AF_INET socket first and
2046 * if it fails return AF_INET6 socket.
2047 */
2048 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
2049 int sock;
2050
2051 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2052 if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) {
2053 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
2054 JNU_ThrowByNameWithMessageAndLastError
2055 (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
2056 return -1;
2057 }
2058 } else { // errno is not NOSUPPORT
2059 JNU_ThrowByNameWithMessageAndLastError
|
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 #include <arpa/inet.h>
26 #include <errno.h>
27 #include <net/if.h>
28 #include <net/if_arp.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/ioctl.h>
32
33 #if defined(_AIX)
34 #include <netinet/in6_var.h>
35 #include <sys/ndd_var.h>
36 #include <sys/kinfo.h>
37 #include <strings.h>
38 #endif
39
40 #if defined(_ALLBSD_SOURCE)
41 #include <net/ethernet.h>
42 #include <net/if_dl.h>
43 #include <ifaddrs.h>
44 #endif
45
46 #include "net_util.h"
47
48 #include "java_net_InetAddress.h"
49
50 #if defined(__linux__)
51 #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
52 #endif
53
54 #ifdef LIFNAMSIZ
55 #define IFNAMESIZE LIFNAMSIZ
56 #else
57 #define IFNAMESIZE IFNAMSIZ
58 #endif
59
60 #define CHECKED_MALLOC3(_pointer, _type, _size) \
61 do { \
62 _pointer = (_type)malloc(_size); \
63 if (_pointer == NULL) { \
64 JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
65 return ifs; /* return untouched list */ \
66 } \
67 } while(0)
68
69 typedef struct _netaddr {
70 struct sockaddr *addr;
71 struct sockaddr *brdcast;
119 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
120
121 static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
122 struct sockaddr *ifr_addrP,
123 struct sockaddr *ifr_broadaddrP,
124 int family, short prefix);
125 static void freeif(netif *ifs);
126
127 static int openSocket(JNIEnv *env, int proto);
128 static int openSocketWithFallback(JNIEnv *env, const char *ifname);
129
130 static short translateIPv4AddressToPrefix(struct sockaddr_in *addr);
131 static short translateIPv6AddressToPrefix(struct sockaddr_in6 *addr);
132
133 static int getIndex(int sock, const char *ifname);
134 static int getFlags(int sock, const char *ifname, int *flags);
135 static int getMacAddress(JNIEnv *env, const char *ifname,
136 const struct in_addr *addr, unsigned char *buf);
137 static int getMTU(JNIEnv *env, int sock, const char *ifname);
138
139 /******************* Java entry points *****************************/
140
141 /*
142 * Class: java_net_NetworkInterface
143 * Method: init
144 * Signature: ()V
145 */
146 JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init
147 (JNIEnv *env, jclass cls)
148 {
149 ni_class = (*env)->FindClass(env, "java/net/NetworkInterface");
150 CHECK_NULL(ni_class);
151 ni_class = (*env)->NewGlobalRef(env, ni_class);
152 CHECK_NULL(ni_class);
153 ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
154 CHECK_NULL(ni_nameID);
155 ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
156 CHECK_NULL(ni_indexID);
157 ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs",
158 "[Ljava/net/InetAddress;");
1638 }
1639
1640 static int getFlags(int sock, const char *ifname, int *flags) {
1641 struct ifreq if2;
1642 memset((char *)&if2, 0, sizeof(if2));
1643 strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
1644
1645 if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
1646 return -1;
1647 }
1648
1649 if (sizeof(if2.ifr_flags) == sizeof(short)) {
1650 *flags = (if2.ifr_flags & 0xffff);
1651 } else {
1652 *flags = if2.ifr_flags;
1653 }
1654 return 0;
1655 }
1656
1657 #endif /* _AIX */
1658
1659 /** BSD **/
1660 #if defined(_ALLBSD_SOURCE)
1661
1662 /*
1663 * Opens a socket for further ioctl calls. Tries AF_INET socket first and
1664 * if it fails return AF_INET6 socket.
1665 */
1666 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1667 int sock;
1668
1669 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1670 if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) {
1671 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1672 JNU_ThrowByNameWithMessageAndLastError
1673 (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
1674 return -1;
1675 }
1676 } else { // errno is not NOSUPPORT
1677 JNU_ThrowByNameWithMessageAndLastError
|