Native counterpart of VpnService.Builder added, exposed by charonservice
[strongswan.git] / src / frontends / android / jni / libandroidbridge / vpnservice_builder.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "vpnservice_builder.h"
19 #include "android_jni.h"
20
21 #include <debug.h>
22 #include <library.h>
23
24 typedef struct private_vpnservice_builder_t private_vpnservice_builder_t;
25
26 /**
27 * private data of vpnservice_builder
28 */
29 struct private_vpnservice_builder_t {
30
31 /**
32 * public interface
33 */
34 vpnservice_builder_t public;
35
36 /**
37 * Java object
38 */
39 jobject builder;
40 };
41
42 METHOD(vpnservice_builder_t, add_address, bool,
43 private_vpnservice_builder_t *this, host_t *addr)
44 {
45 JNIEnv *env;
46 jmethodID method_id;
47 jstring str;
48 char buf[INET_ADDRSTRLEN];
49
50 androidjni_attach_thread(&env);
51
52 DBG2(DBG_LIB, "builder: adding interface address %H", addr);
53
54 if (addr->get_family(addr) != AF_INET)
55 {
56 goto failed;
57 }
58 if (snprintf(buf, sizeof(buf), "%H", addr) >= sizeof(buf))
59 {
60 goto failed;
61 }
62
63 method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
64 "addAddress", "(Ljava/lang/String;I)Z");
65 if (!method_id)
66 {
67 goto failed;
68 }
69 str = (*env)->NewStringUTF(env, buf);
70 if (!str)
71 {
72 goto failed;
73 }
74 if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, 32))
75 {
76 goto failed;
77 }
78 androidjni_detach_thread();
79 return TRUE;
80
81 failed:
82 DBG1(DBG_LIB, "builder: failed to add address");
83 androidjni_exception_occurred(env);
84 androidjni_detach_thread();
85 return FALSE;
86 }
87
88 METHOD(vpnservice_builder_t, set_mtu, bool,
89 private_vpnservice_builder_t *this, int mtu)
90 {
91 JNIEnv *env;
92 jmethodID method_id;
93
94 androidjni_attach_thread(&env);
95
96 DBG2(DBG_LIB, "builder: setting MTU to %d", mtu);
97
98 method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
99 "setMtu", "(I)Z");
100 if (!method_id)
101 {
102 goto failed;
103 }
104 if (!(*env)->CallBooleanMethod(env, this->builder, method_id, mtu))
105 {
106 goto failed;
107 }
108 androidjni_detach_thread();
109 return TRUE;
110
111 failed:
112 DBG1(DBG_LIB, "builder: failed to set MTU");
113 androidjni_exception_occurred(env);
114 androidjni_detach_thread();
115 return FALSE;
116 }
117
118 METHOD(vpnservice_builder_t, add_route, bool,
119 private_vpnservice_builder_t *this, host_t *net, int prefix)
120 {
121 JNIEnv *env;
122 jmethodID method_id;
123 jstring str;
124 char buf[INET_ADDRSTRLEN];
125
126 androidjni_attach_thread(&env);
127
128 DBG2(DBG_LIB, "builder: adding route %+H/%d", net, prefix);
129
130 if (net->get_family(net) != AF_INET)
131 {
132 goto failed;
133 }
134 if (snprintf(buf, sizeof(buf), "%+H", net) >= sizeof(buf))
135 {
136 goto failed;
137 }
138
139 method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
140 "addRoute", "(Ljava/lang/String;I)Z");
141 if (!method_id)
142 {
143 goto failed;
144 }
145 str = (*env)->NewStringUTF(env, buf);
146 if (!str)
147 {
148 goto failed;
149 }
150 if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, prefix))
151 {
152 goto failed;
153 }
154 androidjni_detach_thread();
155 return TRUE;
156
157 failed:
158 DBG1(DBG_LIB, "builder: failed to add route");
159 androidjni_exception_occurred(env);
160 androidjni_detach_thread();
161 return FALSE;
162 }
163
164 METHOD(vpnservice_builder_t, add_dns, bool,
165 private_vpnservice_builder_t *this, host_t *dns)
166 {
167 JNIEnv *env;
168 jmethodID method_id;
169 jstring str;
170 char buf[INET_ADDRSTRLEN];
171
172 androidjni_attach_thread(&env);
173
174 DBG2(DBG_LIB, "builder: adding DNS server %H", dns);
175
176 if (dns->get_family(dns) != AF_INET)
177 {
178 goto failed;
179 }
180 if (snprintf(buf, sizeof(buf), "%H", dns) >= sizeof(buf))
181 {
182 goto failed;
183 }
184
185 method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
186 "addDnsServer", "(Ljava/lang/String;)Z");
187 if (!method_id)
188 {
189 goto failed;
190 }
191 str = (*env)->NewStringUTF(env, buf);
192 if (!str)
193 {
194 goto failed;
195 }
196 if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str))
197 {
198 goto failed;
199 }
200 androidjni_detach_thread();
201 return TRUE;
202
203 failed:
204 DBG1(DBG_LIB, "builder: failed to add DNS server");
205 androidjni_exception_occurred(env);
206 androidjni_detach_thread();
207 return FALSE;
208 }
209
210 METHOD(vpnservice_builder_t, establish, int,
211 private_vpnservice_builder_t *this)
212 {
213 JNIEnv *env;
214 jmethodID method_id;
215 int fd;
216
217 androidjni_attach_thread(&env);
218
219 DBG2(DBG_LIB, "builder: building TUN device");
220
221 method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
222 "establish", "()I");
223 if (!method_id)
224 {
225 goto failed;
226 }
227 fd = (*env)->CallIntMethod(env, this->builder, method_id);
228 if (fd == -1)
229 {
230 goto failed;
231 }
232 androidjni_detach_thread();
233 return fd;
234
235 failed:
236 DBG1(DBG_LIB, "builder: failed to build TUN device");
237 androidjni_exception_occurred(env);
238 androidjni_detach_thread();
239 return -1;
240 }
241
242 METHOD(vpnservice_builder_t, destroy, void,
243 private_vpnservice_builder_t *this)
244 {
245 JNIEnv *env;
246
247 androidjni_attach_thread(&env);
248 (*env)->DeleteGlobalRef(env, this->builder);
249 androidjni_detach_thread();
250 free(this);
251 }
252
253 vpnservice_builder_t *vpnservice_builder_create(jobject builder)
254 {
255 JNIEnv *env;
256 private_vpnservice_builder_t *this;
257
258 INIT(this,
259 .public = {
260 .add_address = _add_address,
261 .add_route = _add_route,
262 .add_dns = _add_dns,
263 .set_mtu = _set_mtu,
264 .establish = _establish,
265 .destroy = _destroy,
266 },
267 );
268
269 androidjni_attach_thread(&env);
270 this->builder = (*env)->NewGlobalRef(env, builder);
271 androidjni_detach_thread();
272
273 return &this->public;
274 }