1 /*
   2  * Copyright (c) 1997, 2018, 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
  23  * questions.
  24  */
  25 #include <winsock2.h>
  26 #include <WS2tcpip.h>
  27 #include <iphlpapi.h>
  28 #include <icmpapi.h>
  29 
  30 /* used to disable connection reset messages on Windows XP */
  31 #ifndef SIO_UDP_CONNRESET
  32 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
  33 #endif
  34 
  35 #ifndef IN6_IS_ADDR_ANY
  36 #define IN6_IS_ADDR_ANY(a)      \
  37     (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) &&      \
  38     ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) &&       \
  39     ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) &&       \
  40     ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0))
  41 #endif
  42 
  43 #ifndef IPV6_V6ONLY
  44 #define IPV6_V6ONLY     27 /* Treat wildcard bind as AF_INET6-only. */
  45 #endif
  46 
  47 #define MAX_BUFFER_LEN          2048
  48 #define MAX_HEAP_BUFFER_LEN     65536
  49 
  50 /* true if SO_RCVTIMEO is supported by underlying provider */
  51 extern jboolean isRcvTimeoutSupported;
  52 
  53 void NET_ThrowCurrent(JNIEnv *env, char *msg);
  54 
  55 typedef union {
  56     struct sockaddr     sa;
  57     struct sockaddr_in  sa4;
  58     struct sockaddr_in6 sa6;
  59 } SOCKETADDRESS;
  60 
  61 /*
  62  * passed to NET_BindV6. Both ipv4_fd and ipv6_fd must be created and unbound
  63  * sockets. On return they may refer to different sockets.
  64  */
  65 struct ipv6bind {
  66     SOCKETADDRESS      *addr;
  67     SOCKET              ipv4_fd;
  68     SOCKET              ipv6_fd;
  69 };
  70 
  71 #define SOCKETADDRESS_COPY(DST,SRC) {                           \
  72     if ((SRC)->sa_family == AF_INET6) {                         \
  73         memcpy ((DST), (SRC), sizeof (struct sockaddr_in6));    \
  74     } else {                                                    \
  75         memcpy ((DST), (SRC), sizeof (struct sockaddr_in));     \
  76     }                                                           \
  77 }
  78 
  79 #define SET_PORT(X,Y) {                    \
  80     if ((X)->sa.sa_family == AF_INET) {    \
  81         (X)->sa4.sin_port = (Y);           \
  82     } else {                               \
  83         (X)->sa6.sin6_port = (Y);          \
  84     }                                      \
  85 }
  86 
  87 #define GET_PORT(X) ((X)->sa.sa_family == AF_INET ? (X)->sa4.sin_port : (X)->sa6.sin6_port)
  88 
  89 #define IS_LOOPBACK_ADDRESS(x) ( \
  90     ((x)->sa.sa_family == AF_INET) ? \
  91         (ntohl((x)->sa4.sin_addr.s_addr) == INADDR_LOOPBACK) : \
  92         (IN6ADDR_ISLOOPBACK(x)) \
  93 )
  94 
  95 JNIEXPORT int JNICALL NET_SocketClose(int fd);
  96 
  97 JNIEXPORT int JNICALL NET_Timeout(int fd, long timeout);
  98 
  99 int NET_Socket(int domain, int type, int protocol);
 100 
 101 void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
 102                                   const char *defaultDetail);
 103 
 104 /*
 105  * differs from NET_Timeout() as follows:
 106  *
 107  * If timeout = -1, it blocks forever.
 108  *
 109  * returns 1 or 2 depending if only one or both sockets
 110  * fire at same time.
 111  *
 112  * *fdret is (one of) the active fds. If both sockets
 113  * fire at same time, *fd == fd always.
 114  */
 115 JNIEXPORT int JNICALL NET_Timeout2(int fd, int fd1, long timeout, int *fdret);
 116 
 117 JNIEXPORT int JNICALL NET_BindV6(struct ipv6bind *b, jboolean exclBind);
 118 
 119 JNIEXPORT int JNICALL NET_WinBind(int s, SOCKETADDRESS *sa, int len,
 120                                   jboolean exclBind);
 121 
 122 /* XP versions of the native routines */
 123 
 124 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
 125   (JNIEnv *env, jclass cls, jstring name);
 126 
 127 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0_XP
 128   (JNIEnv *env, jclass cls, jint index);
 129 
 130 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0_XP
 131   (JNIEnv *env, jclass cls, jobject iaObj);
 132 
 133 JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll_XP
 134   (JNIEnv *env, jclass cls);
 135 
 136 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0_XP
 137   (JNIEnv *env, jclass cls, jstring name, jint index);
 138 
 139 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0_XP
 140   (JNIEnv *env, jclass cls, jstring name, jint index);
 141 
 142 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0_XP
 143   (JNIEnv *env, jclass cls, jstring name, jint index);
 144 
 145 JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0_XP
 146   (JNIEnv *env, jclass cls, jstring name, jint index);
 147 
 148 JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
 149   (JNIEnv *env, jclass class, jstring name, jint index);
 150 
 151 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
 152   (JNIEnv *env, jclass cls, jstring name, jint index);