File: natpmp-jni.c

package info (click to toggle)
libnatpmp 20150609-7.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 300 kB
  • sloc: ansic: 1,430; java: 312; makefile: 150; python: 23
file content (157 lines) | stat: -rw-r--r-- 4,583 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifdef __CYGWIN__
#include <stdint.h>
#define __int64 uint64_t
#endif

#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

#include <stdlib.h>
#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