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