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