1 /*
   2  * Copyright (c) 1997, 2013, 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 
  26 #include <winsock2.h>
  27 #include <WS2tcpip.h>
  28 
  29 /* typedefs that were defined correctly for the first time
  30  * in Nov. 2001 SDK, which we need to include here.
  31  * Specifically, in6_addr and sockaddr_in6 (which is defined but
  32  * not correctly). When moving to a later SDK remove following
  33  * code between START and END
  34  */
  35 
  36 /* --- START --- */
  37 
  38 /* WIN64 already uses newer SDK */
  39 #ifdef _WIN64
  40 
  41 #define SOCKADDR_IN6 sockaddr_in6
  42 
  43 #else
  44 
  45 #ifdef _MSC_VER
  46 #define WS2TCPIP_INLINE __inline
  47 #else
  48 #define WS2TCPIP_INLINE extern inline /* GNU style */
  49 #endif
  50 
  51 #if defined(_MSC_VER) && _MSC_VER >= 1310
  52 
  53 #define SOCKADDR_IN6 sockaddr_in6
  54 
  55 #else
  56 
  57 /*SO_REUSEPORT is not supported on Windows, define it to 0*/
  58 #define SO_REUSEPORT 0
  59 
  60 /* Retain this code a little longer to support building in
  61  * old environments.  _MSC_VER is defined as:
  62  *     1200 for MSVC++ 6.0
  63  *     1310 for Vc7
  64  */
  65 
  66 #define IPPROTO_IPV6    41
  67 #define IPV6_MULTICAST_IF 9
  68 
  69 struct in6_addr {
  70     union {
  71         u_char Byte[16];
  72         u_short Word[8];
  73     } u;
  74 };
  75 
  76 /*
  77 ** Defines to match RFC 2553.
  78 */
  79 #define _S6_un     u
  80 #define _S6_u8     Byte
  81 #define s6_addr    _S6_un._S6_u8
  82 
  83 /*
  84 ** Defines for our implementation.
  85 */
  86 #define s6_bytes   u.Byte
  87 #define s6_words   u.Word
  88 
  89 /* IPv6 socket address structure, RFC 2553 */
  90 
  91 struct SOCKADDR_IN6 {
  92         short   sin6_family;    /* AF_INET6 */
  93         u_short sin6_port;      /* Transport level port number */
  94         u_long  sin6_flowinfo;  /* IPv6 flow information */
  95         struct in6_addr sin6_addr; /* IPv6 address */
  96         u_long sin6_scope_id;  /* set of interfaces for a scope */
  97 };
  98 
  99 
 100 /* Error codes from getaddrinfo() */
 101 
 102 #define EAI_AGAIN       WSATRY_AGAIN
 103 #define EAI_BADFLAGS    WSAEINVAL
 104 #define EAI_FAIL        WSANO_RECOVERY
 105 #define EAI_FAMILY      WSAEAFNOSUPPORT
 106 #define EAI_MEMORY      WSA_NOT_ENOUGH_MEMORY
 107 //#define EAI_NODATA      WSANO_DATA
 108 #define EAI_NONAME      WSAHOST_NOT_FOUND
 109 #define EAI_SERVICE     WSATYPE_NOT_FOUND
 110 #define EAI_SOCKTYPE    WSAESOCKTNOSUPPORT
 111 
 112 #define EAI_NODATA      EAI_NONAME
 113 
 114 /* Structure used in getaddrinfo() call */
 115 
 116 typedef struct addrinfo {
 117     int ai_flags;              /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
 118     int ai_family;             /* PF_xxx */
 119     int ai_socktype;           /* SOCK_xxx */
 120     int ai_protocol;           /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
 121     size_t ai_addrlen;         /* Length of ai_addr */
 122     char *ai_canonname;        /* Canonical name for nodename */
 123     struct sockaddr *ai_addr;  /* Binary address */
 124     struct addrinfo *ai_next;  /* Next structure in linked list */
 125 } ADDRINFO, FAR * LPADDRINFO;
 126 
 127 /* Flags used in "hints" argument to getaddrinfo() */
 128 
 129 #define AI_PASSIVE     0x1  /* Socket address will be used in bind() call */
 130 #define AI_CANONNAME   0x2  /* Return canonical name in first ai_canonname */
 131 #define AI_NUMERICHOST 0x4  /* Nodename must be a numeric address string */
 132 
 133 /* IPv6 Multicasting definitions */
 134 
 135 /* Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP */
 136 
 137 typedef struct ipv6_mreq {
 138     struct in6_addr ipv6mr_multiaddr;  /* IPv6 multicast address */
 139     unsigned int    ipv6mr_interface;  /* Interface index */
 140 } IPV6_MREQ;
 141 
 142 #define IPV6_ADD_MEMBERSHIP     12 /* Add an IP group membership */
 143 #define IPV6_DROP_MEMBERSHIP    13 /* Drop an IP group membership */
 144 #define IPV6_MULTICAST_LOOP     11 /* Set/get IP multicast loopback */
 145 
 146 WS2TCPIP_INLINE int
 147 IN6_IS_ADDR_MULTICAST(const struct in6_addr *a)
 148 {
 149     return (a->s6_bytes[0] == 0xff);
 150 }
 151 
 152 WS2TCPIP_INLINE int
 153 IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *a)
 154 {
 155     return (a->s6_bytes[0] == 0xfe
 156             && a->s6_bytes[1] == 0x80);
 157 }
 158 
 159 #define NI_MAXHOST  1025  /* Max size of a fully-qualified domain name */
 160 #define NI_MAXSERV    32  /* Max size of a service name */
 161 
 162 #define INET_ADDRSTRLEN  16 /* Max size of numeric form of IPv4 address */
 163 #define INET6_ADDRSTRLEN 46 /* Max size of numeric form of IPv6 address */
 164 
 165 /* Flags for getnameinfo() */
 166 
 167 #define NI_NOFQDN       0x01  /* Only return nodename portion for local hosts */
 168 #define NI_NUMERICHOST  0x02  /* Return numeric form of the host's address */
 169 #define NI_NAMEREQD     0x04  /* Error if the host's name not in DNS */
 170 #define NI_NUMERICSERV  0x08  /* Return numeric form of the service (port #) */
 171 #define NI_DGRAM        0x10  /* Service is a datagram service */
 172 
 173 
 174 #define IN6_IS_ADDR_V4MAPPED(a) \
 175     (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) &&      \
 176     ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) &&       \
 177     ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0xffff))
 178 
 179 
 180 /* --- END --- */
 181 #endif /* end 'else older build environment' */
 182 
 183 #endif
 184 
 185 #if !INCL_WINSOCK_API_TYPEDEFS
 186 
 187 typedef
 188 int
 189 (WSAAPI * LPFN_GETADDRINFO)(
 190     IN const char FAR * nodename,
 191     IN const char FAR * servname,
 192     IN const struct addrinfo FAR * hints,
 193     OUT struct addrinfo FAR * FAR * res
 194     );
 195 
 196 typedef
 197 void
 198 (WSAAPI * LPFN_FREEADDRINFO)(
 199     IN struct addrinfo FAR * ai
 200     );
 201 
 202 typedef
 203 int
 204 (WSAAPI * LPFN_GETNAMEINFO)(
 205     IN  const struct sockaddr FAR * sa,
 206     IN  int             salen,
 207     OUT char FAR *      host,
 208     IN  DWORD           hostlen,
 209     OUT char FAR *      serv,
 210     IN  DWORD           servlen,
 211     IN  int             flags
 212     );
 213 #endif
 214 
 215 /* used to disable connection reset messages on Windows XP */
 216 #ifndef SIO_UDP_CONNRESET
 217 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
 218 #endif
 219 
 220 #ifndef IN6_IS_ADDR_ANY
 221 #define IN6_IS_ADDR_ANY(a)      \
 222     (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) &&      \
 223     ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) &&       \
 224     ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) &&       \
 225     ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0))
 226 #endif
 227 
 228 #ifndef IPV6_V6ONLY
 229 #define IPV6_V6ONLY     27 /* Treat wildcard bind as AF_INET6-only. */
 230 #endif
 231 
 232 #include "java_io_FileDescriptor.h"
 233 #include "java_net_SocketOptions.h"
 234 
 235 #define MAX_BUFFER_LEN          2048
 236 #define MAX_HEAP_BUFFER_LEN     65536
 237 
 238 
 239 /* true if SO_RCVTIMEO is supported by underlying provider */
 240 extern jboolean isRcvTimeoutSupported;
 241 
 242 void NET_ThrowCurrent(JNIEnv *env, char *msg);
 243 
 244 /*
 245  * Return default Type Of Service
 246  */
 247 int NET_GetDefaultTOS(void);
 248 
 249 typedef union {
 250     struct sockaddr     him;
 251     struct sockaddr_in  him4;
 252     struct SOCKADDR_IN6 him6;
 253 } SOCKETADDRESS;
 254 
 255 /*
 256  * passed to NET_BindV6. Both ipv4_fd and ipv6_fd must be created and unbound
 257  * sockets. On return they may refer to different sockets.
 258  */
 259 struct ipv6bind {
 260     SOCKETADDRESS       *addr;
 261     SOCKET               ipv4_fd;
 262     SOCKET               ipv6_fd;
 263 };
 264 
 265 #define SOCKETADDRESS_LEN(X)    \
 266         (((X)->him.sa_family==AF_INET6)? sizeof(struct SOCKADDR_IN6) : \
 267                          sizeof(struct sockaddr_in))
 268 
 269 #define SOCKETADDRESS_COPY(DST,SRC) {                           \
 270     if ((SRC)->sa_family == AF_INET6) {                         \
 271         memcpy ((DST), (SRC), sizeof (struct SOCKADDR_IN6));    \
 272     } else {                                                    \
 273         memcpy ((DST), (SRC), sizeof (struct sockaddr_in));     \
 274     }                                                           \
 275 }
 276 
 277 #define SET_PORT(X,Y) {                         \
 278     if ((X)->him.sa_family == AF_INET) {        \
 279         (X)->him4.sin_port = (Y);               \
 280     } else {                                    \
 281         (X)->him6.sin6_port = (Y);              \
 282     }                                           \
 283 }
 284 
 285 #define GET_PORT(X) ((X)->him.sa_family==AF_INET ?(X)->him4.sin_port: (X)->him6.sin6_port)
 286 
 287 #define IS_LOOPBACK_ADDRESS(x) ( \
 288     ((x)->him.sa_family == AF_INET) ? \
 289         (ntohl((x)->him4.sin_addr.s_addr)==INADDR_LOOPBACK) : \
 290         (IN6ADDR_ISLOOPBACK (x)) \
 291 )
 292 
 293 JNIEXPORT int JNICALL NET_SocketClose(int fd);
 294 
 295 JNIEXPORT int JNICALL NET_Timeout(int fd, long timeout);
 296 
 297 int NET_Socket(int domain, int type, int protocol);
 298 
 299 void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
 300          const char *defaultDetail);
 301 
 302 void NET_ThrowSocketException(JNIEnv *env, char* msg);
 303 
 304 /*
 305  * differs from NET_Timeout() as follows:
 306  *
 307  * If timeout = -1, it blocks forever.
 308  *
 309  * returns 1 or 2 depending if only one or both sockets
 310  * fire at same time.
 311  *
 312  * *fdret is (one of) the active fds. If both sockets
 313  * fire at same time, *fd == fd always.
 314  */
 315 JNIEXPORT int JNICALL NET_Timeout2(int fd, int fd1, long timeout, int *fdret);
 316 
 317 JNIEXPORT int JNICALL NET_BindV6(struct ipv6bind* b, jboolean exclBind);
 318 
 319 #define NET_WAIT_READ   0x01
 320 #define NET_WAIT_WRITE  0x02
 321 #define NET_WAIT_CONNECT        0x04
 322 
 323 extern jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
 324 
 325 JNIEXPORT int JNICALL NET_WinBind(int s, struct sockaddr *him, int len,
 326                                    jboolean exclBind);
 327 
 328 /* XP versions of the native routines */
 329 
 330 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
 331     (JNIEnv *env, jclass cls, jstring name);
 332 
 333 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0_XP
 334   (JNIEnv *env, jclass cls, jint index);
 335 
 336 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0_XP
 337     (JNIEnv *env, jclass cls, jobject iaObj);
 338 
 339 JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll_XP
 340     (JNIEnv *env, jclass cls);
 341 
 342 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0_XP
 343 (JNIEnv *env, jclass cls, jstring name, jint index);
 344 
 345 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0_XP
 346 (JNIEnv *env, jclass cls, jstring name, jint index);
 347 
 348 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0_XP
 349 (JNIEnv *env, jclass cls, jstring name, jint index);
 350 
 351 JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0_XP
 352 (JNIEnv *env, jclass cls, jstring name, jint index);
 353 
 354 JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
 355 (JNIEnv *env, jclass class, jstring name, jint index);
 356 
 357 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
 358 (JNIEnv *env, jclass cls, jstring name, jint index);
 359