diff --git a/src/frontends/android/jni/libandroidbridge/Android.mk b/src/frontends/android/jni/libandroidbridge/Android.mk index f47e39656..b1fa4d1cb 100644 --- a/src/frontends/android/jni/libandroidbridge/Android.mk +++ b/src/frontends/android/jni/libandroidbridge/Android.mk @@ -11,6 +11,7 @@ backend/android_service.c backend/android_service.h \ charonservice.c charonservice.h \ kernel/android_ipsec.c kernel/android_ipsec.h \ kernel/android_net.c kernel/android_net.h \ +kernel/network_manager.c kernel/network_manager.h \ vpnservice_builder.c vpnservice_builder.h # build libandroidbridge ------------------------------------------------------- diff --git a/src/frontends/android/jni/libandroidbridge/kernel/network_manager.c b/src/frontends/android/jni/libandroidbridge/kernel/network_manager.c new file mode 100644 index 000000000..e7bcf1365 --- /dev/null +++ b/src/frontends/android/jni/libandroidbridge/kernel/network_manager.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 . * + * 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 "network_manager.h" + +#include "../android_jni.h" +#include + +typedef struct private_network_manager_t private_network_manager_t; + +struct private_network_manager_t { + + /** + * Public interface + */ + network_manager_t public; + + /** + * Reference to NetworkManager object + */ + jobject obj; + + /** + * Java class for NetworkManager + */ + jclass cls; +}; + +METHOD(network_manager_t, get_local_address, host_t*, + private_network_manager_t *this, bool ipv4) +{ + JNIEnv *env; + jmethodID method_id; + jstring jaddr; + char *addr; + host_t *host; + + androidjni_attach_thread(&env); + method_id = (*env)->GetMethodID(env, this->cls, "getLocalAddress", + "(Z)Ljava/lang/String;"); + if (!method_id) + { + goto failed; + } + jaddr = (*env)->CallObjectMethod(env, this->obj, method_id, ipv4); + if (!jaddr) + { + goto failed; + } + addr = androidjni_convert_jstring(env, jaddr); + androidjni_detach_thread(); + host = host_create_from_string(addr, 0); + free(addr); + return host; + +failed: + androidjni_exception_occurred(env); + androidjni_detach_thread(); + return NULL; +} + +METHOD(network_manager_t, destroy, void, + private_network_manager_t *this) +{ + JNIEnv *env; + + androidjni_attach_thread(&env); + if (this->obj) + { + (*env)->DeleteGlobalRef(env, this->obj); + } + if (this->cls) + { + (*env)->DeleteGlobalRef(env, this->cls); + } + androidjni_detach_thread(); + free(this); +} + +/* + * Described in header. + */ +network_manager_t *network_manager_create() +{ + private_network_manager_t *this; + JNIEnv *env; + jmethodID method_id; + jobject obj; + jclass cls; + + INIT(this, + .public = { + .get_local_address = _get_local_address, + .destroy = _destroy, + }, + ); + + androidjni_attach_thread(&env); + cls = (*env)->FindClass(env, JNI_PACKAGE_STRING "/NetworkManager"); + if (!cls) + { + goto failed; + } + this->cls = (*env)->NewGlobalRef(env, cls); + method_id = (*env)->GetMethodID(env, cls, "", + "()V"); + if (!method_id) + { + goto failed; + } + obj = (*env)->NewObject(env, cls, method_id); + if (!obj) + { + goto failed; + } + this->obj = (*env)->NewGlobalRef(env, obj); + androidjni_detach_thread(); + return &this->public; + +failed: + DBG1(DBG_KNL, "failed to build NetworkManager object"); + androidjni_exception_occurred(env); + androidjni_detach_thread(); + destroy(this); + return NULL; +}; diff --git a/src/frontends/android/jni/libandroidbridge/kernel/network_manager.h b/src/frontends/android/jni/libandroidbridge/kernel/network_manager.h new file mode 100644 index 000000000..cb0da7fa2 --- /dev/null +++ b/src/frontends/android/jni/libandroidbridge/kernel/network_manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 . + * + * 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. + */ + +/** + * @defgroup network_manager network_manager + * @{ @ingroup kernel_android + */ + +#ifndef NETWORK_MANAGER_H_ +#define NETWORK_MANAGER_H_ + +#include + +#include +#include + +typedef struct network_manager_t network_manager_t; + +/** + * NetworkManager, used to retrieve local IP addresses. + * + * Communicates with NetworkManager via JNI + */ +struct network_manager_t { + + /** + * Get a local address + * + * @param ipv4 TRUE to get an IPv4 address + * @return the address or NULL if none available + */ + host_t *(*get_local_address)(network_manager_t *this, bool ipv4); + + /** + * Destroy a network_manager_t instance + */ + void (*destroy)(network_manager_t *this); +}; + +/** + * Create a network_manager_t instance + * + * @return network_manager_t instance + */ +network_manager_t *network_manager_create(); + +#endif /** NETWORK_MANAGER_H_ @}*/ diff --git a/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java b/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java new file mode 100644 index 000000000..d9ed49b34 --- /dev/null +++ b/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 . + * + * 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. + */ + +package org.strongswan.android.logic; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + +public class NetworkManager +{ + public NetworkManager() + { + } + + /** + * Function that retrieves a local address of the given family. + * + * @param ipv4 true to return an IPv4 address, false for IPv6 + * @return string representation of an IPv4 address, or null if none found + */ + public String getLocalAddress(boolean ipv4) + { + try + { + Enumeration en = NetworkInterface.getNetworkInterfaces(); + if (en == null) + { /* no interfaces at all */ + return null; + } + while (en.hasMoreElements()) + { + NetworkInterface intf = en.nextElement(); + if (intf.isLoopback() || !intf.isUp() || + intf.getName().startsWith("tun")) + { + continue; + } + Enumeration enumIpAddr = intf.getInetAddresses(); + while (enumIpAddr.hasMoreElements()) + { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (inetAddress.isLoopbackAddress()) + { + continue; + } + if ((ipv4 && inetAddress instanceof Inet4Address) || + (!ipv4 && inetAddress instanceof Inet6Address)) + { + return inetAddress.getHostAddress(); + } + } + } + } + catch (SocketException ex) + { + ex.printStackTrace(); + return null; + } + return null; + } +}