1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
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
1696 ni_class = (*env)->NewGlobalRef(env, c);
1697 CHECK_NULL(ni_class);
1698 }
1699
1700 value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
1701 if (value == NULL) {
1702 if (!(*env)->ExceptionOccurred(env)) {
1703 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1704 "bad argument for IP_MULTICAST_IF"
1705 ": address not bound to any interface");
1706 }
1707 return;
1708 }
1709 opt = java_net_SocketOptions_IP_MULTICAST_IF2;
1710 } else {
1711 struct in_addr in;
1712
1713 in.s_addr = htonl(getInetAddress_addr(env, value));
1714 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1715 (const char*)&in, sizeof(in)) < 0) {
1716 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1717 "Error setting socket option");
1718 }
1719 return;
1720 }
1721 }
1722
1723 if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1724 /*
1725 * value is a NetworkInterface.
1726 * On IPv6 system get the index of the interface and use the
1727 * IPV6_MULTICAST_IF socket option
1728 * On IPv4 system extract addr[0] and use the IP_MULTICAST_IF
1729 * option. For IPv6 both must be done.
1730 */
1731 if (ipv6_supported) {
1732 static jfieldID ni_indexID;
1733 struct in_addr in;
1734 int index;
1735
1736 if (ni_indexID == NULL) {
1737 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
1738 CHECK_NULL(c);
1739 ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
1740 CHECK_NULL(ni_indexID);
1741 }
1742 index = (*env)->GetIntField(env, value, ni_indexID);
1743
1744 if ( isAdapterIpv6Enabled(env, index) != 0 ) {
1745 if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1746 (const char*)&index, sizeof(index)) < 0) {
1747 if (errno == EINVAL && index > 0) {
1748 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1749 "IPV6_MULTICAST_IF failed (interface has IPv4 "
1750 "address only?)");
1751 } else {
1752 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1753 "Error setting socket option");
1754 }
1755 return;
1756 }
1757 }
1758 /* If there are any IPv4 addresses on this interface then
1759 * repeat the operation on the IPv4 fd */
1760
1761 if (getInet4AddrFromIf (env, value, &in) < 0) {
1762 return;
1763 }
1764 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1765 (const char*)&in, sizeof(in)) < 0) {
1766 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1767 "Error setting socket option");
1768 }
1769 return;
1770 } else {
1771 struct in_addr in;
1772
1773 if (getInet4AddrFromIf (env, value, &in) < 0) {
1774 if ((*env)->ExceptionOccurred(env)) {
1775 return;
1776 }
1777 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1778 "no InetAddress instances of requested type");
1779 return;
1780 }
1781
1782 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1783 (const char*)&in, sizeof(in)) < 0) {
1784 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1785 "Error setting socket option");
1786 }
1787 return;
1788 }
1789 }
1790 }
1791
1792 /*
1793 * Class: java_net_TwoStacksPlainDatagramSocketImpl
1794 * Method: socketNativeSetOption
1795 * Signature: (ILjava/lang/Object;)V
1796 */
1797 JNIEXPORT void JNICALL
1798 Java_java_net_TwoStacksPlainDatagramSocketImpl_socketNativeSetOption(JNIEnv *env,jobject this,
1799 jint opt,jobject value) {
1800
1801 int fd=-1, fd1=-1;
1802 int levelv4 = 0, levelv6 = 0, optnamev4 = 0, optnamev6 = 0, optlen = 0;
1803 union {
1804 int i;
1805 char c;
1915 * ipv4Mode == 0, the context is IPV6 processing
1916 *
1917 */
1918 static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint opt, int ipv4Mode) {
1919 static jclass inet4_class;
1920 static jmethodID inet4_ctrID;
1921
1922 static jclass ni_class; static jmethodID ni_ctrID;
1923 static jfieldID ni_indexID;
1924 static jfieldID ni_addrsID;
1925
1926 jobjectArray addrArray;
1927 jobject addr;
1928 jobject ni;
1929
1930 struct in_addr in;
1931 struct in_addr *inP = ∈
1932 int len = sizeof(struct in_addr);
1933 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1934 (char *)inP, &len) < 0) {
1935 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1936 "Error getting socket option");
1937 return NULL;
1938 }
1939
1940 /*
1941 * Construct and populate an Inet4Address
1942 */
1943 if (inet4_class == NULL) {
1944 jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
1945 CHECK_NULL_RETURN(c, NULL);
1946 inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
1947 CHECK_NULL_RETURN(inet4_ctrID, NULL);
1948 inet4_class = (*env)->NewGlobalRef(env, c);
1949 CHECK_NULL_RETURN(inet4_class, NULL);
1950 }
1951 addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
1952 CHECK_NULL_RETURN(addr, NULL);
1953
1954 setInetAddress_addr(env, addr, ntohl(in.s_addr));
1955
1956 /*
2039 if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
2040 (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
2041
2042 static jclass ni_class;
2043 static jmethodID ni_ctrID;
2044 static jfieldID ni_indexID;
2045 static jfieldID ni_addrsID;
2046 static jclass ia_class;
2047 static jmethodID ia_anyLocalAddressID;
2048
2049 int index;
2050 int len = sizeof(index);
2051
2052 jobjectArray addrArray;
2053 jobject addr;
2054 jobject ni;
2055
2056 {
2057 if (getsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
2058 (char*)&index, &len) < 0) {
2059 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
2060 "Error getting socket option");
2061 return NULL;
2062 }
2063 }
2064
2065 if (ni_class == NULL) {
2066 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
2067 CHECK_NULL_RETURN(c, NULL);
2068 ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
2069 CHECK_NULL_RETURN(ni_ctrID, NULL);
2070 ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
2071 CHECK_NULL_RETURN(ni_indexID, NULL);
2072 ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
2073 "[Ljava/net/InetAddress;");
2074 CHECK_NULL_RETURN(ni_addrsID, NULL);
2075
2076 ia_class = (*env)->FindClass(env, "java/net/InetAddress");
2077 CHECK_NULL_RETURN(ia_class, NULL);
2078 ia_class = (*env)->NewGlobalRef(env, ia_class);
2079 CHECK_NULL_RETURN(ia_class, NULL);
2080 ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
2271 return NULL;
2272 }
2273
2274 /* find out local IP address */
2275
2276 len = sizeof (struct sockaddr_in);
2277
2278 /* family==-1 when socket is not connected */
2279 if ((family == IPv6) || (family == -1 && fd == -1)) {
2280 fd = fd1; /* must be IPv6 only */
2281 len = sizeof (struct SOCKADDR_IN6);
2282 }
2283
2284 if (fd == -1) {
2285 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
2286 "Socket closed");
2287 return NULL;
2288 }
2289
2290 if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
2291 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
2292 "Error getting socket name");
2293 return NULL;
2294 }
2295 iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
2296
2297 return iaObj;
2298 }
2299
2300 /*
2301 * Class: java_net_TwoStacksPlainDatagramSocketImpl
2302 * Method: setTimeToLive
2303 * Signature: (I)V
2304 */
2305 JNIEXPORT void JNICALL
2306 Java_java_net_TwoStacksPlainDatagramSocketImpl_setTimeToLive(JNIEnv *env, jobject this,
2307 jint ttl) {
2308
2309 jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
2310 jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
2311 int fd = -1, fd1 = -1;
2312 int ittl = (int)ttl;
|
1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
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
1696 ni_class = (*env)->NewGlobalRef(env, c);
1697 CHECK_NULL(ni_class);
1698 }
1699
1700 value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
1701 if (value == NULL) {
1702 if (!(*env)->ExceptionOccurred(env)) {
1703 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1704 "bad argument for IP_MULTICAST_IF"
1705 ": address not bound to any interface");
1706 }
1707 return;
1708 }
1709 opt = java_net_SocketOptions_IP_MULTICAST_IF2;
1710 } else {
1711 struct in_addr in;
1712
1713 in.s_addr = htonl(getInetAddress_addr(env, value));
1714 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1715 (const char*)&in, sizeof(in)) < 0) {
1716 JNU_ThrowByNameWithMessageAndLastError
1717 (env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
1718 }
1719 return;
1720 }
1721 }
1722
1723 if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1724 /*
1725 * value is a NetworkInterface.
1726 * On IPv6 system get the index of the interface and use the
1727 * IPV6_MULTICAST_IF socket option
1728 * On IPv4 system extract addr[0] and use the IP_MULTICAST_IF
1729 * option. For IPv6 both must be done.
1730 */
1731 if (ipv6_supported) {
1732 static jfieldID ni_indexID;
1733 struct in_addr in;
1734 int index;
1735
1736 if (ni_indexID == NULL) {
1737 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
1738 CHECK_NULL(c);
1739 ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
1740 CHECK_NULL(ni_indexID);
1741 }
1742 index = (*env)->GetIntField(env, value, ni_indexID);
1743
1744 if (isAdapterIpv6Enabled(env, index) != 0) {
1745 if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1746 (const char*)&index, sizeof(index)) < 0) {
1747 if (errno == EINVAL && index > 0) {
1748 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1749 "IPV6_MULTICAST_IF failed (interface has IPv4 "
1750 "address only?)");
1751 } else {
1752 JNU_ThrowByNameWithMessageAndLastError
1753 (env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
1754 }
1755 return;
1756 }
1757 }
1758 /* If there are any IPv4 addresses on this interface then
1759 * repeat the operation on the IPv4 fd */
1760
1761 if (getInet4AddrFromIf(env, value, &in) < 0) {
1762 return;
1763 }
1764 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1765 (const char*)&in, sizeof(in)) < 0) {
1766 JNU_ThrowByNameWithMessageAndLastError
1767 (env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
1768 }
1769 return;
1770 } else {
1771 struct in_addr in;
1772
1773 if (getInet4AddrFromIf (env, value, &in) < 0) {
1774 if ((*env)->ExceptionOccurred(env)) {
1775 return;
1776 }
1777 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1778 "no InetAddress instances of requested type");
1779 return;
1780 }
1781
1782 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1783 (const char*)&in, sizeof(in)) < 0) {
1784 JNU_ThrowByNameWithMessageAndLastError
1785 (env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
1786 }
1787 return;
1788 }
1789 }
1790 }
1791
1792 /*
1793 * Class: java_net_TwoStacksPlainDatagramSocketImpl
1794 * Method: socketNativeSetOption
1795 * Signature: (ILjava/lang/Object;)V
1796 */
1797 JNIEXPORT void JNICALL
1798 Java_java_net_TwoStacksPlainDatagramSocketImpl_socketNativeSetOption(JNIEnv *env,jobject this,
1799 jint opt,jobject value) {
1800
1801 int fd=-1, fd1=-1;
1802 int levelv4 = 0, levelv6 = 0, optnamev4 = 0, optnamev6 = 0, optlen = 0;
1803 union {
1804 int i;
1805 char c;
1915 * ipv4Mode == 0, the context is IPV6 processing
1916 *
1917 */
1918 static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint opt, int ipv4Mode) {
1919 static jclass inet4_class;
1920 static jmethodID inet4_ctrID;
1921
1922 static jclass ni_class; static jmethodID ni_ctrID;
1923 static jfieldID ni_indexID;
1924 static jfieldID ni_addrsID;
1925
1926 jobjectArray addrArray;
1927 jobject addr;
1928 jobject ni;
1929
1930 struct in_addr in;
1931 struct in_addr *inP = ∈
1932 int len = sizeof(struct in_addr);
1933 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1934 (char *)inP, &len) < 0) {
1935 JNU_ThrowByNameWithMessageAndLastError
1936 (env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
1937 return NULL;
1938 }
1939
1940 /*
1941 * Construct and populate an Inet4Address
1942 */
1943 if (inet4_class == NULL) {
1944 jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
1945 CHECK_NULL_RETURN(c, NULL);
1946 inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
1947 CHECK_NULL_RETURN(inet4_ctrID, NULL);
1948 inet4_class = (*env)->NewGlobalRef(env, c);
1949 CHECK_NULL_RETURN(inet4_class, NULL);
1950 }
1951 addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
1952 CHECK_NULL_RETURN(addr, NULL);
1953
1954 setInetAddress_addr(env, addr, ntohl(in.s_addr));
1955
1956 /*
2039 if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
2040 (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
2041
2042 static jclass ni_class;
2043 static jmethodID ni_ctrID;
2044 static jfieldID ni_indexID;
2045 static jfieldID ni_addrsID;
2046 static jclass ia_class;
2047 static jmethodID ia_anyLocalAddressID;
2048
2049 int index;
2050 int len = sizeof(index);
2051
2052 jobjectArray addrArray;
2053 jobject addr;
2054 jobject ni;
2055
2056 {
2057 if (getsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
2058 (char*)&index, &len) < 0) {
2059 JNU_ThrowByNameWithMessageAndLastError
2060 (env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
2061 return NULL;
2062 }
2063 }
2064
2065 if (ni_class == NULL) {
2066 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
2067 CHECK_NULL_RETURN(c, NULL);
2068 ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
2069 CHECK_NULL_RETURN(ni_ctrID, NULL);
2070 ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
2071 CHECK_NULL_RETURN(ni_indexID, NULL);
2072 ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
2073 "[Ljava/net/InetAddress;");
2074 CHECK_NULL_RETURN(ni_addrsID, NULL);
2075
2076 ia_class = (*env)->FindClass(env, "java/net/InetAddress");
2077 CHECK_NULL_RETURN(ia_class, NULL);
2078 ia_class = (*env)->NewGlobalRef(env, ia_class);
2079 CHECK_NULL_RETURN(ia_class, NULL);
2080 ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
2271 return NULL;
2272 }
2273
2274 /* find out local IP address */
2275
2276 len = sizeof (struct sockaddr_in);
2277
2278 /* family==-1 when socket is not connected */
2279 if ((family == IPv6) || (family == -1 && fd == -1)) {
2280 fd = fd1; /* must be IPv6 only */
2281 len = sizeof (struct SOCKADDR_IN6);
2282 }
2283
2284 if (fd == -1) {
2285 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
2286 "Socket closed");
2287 return NULL;
2288 }
2289
2290 if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
2291 JNU_ThrowByNameWithMessageAndLastError
2292 (env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
2293 return NULL;
2294 }
2295 iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
2296
2297 return iaObj;
2298 }
2299
2300 /*
2301 * Class: java_net_TwoStacksPlainDatagramSocketImpl
2302 * Method: setTimeToLive
2303 * Signature: (I)V
2304 */
2305 JNIEXPORT void JNICALL
2306 Java_java_net_TwoStacksPlainDatagramSocketImpl_setTimeToLive(JNIEnv *env, jobject this,
2307 jint ttl) {
2308
2309 jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
2310 jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
2311 int fd = -1, fd1 = -1;
2312 int ittl = (int)ttl;
|