/* * Class: es_tid_rocksaw_net_RawSocket * Method: __query_routing_interface * Signature: (II[B[B)I */ JNIEXPORT jint JNICALL Java_es_tid_rocksaw_net_RawSocket__1_1query_1routing_1interface (JNIEnv *env, jclass cls, jint socket, jint family, jbyteArray destination, jbyteArray source) { int result = 0; #if defined(_WIN32) struct sockaddr_storage ifc; DWORD size; struct sockaddr *saddr; socklen_t socklen; union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } sin; if(family == PF_INET) { socklen = sizeof(sin.sin); saddr = init_sockaddr_in(env, &sin.sin, destination); } else if(family == PF_INET6) { socklen = sizeof(sin.sin6); saddr = init_sockaddr_in6(env, &sin.sin6, destination); } else return -1; result = WSAIoctl(socket, SIO_ROUTING_INTERFACE_QUERY, saddr, socklen, (struct sockaddr *)&ifc, sizeof(ifc), &size, NULL, NULL); if(result != SOCKET_ERROR) { jbyte *buf = (*env)->GetByteArrayElements(env, source, NULL); if(ifc.ss_family == PF_INET6) { memcpy(buf, &((struct sockaddr_in6*)&ifc)->sin6_addr, sizeof(struct in6_addr)); } else { memcpy(buf, &((struct sockaddr_in*)&ifc)->sin_addr, sizeof(struct in_addr)); } (*env)->ReleaseByteArrayElements(env, source, buf, 0); } #endif return result; }
/* * Class: es_tid_rocksaw_net_RawSocket * Method: __bind * Signature: (II[B)I */ JNIEXPORT jint JNICALL Java_es_tid_rocksaw_net_RawSocket__1_1bind (JNIEnv *env, jclass cls, jint socket, jint family, jbyteArray address) { struct sockaddr *saddr; socklen_t socklen; union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } sin; if(family == PF_INET) { socklen = sizeof(sin.sin); saddr = init_sockaddr_in(env, &sin.sin, address); } else if(family == PF_INET6) { socklen = sizeof(sin.sin6); saddr = init_sockaddr_in6(env, &sin.sin6, address); } else return -1; return bind(socket, saddr, socklen); }
/* * Class: com_savarese_rocksaw_net_RawSocket * Method: __sendto * Signature: (I[BIII[B)I */ JNIEXPORT jint JNICALL Java_com_savarese_rocksaw_net_RawSocket__1_1sendto (JNIEnv *env, jclass cls, jint socket, jbyteArray data, jint offset, jint len, jint family, jbyteArray address, jint scope_id) { int result; jbyte *buf; union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } sin; struct sockaddr *saddr; socklen_t socklen; if(family == PF_INET) { socklen = sizeof(sin.sin); saddr = init_sockaddr_in(env, &sin.sin, address); } else if(family == PF_INET6) { socklen = sizeof(sin.sin6); saddr = init_sockaddr_in6(env, &sin.sin6, address, scope_id); } else { errno = EINVAL; return errno; } buf = (*env)->GetByteArrayElements(env, data, NULL); result = sendto(socket, buf+offset, len, 0, saddr, socklen); (*env)->ReleaseByteArrayElements(env, data, buf, JNI_ABORT); #if defined(_WIN32) if(result < 0) errno = WSAGetLastError(); #endif return result; }