#ifdef __CYGWIN__ #include #define __int64 uint64_t #endif #ifdef _WIN32 #include #include #include #endif #include #include "natpmp.h" #include "fr_free_miniupnp_libnatpmp_NatPmp.h" #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_init (JNIEnv *env, jobject obj, jint forcegw, jint forcedgw) { natpmp_t *p = malloc (sizeof(natpmp_t)); if (p == NULL) return; initnatpmp(p, forcegw, (in_addr_t) forcedgw); jobject wrapped = (*env)->NewDirectByteBuffer(env, p, sizeof(natpmp_t)); if (wrapped == NULL) return; jclass thisClass = (*env)->GetObjectClass(env,obj); if (thisClass == NULL) return; jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); if (fid == NULL) return; (*env)->SetObjectField(env, obj, fid, wrapped); } JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_free (JNIEnv *env, jobject obj) { jclass thisClass = (*env)->GetObjectClass(env,obj); if (thisClass == NULL) return; jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); if (fid == NULL) return; jobject wrapped = (*env)->GetObjectField(env, obj, fid); if (wrapped == NULL) return; natpmp_t* natpmp = (natpmp_t*) (*env)->GetDirectBufferAddress(env, wrapped); closenatpmp(natpmp); if (natpmp == NULL) return; free(natpmp); (*env)->SetObjectField(env, obj, fid, NULL); } static natpmp_t* getNatPmp(JNIEnv* env, jobject obj) { jclass thisClass = (*env)->GetObjectClass(env,obj); if (thisClass == NULL) return NULL; jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); if (fid == NULL) return NULL; jobject wrapped = (*env)->GetObjectField(env, obj, fid); if (wrapped == NULL) return NULL; natpmp_t* natpmp = (natpmp_t*) (*env)->GetDirectBufferAddress(env, wrapped); return natpmp; } JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_sendPublicAddressRequest(JNIEnv* env, jobject obj) { natpmp_t* natpmp = getNatPmp(env, obj); if (natpmp == NULL) return -1; return sendpublicaddressrequest(natpmp); } JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_startup(JNIEnv* env, jclass cls) { (void)env; (void)cls; #ifdef _WIN32 WSADATA wsaData; WORD wVersionRequested = MAKEWORD(2, 2); WSAStartup(wVersionRequested, &wsaData); #endif } JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_sendNewPortMappingRequest(JNIEnv* env, jobject obj, jint protocol, jint privateport, jint publicport, jint lifetime) { natpmp_t* natpmp = getNatPmp(env, obj); if (natpmp == NULL) return -1; return sendnewportmappingrequest(natpmp, protocol, privateport, publicport, lifetime); } JNIEXPORT jlong JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_getNatPmpRequestTimeout(JNIEnv* env, jobject obj) { natpmp_t* natpmp = getNatPmp(env, obj); struct timeval timeout; getnatpmprequesttimeout(natpmp, &timeout); return ((jlong) timeout.tv_sec) * 1000 + (timeout.tv_usec / 1000); } #define SET_FIELD(prefix, name, type, longtype) { \ jfieldID fid = (*env)->GetFieldID(env, thisClass, #name, type); \ if (fid == NULL) return -1; \ (*env)->Set ## longtype ## Field(env, response, fid, resp. prefix name); \ } JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_readNatPmpResponseOrRetry(JNIEnv* env, jobject obj, jobject response) { natpmp_t* natpmp = getNatPmp(env, obj); natpmpresp_t resp; int result = readnatpmpresponseorretry(natpmp, &resp); if (result != 0) { return result; } jclass thisClass = (*env)->GetObjectClass(env, response); if (thisClass == NULL) return -1; SET_FIELD(,type, "S", Short); SET_FIELD(,resultcode, "S", Short); jfieldID fid = (*env)->GetFieldID(env, thisClass, "epoch", "J"); if (fid == NULL) return -1; (*env)->SetLongField(env, response, fid, ((jlong)resp.epoch) * 1000); if (resp.type == 0) { jfieldID fid = (*env)->GetFieldID(env, thisClass, "addr", "I"); if (fid == NULL) return -1; (*env)->SetIntField(env, response, fid, resp.pnu.publicaddress.addr.s_addr); } else { SET_FIELD(pnu.newportmapping., privateport, "I", Int); SET_FIELD(pnu.newportmapping., mappedpublicport, "I", Int); jfieldID fid = (*env)->GetFieldID(env, thisClass, "lifetime", "J"); if (fid == NULL) return -1; (*env)->SetLongField(env, response, fid, ((jlong) resp.pnu.newportmapping.lifetime) * 1000 * 1000); } return result; } #ifdef __cplusplus } #endif