aboutsummaryrefslogtreecommitdiffstats
path: root/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontends/android/jni/libandroidbridge/vpnservice_builder.c')
-rw-r--r--src/frontends/android/jni/libandroidbridge/vpnservice_builder.c274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c b/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c
new file mode 100644
index 000000000..6ff732520
--- /dev/null
+++ b/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012 Giuliano Grassi
+ * Copyright (C) 2012 Ralf Sager
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "vpnservice_builder.h"
+#include "android_jni.h"
+
+#include <debug.h>
+#include <library.h>
+
+typedef struct private_vpnservice_builder_t private_vpnservice_builder_t;
+
+/**
+ * private data of vpnservice_builder
+ */
+struct private_vpnservice_builder_t {
+
+ /**
+ * public interface
+ */
+ vpnservice_builder_t public;
+
+ /**
+ * Java object
+ */
+ jobject builder;
+};
+
+METHOD(vpnservice_builder_t, add_address, bool,
+ private_vpnservice_builder_t *this, host_t *addr)
+{
+ JNIEnv *env;
+ jmethodID method_id;
+ jstring str;
+ char buf[INET_ADDRSTRLEN];
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: adding interface address %H", addr);
+
+ if (addr->get_family(addr) != AF_INET)
+ {
+ goto failed;
+ }
+ if (snprintf(buf, sizeof(buf), "%H", addr) >= sizeof(buf))
+ {
+ goto failed;
+ }
+
+ method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
+ "addAddress", "(Ljava/lang/String;I)Z");
+ if (!method_id)
+ {
+ goto failed;
+ }
+ str = (*env)->NewStringUTF(env, buf);
+ if (!str)
+ {
+ goto failed;
+ }
+ if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, 32))
+ {
+ goto failed;
+ }
+ androidjni_detach_thread();
+ return TRUE;
+
+failed:
+ DBG1(DBG_LIB, "builder: failed to add address");
+ androidjni_exception_occurred(env);
+ androidjni_detach_thread();
+ return FALSE;
+}
+
+METHOD(vpnservice_builder_t, set_mtu, bool,
+ private_vpnservice_builder_t *this, int mtu)
+{
+ JNIEnv *env;
+ jmethodID method_id;
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: setting MTU to %d", mtu);
+
+ method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
+ "setMtu", "(I)Z");
+ if (!method_id)
+ {
+ goto failed;
+ }
+ if (!(*env)->CallBooleanMethod(env, this->builder, method_id, mtu))
+ {
+ goto failed;
+ }
+ androidjni_detach_thread();
+ return TRUE;
+
+failed:
+ DBG1(DBG_LIB, "builder: failed to set MTU");
+ androidjni_exception_occurred(env);
+ androidjni_detach_thread();
+ return FALSE;
+}
+
+METHOD(vpnservice_builder_t, add_route, bool,
+ private_vpnservice_builder_t *this, host_t *net, int prefix)
+{
+ JNIEnv *env;
+ jmethodID method_id;
+ jstring str;
+ char buf[INET_ADDRSTRLEN];
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: adding route %+H/%d", net, prefix);
+
+ if (net->get_family(net) != AF_INET)
+ {
+ goto failed;
+ }
+ if (snprintf(buf, sizeof(buf), "%+H", net) >= sizeof(buf))
+ {
+ goto failed;
+ }
+
+ method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
+ "addRoute", "(Ljava/lang/String;I)Z");
+ if (!method_id)
+ {
+ goto failed;
+ }
+ str = (*env)->NewStringUTF(env, buf);
+ if (!str)
+ {
+ goto failed;
+ }
+ if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, prefix))
+ {
+ goto failed;
+ }
+ androidjni_detach_thread();
+ return TRUE;
+
+failed:
+ DBG1(DBG_LIB, "builder: failed to add route");
+ androidjni_exception_occurred(env);
+ androidjni_detach_thread();
+ return FALSE;
+}
+
+METHOD(vpnservice_builder_t, add_dns, bool,
+ private_vpnservice_builder_t *this, host_t *dns)
+{
+ JNIEnv *env;
+ jmethodID method_id;
+ jstring str;
+ char buf[INET_ADDRSTRLEN];
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: adding DNS server %H", dns);
+
+ if (dns->get_family(dns) != AF_INET)
+ {
+ goto failed;
+ }
+ if (snprintf(buf, sizeof(buf), "%H", dns) >= sizeof(buf))
+ {
+ goto failed;
+ }
+
+ method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
+ "addDnsServer", "(Ljava/lang/String;)Z");
+ if (!method_id)
+ {
+ goto failed;
+ }
+ str = (*env)->NewStringUTF(env, buf);
+ if (!str)
+ {
+ goto failed;
+ }
+ if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str))
+ {
+ goto failed;
+ }
+ androidjni_detach_thread();
+ return TRUE;
+
+failed:
+ DBG1(DBG_LIB, "builder: failed to add DNS server");
+ androidjni_exception_occurred(env);
+ androidjni_detach_thread();
+ return FALSE;
+}
+
+METHOD(vpnservice_builder_t, establish, int,
+ private_vpnservice_builder_t *this)
+{
+ JNIEnv *env;
+ jmethodID method_id;
+ int fd;
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: building TUN device");
+
+ method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
+ "establish", "()I");
+ if (!method_id)
+ {
+ goto failed;
+ }
+ fd = (*env)->CallIntMethod(env, this->builder, method_id);
+ if (fd == -1)
+ {
+ goto failed;
+ }
+ androidjni_detach_thread();
+ return fd;
+
+failed:
+ DBG1(DBG_LIB, "builder: failed to build TUN device");
+ androidjni_exception_occurred(env);
+ androidjni_detach_thread();
+ return -1;
+}
+
+METHOD(vpnservice_builder_t, destroy, void,
+ private_vpnservice_builder_t *this)
+{
+ JNIEnv *env;
+
+ androidjni_attach_thread(&env);
+ (*env)->DeleteGlobalRef(env, this->builder);
+ androidjni_detach_thread();
+ free(this);
+}
+
+vpnservice_builder_t *vpnservice_builder_create(jobject builder)
+{
+ JNIEnv *env;
+ private_vpnservice_builder_t *this;
+
+ INIT(this,
+ .public = {
+ .add_address = _add_address,
+ .add_route = _add_route,
+ .add_dns = _add_dns,
+ .set_mtu = _set_mtu,
+ .establish = _establish,
+ .destroy = _destroy,
+ },
+ );
+
+ androidjni_attach_thread(&env);
+ this->builder = (*env)->NewGlobalRef(env, builder);
+ androidjni_detach_thread();
+
+ return &this->public;
+}