/** * Creates a SDP socket. */ static int create(JNIEnv* env) { int s; #if defined(__solaris__) #ifdef AF_INET6 int domain = ipv6_available() ? AF_INET6 : AF_INET; #else int domain = AF_INET; #endif s = socket(domain, SOCK_STREAM, PROTO_SDP); #elif defined(__linux__) /** * IPv6 not supported by SDP on Linux */ if (ipv6_available()) { JNU_ThrowIOException(env, "IPv6 not supported"); return -1; } s = socket(AF_INET_SDP, SOCK_STREAM, 0); #else /* not supported on other platforms at this time */ s = -1; errno = EPROTONOSUPPORT; #endif if (s < 0) JNU_ThrowIOExceptionWithLastError(env, "socket"); return s; }
/* * Class: NetworkInterface * Method: getByIndex * Signature: (I)LNetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex (JNIEnv *env, jclass cls, jint index) { netif *ifList, *curr; jobject netifObj = NULL; if (os_supports_ipv6 && ipv6_available()) { return Java_java_net_NetworkInterface_getByIndex_XP (env, cls, index); } /* get the list of interfaces */ if ((*enumInterfaces_fn)(env, &ifList) < 0) { return NULL; } /* search by index */ curr = ifList; while (curr != NULL) { if (index == curr->index) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) { netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the interface list */ free_netif(ifList); return netifObj; }
JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_connect(JNIEnv *env, jclass clazz, jobject fdo, jobject iao, jint port, jint trafficClass) { SOCKADDR sa; int sa_len = SOCKADDR_LEN; int rv; NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *) &sa, &sa_len); #ifdef AF_INET6 #if 0 if (trafficClass != 0 && ipv6_available()) { /* ## FIX */ NET_SetTrafficClass((struct sockaddr *)&sa, trafficClass); } #endif #endif rv = connect(fdval(env, fdo), (struct sockaddr *)&sa, sa_len); if (rv != 0) { if (errno == EINPROGRESS) { return IOS_UNAVAILABLE; } else if (errno == EINTR) { return IOS_INTERRUPTED; } return handleSocketError(env, errno); } return 1; }
JNIEXPORT int JNICALL Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean stream, jboolean reuse) { int fd; #ifdef AF_INET6 if (ipv6_available()) fd = socket(AF_INET6, (stream ? SOCK_STREAM : SOCK_DGRAM), 0); else #endif /* AF_INET6 */ fd = socket(AF_INET, (stream ? SOCK_STREAM : SOCK_DGRAM), 0); if (fd < 0) { return handleSocketError(env, errno); } if (reuse) { int arg = 1; if (NET_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg)) < 0) { JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "sun.nio.ch.Net.setIntOption"); } } return fd; }
JNIEXPORT void JNICALL Java_sun_net_spi_SdpProvider_convert(JNIEnv *env, jclass cls, jint fd) { #ifdef PROTO_SDP int domain = ipv6_available() ? AF_INET6 : AF_INET; int s = socket(domain, SOCK_STREAM, PROTO_SDP); if (s < 0) { JNU_ThrowIOExceptionWithLastError(env, "socket"); } else { int arg, len, res; struct linger linger; /* copy socket options that are relevant to SDP */ len = sizeof(arg); if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, &len) == 0) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, len); len = sizeof(arg); if (getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, &len) == 0) setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, len); len = sizeof(linger); if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (void*)&linger, &len) == 0) setsockopt(s, SOL_SOCKET, SO_LINGER, (char*)&linger, len); RESTARTABLE(dup2(s, fd), res); if (res < 0) JNU_ThrowIOExceptionWithLastError(env, "dup2"); RESTARTABLE(close(s), res); } #else JNU_ThrowInternalError(env, "should not reach here"); #endif }
/* * Enumerates all interfaces */ static netif *enumInterfaces(JNIEnv *env) { netif *ifs; /* * Enumerate IPv4 addresses */ ifs = enumIPv4Interfaces(env, NULL); if (ifs == NULL) { if ((*env)->ExceptionOccurred(env)) { return NULL; } } /* * If IPv6 is available then enumerate IPv6 addresses. */ #ifdef AF_INET6 if (ipv6_available()) { ifs = enumIPv6Interfaces(env, ifs); if ((*env)->ExceptionOccurred(env)) { freeif(ifs); return NULL; } } #endif return ifs; }
/* * Enumerates all interfaces */ static netif *enumInterfaces(JNIEnv *env) { netif *ifs; /* * Enumerate IPv4 addresses */ ifs = enumIPvXInterfaces(env, NULL, KAfInet); if (ifs == NULL) { if ((*env)->ExceptionOccurred(env)) { return NULL; } } /* * If IPv6 is available then enumerate IPv6 addresses. */ if (ipv6_available()) { ifs = enumIPvXInterfaces(env, ifs, KAfInet6); if ((*env)->ExceptionOccurred(env)) { return NULL; } } return ifs; }
/* * Class: NetworkInterface * Method: getByIndex0 * Signature: (I)LNetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0 (JNIEnv *env, jclass cls, jint index) { netif *ifList, *curr; jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByIndex0_XP (env, cls, index); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* search by index */ curr = ifList; while (curr != NULL) { if (index == curr->index) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) { netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the interface list */ free_netif(ifList); return netifObj; }
JNIEXPORT int JNICALL Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, jboolean stream, jboolean reuse) { int fd; int type = (stream ? SOCK_STREAM : SOCK_DGRAM); #ifdef AF_INET6 int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET; #else int domain = AF_INET; #endif fd = socket(domain, type, 0); if (fd < 0) { return handleSocketError(env, errno); } #ifdef AF_INET6 /* Disable IPV6_V6ONLY to ensure dual-socket support */ if (domain == AF_INET6) { int arg = 0; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, sizeof(int)) < 0) { JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "sun.nio.ch.Net.setIntOption"); close(fd); return -1; } } #endif if (reuse) { int arg = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg)) < 0) { JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "sun.nio.ch.Net.setIntOption"); close(fd); return -1; } } #if defined(__linux__) && defined(AF_INET6) /* By default, Linux uses the route default */ if (domain == AF_INET6 && type == SOCK_DGRAM) { int arg = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &arg, sizeof(arg)) < 0) { JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "sun.nio.ch.Net.setIntOption"); close(fd); return -1; } } #endif return fd; }
static int matchFamily(struct sockaddr *sa) { int family = sa->sa_family; #ifdef AF_INET6 if (ipv6_available()) { return (family == AF_INET6); } #endif return (family == AF_INET); }
void probe_Init() { probe.select_changes_time = select_changes_time() ? 1 : 0; log_Printf(LogDEBUG, "Select changes time: %s\n", probe.select_changes_time ? "yes" : "no"); #ifndef NOINET6 probe.ipv6_available = ipv6_available() ? 1 : 0; log_Printf(LogDEBUG, "IPv6 available: %s\n", probe.ipv6_available ? "yes" : "no"); #endif }
/* * Class: java_net_InetAddressImplFactory * Method: isIPv6Supported * Signature: ()I */ JNIEXPORT jboolean JNICALL Java_java_net_InetAddressImplFactory_isIPv6Supported(JNIEnv *env, jclass cls) { #ifdef AF_INET6 if (ipv6_available()) { return JNI_TRUE; } else #endif /* AF_INET6 */ { return JNI_FALSE; } }
/* * Class: java_net_NetworkInterface * Method: getAll * Signature: ()[Ljava/net/NetworkInterface; */ JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll (JNIEnv *env, jclass cls) { int count; netif *ifList, *curr; jobjectArray netIFArr; jint arr_index; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getAll_XP (env, cls); } /* * Get list of interfaces */ count = enumInterfaces(env, &ifList); if (count < 0) { return NULL; } /* allocate a NetworkInterface array */ netIFArr = (*env)->NewObjectArray(env, count, cls, NULL); if (netIFArr == NULL) { return NULL; } /* * Iterate through the interfaces, create a NetworkInterface instance * for each array element and populate the object. */ curr = ifList; arr_index = 0; while (curr != NULL) { jobject netifObj; netifObj = createNetworkInterface(env, curr, -1, NULL); if (netifObj == NULL) { return NULL; } /* put the NetworkInterface into the array */ (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj); curr = curr->next; } /* release the interface list */ free_netif(ifList); return netIFArr; }
/* * Class: java_net_NetworkInterface * Method: getByName0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 (JNIEnv *env, jclass cls, jstring name) { netif *ifList, *curr; jboolean isCopy; const char *name_utf; jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByName0_XP (env, cls, name); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* get the name as a C string */ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); if (name_utf != NULL) { /* Search by name */ curr = ifList; while (curr != NULL) { if (strcmp(name_utf, curr->name) == 0) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) { ; netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the UTF string */ (*env)->ReleaseStringUTFChars(env, name, name_utf); } else { if (!(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, NULL); } /* release the interface list */ free_netif(ifList); return netifObj; }
JNIEXPORT jboolean JNICALL Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl) { /* * Return true if Windows Vista or newer, and IPv6 is configured */ OSVERSIONINFO ver; ver.dwOSVersionInfoSize = sizeof(ver); GetVersionEx(&ver); if ((ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ver.dwMajorVersion >= 6) && ipv6_available()) { return JNI_TRUE; } return JNI_FALSE; }
/* * Class: java_net_NetworkInterface * Method: isLoopback0 * Signature: (Ljava/lang/String;I)Z */ JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0 (JNIEnv *env, jclass cls, jstring name, jint index) { MIB_IFROW *ifRowP; jboolean ret = JNI_FALSE; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_isLoopback0_XP(env, cls, name, index); } else { ifRowP = getIF(index); if (ifRowP != NULL) { if (ifRowP->dwType == MIB_IF_TYPE_LOOPBACK) ret = JNI_TRUE; free(ifRowP); } return ret; } }
/* * Class: java_net_NetworkInterface * Method: isUp0 * Signature: (Ljava/lang/String;)Z */ JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0 (JNIEnv *env, jclass cls, jstring name, jint index) { jboolean ret = JNI_FALSE; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_isUp0_XP(env, cls, name, index); } else { MIB_IFROW *ifRowP; ifRowP = getIF(index); if (ifRowP != NULL) { ret = ifRowP->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP && (ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL || ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED); free(ifRowP); } } return ret; }
/* * Class: java_net_NetworkInterface * Method: getByName0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 (JNIEnv *env, jclass cls, jstring name) { netif *ifList, *curr; jboolean isCopy; const char *name_utf; jobject netifObj = NULL; if (os_supports_ipv6 && ipv6_available()) { return Java_java_net_NetworkInterface_getByName0_XP (env, cls, name); } /* get the list of interfaces */ if ((*enumInterfaces_fn)(env, &ifList) < 0) { return NULL; } /* get the name as a C string */ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); /* Search by name */ curr = ifList; while (curr != NULL) { if (strcmp(name_utf, curr->name) == 0) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr != NULL) {; netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the UTF string */ (*env)->ReleaseStringUTFChars(env, name, name_utf); /* release the interface list */ free_netif(ifList); return netifObj; }
/* * Class: java_net_NetworkInterface * Method: isP2P0 * Signature: (Ljava/lang/String;I)Z */ JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0 (JNIEnv *env, jclass cls, jstring name, jint index) { MIB_IFROW *ifRowP; jboolean ret = JNI_FALSE; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_isP2P0_XP(env, cls, name, index); } else { ifRowP = getIF(index); if (ifRowP != NULL) { switch(ifRowP->dwType) { case MIB_IF_TYPE_PPP: case MIB_IF_TYPE_SLIP: ret = JNI_TRUE; break; } free(ifRowP); } } return ret; }
/* If address types is IPv6, then IPv6 must be available. Otherwise * no address can be generated. Note if an IPv4 mapped address is passed * an IPv4 sockaddr_in will be returned. */ JNIEXPORT int JNICALL NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, int *len, jboolean isLocalAddr) { jint family, iafam; iafam = (*env)->GetIntField(env, iaObj, ia_familyID); family = (iafam == IPv4)? AF_INET : AF_INET6; if (ipv6_available() && family==AF_INET6) { struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him; jbyteArray ipaddress; jbyte caddr[16]; jint address, scopeid; ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID); scopeid = (jint)(*env)->GetIntField(env, iaObj, ia6_scopeidID); (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); memset((char *)him6, 0, sizeof(struct SOCKADDR_IN6)); him6->sin6_port = (u_short) htons((u_short)port); memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) ); him6->sin6_family = AF_INET6; him6->sin6_scope_id = scopeid; *len = sizeof(struct SOCKADDR_IN6) ; } else { struct sockaddr_in *him4 = (struct sockaddr_in*)him; jint address; if (family != AF_INET) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable"); return -1; } memset((char *) him4, 0, sizeof(struct sockaddr_in)); address = (int)(*env)->GetIntField(env, iaObj, ia_addressID); him4->sin_port = htons((short) port); him4->sin_addr.s_addr = (u_long) htonl(address); him4->sin_family = AF_INET; *len = sizeof(struct sockaddr_in); } return 0; }
/* * Class: sun_nio_ch_sctp_SctpNet * Method: socket0 * Signature: (Z)I */ JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpNet_socket0 (JNIEnv *env, jclass klass, jboolean oneToOne) { int fd; struct sctp_event_subscribe event; #ifdef AF_INET6 int domain = ipv6_available() ? AF_INET6 : AF_INET; #else int domain = AF_INET; #endif /* Try to load the socket API extension functions */ if (!funcsLoaded && !loadSocketExtensionFuncs(env)) { return 0; } fd = socket(domain, (oneToOne ? SOCK_STREAM : SOCK_SEQPACKET), IPPROTO_SCTP); if (fd < 0) { return handleSocketError(env, errno); } /* Enable events */ memset(&event, 0, sizeof(event)); event.sctp_data_io_event = 1; event.sctp_association_event = 1; event.sctp_address_event = 1; event.sctp_send_failure_event = 1; //event.sctp_peer_error_event = 1; event.sctp_shutdown_event = 1; //event.sctp_partial_delivery_event = 1; //event.sctp_adaptation_layer_event = 1; if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) { handleSocketError(env, errno); } return fd; }
/* * Create the marker file descriptor by establishing a loopback connection * which we shutdown but do not close the fd. The result is an fd that * can be used for read/write. */ static int getMarkerFD() { int server_fd, child_fd, connect_fd; SOCKADDR him; int type, len, port; type = AF_INET; #ifdef AF_INET6 if (ipv6_available()) { type = AF_INET6; } #endif /* * Create listener on any port */ server_fd = JVM_Socket(type, SOCK_STREAM, 0); if (server_fd < 0) { return -1; } if (JVM_Listen(server_fd, 1) == -1) { JVM_SocketClose(server_fd); return -1; } len = SOCKADDR_LEN; if (JVM_GetSockName(server_fd, (struct sockaddr *)&him, &len) == -1) { JVM_SocketClose(server_fd); return -1; } port = NET_GetPortFromSockaddr((struct sockaddr *)&him); /* * Establish connection from client socket. * Server is bound to 0.0.0.0/X or ::/X * We connect to 127.0.0.1/X or ::1/X */ #ifdef AF_INET6 if (ipv6_available()) { struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&him; jbyte caddr[16]; memset((char *) caddr, 0, 16); caddr[15] = 1; memset((char *)him6, 0, sizeof(struct sockaddr_in6)); memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) ); him6->sin6_port = htons((short) port); him6->sin6_family = AF_INET6; len = sizeof(struct sockaddr_in6) ; } else #endif /* AF_INET6 */ { struct sockaddr_in *him4 = (struct sockaddr_in*)&him; memset((char *) him4, 0, sizeof(struct sockaddr_in)); him4->sin_port = htons((short) port); him4->sin_addr.s_addr = (uint32_t) htonl(0x7f000001); him4->sin_family = AF_INET; len = sizeof(struct sockaddr_in); } connect_fd = JVM_Socket(type, SOCK_STREAM, 0); if (connect_fd < 0) { JVM_SocketClose(server_fd); return -1; } if (JVM_Connect(connect_fd, (struct sockaddr *) &him, len) == -1) { JVM_SocketClose(server_fd); JVM_SocketClose(connect_fd); return -1; } /* * Server accepts connection - do in in non-blocking mode to avoid * hanging if there's an error (should never happen!!!) */ SET_NONBLOCKING(server_fd); len = SOCKADDR_LEN; child_fd = JVM_Accept(server_fd, (struct sockaddr *)&him, (jint *)&len); if (child_fd == -1) { JVM_SocketClose(server_fd); JVM_SocketClose(connect_fd); return -1; } /* * Finally shutdown connect_fd (any reads to this fd will get * EOF; any writes will get an error). */ JVM_SocketShutdown(connect_fd, 2); JVM_SocketClose(child_fd); JVM_SocketClose(server_fd); return connect_fd; }
JNIEXPORT jboolean JNICALL Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl) { return (ipv6_available()) ? JNI_TRUE : JNI_FALSE; }
/* * Class: java_net_NetworkInterface * Method: getByInetAddress0 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 (JNIEnv *env, jclass cls, jobject iaObj) { netif *ifList, *curr; jint addr = getInetAddress_addr(env, iaObj); jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* * Enumerate the addresses on each interface until we find a * matching address. */ curr = ifList; while (curr != NULL) { int count; netaddr *addrList; netaddr *addrP; /* enumerate the addresses on this interface */ count = enumAddresses_win(env, curr, &addrList); if (count < 0) { free_netif(ifList); return NULL; } /* iterate through each address */ addrP = addrList; while (addrP != NULL) { if ((unsigned long)addr == ntohl(addrP->addr.him4.sin_addr.s_addr)) { break; } addrP = addrP->next; } /* * Address matched so create NetworkInterface for this interface * and address list. */ if (addrP != NULL) { /* createNetworkInterface will free addrList */ netifObj = createNetworkInterface(env, curr, count, addrList); break; } /* on next interface */ curr = curr->next; } /* release the interface list */ free_netif(ifList); return netifObj; }