blob: d9f634170a5f783cee8554ac750e949a736787a0 [file] [log] [blame]
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <winsock2.h>
#include <WS2tcpip.h>
/* typedefs that were defined correctly for the first time
* in Nov. 2001 SDK, which we need to include here.
* Specifically, in6_addr and sockaddr_in6 (which is defined but
* not correctly). When moving to a later SDK remove following
* code between START and END
*/
/* --- START --- */
/* WIN64 already uses newer SDK */
#ifdef _WIN64
#define SOCKADDR_IN6 sockaddr_in6
#else
#ifdef _MSC_VER
#define WS2TCPIP_INLINE __inline
#else
#define WS2TCPIP_INLINE extern inline /* GNU style */
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1310
#define SOCKADDR_IN6 sockaddr_in6
#else
/* Retain this code a little longer to support building in
* old environments. _MSC_VER is defined as:
* 1200 for MSVC++ 6.0
* 1310 for Vc7
*/
#define IPPROTO_IPV6 41
#define IPV6_MULTICAST_IF 9
struct in6_addr {
union {
u_char Byte[16];
u_short Word[8];
} u;
};
/*
** Defines to match RFC 2553.
*/
#define _S6_un u
#define _S6_u8 Byte
#define s6_addr _S6_un._S6_u8
/*
** Defines for our implementation.
*/
#define s6_bytes u.Byte
#define s6_words u.Word
/* IPv6 socket address structure, RFC 2553 */
struct SOCKADDR_IN6 {
short sin6_family; /* AF_INET6 */
u_short sin6_port; /* Transport level port number */
u_long sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
u_long sin6_scope_id; /* set of interfaces for a scope */
};
/* Error codes from getaddrinfo() */
#define EAI_AGAIN WSATRY_AGAIN
#define EAI_BADFLAGS WSAEINVAL
#define EAI_FAIL WSANO_RECOVERY
#define EAI_FAMILY WSAEAFNOSUPPORT
#define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
//#define EAI_NODATA WSANO_DATA
#define EAI_NONAME WSAHOST_NOT_FOUND
#define EAI_SERVICE WSATYPE_NOT_FOUND
#define EAI_SOCKTYPE WSAESOCKTNOSUPPORT
#define EAI_NODATA EAI_NONAME
/* Structure used in getaddrinfo() call */
typedef struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* Length of ai_addr */
char *ai_canonname; /* Canonical name for nodename */
struct sockaddr *ai_addr; /* Binary address */
struct addrinfo *ai_next; /* Next structure in linked list */
} ADDRINFO, FAR * LPADDRINFO;
/* Flags used in "hints" argument to getaddrinfo() */
#define AI_PASSIVE 0x1 /* Socket address will be used in bind() call */
#define AI_CANONNAME 0x2 /* Return canonical name in first ai_canonname */
#define AI_NUMERICHOST 0x4 /* Nodename must be a numeric address string */
/* IPv6 Multicasting definitions */
/* Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP */
typedef struct ipv6_mreq {
struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast address */
unsigned int ipv6mr_interface; /* Interface index */
} IPV6_MREQ;
#define IPV6_ADD_MEMBERSHIP 12 /* Add an IP group membership */
#define IPV6_DROP_MEMBERSHIP 13 /* Drop an IP group membership */
#define IPV6_MULTICAST_LOOP 11 /* Set/get IP multicast loopback */
WS2TCPIP_INLINE int
IN6_IS_ADDR_MULTICAST(const struct in6_addr *a)
{
return (a->s6_bytes[0] == 0xff);
}
WS2TCPIP_INLINE int
IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *a)
{
return (a->s6_bytes[0] == 0xfe
&& a->s6_bytes[1] == 0x80);
}
#define NI_MAXHOST 1025 /* Max size of a fully-qualified domain name */
#define NI_MAXSERV 32 /* Max size of a service name */
#define INET_ADDRSTRLEN 16 /* Max size of numeric form of IPv4 address */
#define INET6_ADDRSTRLEN 46 /* Max size of numeric form of IPv6 address */
/* Flags for getnameinfo() */
#define NI_NOFQDN 0x01 /* Only return nodename portion for local hosts */
#define NI_NUMERICHOST 0x02 /* Return numeric form of the host's address */
#define NI_NAMEREQD 0x04 /* Error if the host's name not in DNS */
#define NI_NUMERICSERV 0x08 /* Return numeric form of the service (port #) */
#define NI_DGRAM 0x10 /* Service is a datagram service */
#define IN6_IS_ADDR_V4MAPPED(a) \
(((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \
((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && \
((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0xffff))
/* --- END --- */
#endif /* end 'else older build environment' */
#endif
#if !INCL_WINSOCK_API_TYPEDEFS
typedef
int
(WSAAPI * LPFN_GETADDRINFO)(
IN const char FAR * nodename,
IN const char FAR * servname,
IN const struct addrinfo FAR * hints,
OUT struct addrinfo FAR * FAR * res
);
typedef
void
(WSAAPI * LPFN_FREEADDRINFO)(
IN struct addrinfo FAR * ai
);
typedef
int
(WSAAPI * LPFN_GETNAMEINFO)(
IN const struct sockaddr FAR * sa,
IN int salen,
OUT char FAR * host,
IN DWORD hostlen,
OUT char FAR * serv,
IN DWORD servlen,
IN int flags
);
#endif
LPFN_GETADDRINFO getaddrinfo_ptr;
LPFN_FREEADDRINFO freeaddrinfo_ptr;
LPFN_GETNAMEINFO getnameinfo_ptr;
/* used to disable connection reset messages on Windows XP */
#ifndef SIO_UDP_CONNRESET
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
#endif
#ifndef IN6_IS_ADDR_ANY
#define IN6_IS_ADDR_ANY(a) \
(((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \
((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && \
((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && \
((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0))
#endif
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27 /* Treat wildcard bind as AF_INET6-only. */
#endif
#include "java_io_FileDescriptor.h"
#include "java_net_SocketOptions.h"
#define MAX_BUFFER_LEN 2048
#define MAX_HEAP_BUFFER_LEN 65536
/* true if SO_RCVTIMEO is supported by underlying provider */
extern jboolean isRcvTimeoutSupported;
void NET_ThrowCurrent(JNIEnv *env, char *msg);
/*
* Return default Type Of Service
*/
int NET_GetDefaultTOS(void);
typedef union {
struct sockaddr him;
struct sockaddr_in him4;
struct SOCKADDR_IN6 him6;
} SOCKETADDRESS;
/*
* passed to NET_BindV6. Both ipv4_fd and ipv6_fd must be created and unbound
* sockets. On return they may refer to different sockets.
*/
struct ipv6bind {
SOCKETADDRESS *addr;
SOCKET ipv4_fd;
SOCKET ipv6_fd;
};
#define SOCKETADDRESS_LEN(X) \
(((X)->him.sa_family==AF_INET6)? sizeof(struct SOCKADDR_IN6) : \
sizeof(struct sockaddr_in))
#define SOCKETADDRESS_COPY(DST,SRC) { \
if ((SRC)->sa_family == AF_INET6) { \
memcpy ((DST), (SRC), sizeof (struct SOCKADDR_IN6)); \
} else { \
memcpy ((DST), (SRC), sizeof (struct sockaddr_in)); \
} \
}
#define SET_PORT(X,Y) { \
if ((X)->him.sa_family == AF_INET) { \
(X)->him4.sin_port = (Y); \
} else { \
(X)->him6.sin6_port = (Y); \
} \
}
#define GET_PORT(X) ((X)->him.sa_family==AF_INET ?(X)->him4.sin_port: (X)->him6.sin6_port)
#define IS_LOOPBACK_ADDRESS(x) ( \
((x)->him.sa_family == AF_INET) ? \
(ntohl((x)->him4.sin_addr.s_addr)==INADDR_LOOPBACK) : \
(IN6ADDR_ISLOOPBACK (x)) \
)
JNIEXPORT int JNICALL NET_SocketClose(int fd);
JNIEXPORT int JNICALL NET_Timeout(int fd, long timeout);
int NET_Socket(int domain, int type, int protocol);
void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail);
void NET_ThrowSocketException(JNIEnv *env, char* msg);
jboolean NET_addrtransAvailable();
/*
* differs from NET_Timeout() as follows:
*
* If timeout = -1, it blocks forever.
*
* returns 1 or 2 depending if only one or both sockets
* fire at same time.
*
* *fdret is (one of) the active fds. If both sockets
* fire at same time, *fd == fd always.
*/
JNIEXPORT int JNICALL NET_Timeout2(int fd, int fd1, long timeout, int *fdret);
JNIEXPORT int JNICALL NET_BindV6(struct ipv6bind* b);
#define NET_WAIT_READ 0x01
#define NET_WAIT_WRITE 0x02
#define NET_WAIT_CONNECT 0x04
extern jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
/* XP versions of the native routines */
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
(JNIEnv *env, jclass cls, jstring name);
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0_XP
(JNIEnv *env, jclass cls, jint index);
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0_XP
(JNIEnv *env, jclass cls, jobject iaObj);
JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll_XP
(JNIEnv *env, jclass cls);
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0_XP
(JNIEnv *env, jclass cls, jstring name, jint index);
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0_XP
(JNIEnv *env, jclass cls, jstring name, jint index);
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0_XP
(JNIEnv *env, jclass cls, jstring name, jint index);
JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0_XP
(JNIEnv *env, jclass cls, jstring name, jint index);
JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
(JNIEnv *env, jclass class, jstring name, jint index);
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
(JNIEnv *env, jclass cls, jstring name, jint index);