diff options
author | Parménides GV <parmegv@sdf.org> | 2015-01-12 19:18:54 +0100 |
---|---|---|
committer | Parménides GV <parmegv@sdf.org> | 2015-01-12 19:18:54 +0100 |
commit | 32998b046977da5d272a948ad0668bf653d598f4 (patch) | |
tree | a8f68d5b09d7293ceb35211d2f26f48d4312fcf3 /app/jni | |
parent | 1d37f94a7980d1181a49863cb3880bc7938cc6d1 (diff) | |
parent | 6ed3fde3ea171700390552dd1040e10e8cc1ca32 (diff) |
Merge branch 'bug/Release-ConfigurationWizard-differs-from-debug's-#6633' into bug/ButterKnife-doesn't-find-provider_list_view-#6581
Diffstat (limited to 'app/jni')
-rw-r--r-- | app/jni/Android.mk | 3 | ||||
-rw-r--r-- | app/jni/jniglue.c | 3 | ||||
-rw-r--r-- | app/jni/jniglue.h | 9 | ||||
-rw-r--r-- | app/jni/scan_ifs.c | 109 |
4 files changed, 122 insertions, 2 deletions
diff --git a/app/jni/Android.mk b/app/jni/Android.mk index 90074b0f..df8cbb34 100644 --- a/app/jni/Android.mk +++ b/app/jni/Android.mk @@ -49,8 +49,9 @@ LOCAL_PATH := $(JNI_DIR) # The only real JNI library include $(CLEAR_VARS) LOCAL_LDLIBS := -llog -lz +LOCAL_CFLAGS = --std=c99 LOCAL_C_INCLUDES := openssl/include openssl/crypto openssl -LOCAL_SRC_FILES:= jniglue.c jbcrypto.cpp +LOCAL_SRC_FILES:= jniglue.c jbcrypto.cpp scan_ifs.c LOCAL_MODULE = opvpnutil LOCAL_SHARED_LIBRARIES := libcrypto include $(BUILD_SHARED_LIBRARY) diff --git a/app/jni/jniglue.c b/app/jni/jniglue.c index 36ad8fe7..d446f78c 100644 --- a/app/jni/jniglue.c +++ b/app/jni/jniglue.c @@ -1,7 +1,8 @@ #include <jni.h> #include <android/log.h> #include <stdlib.h> -#include <setjmp.h> +#include <unistd.h> + #include "jniglue.h" diff --git a/app/jni/jniglue.h b/app/jni/jniglue.h index a86d52da..8f813b64 100644 --- a/app/jni/jniglue.h +++ b/app/jni/jniglue.h @@ -10,3 +10,12 @@ #define xcopenvpn_jniglue_h void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,const char* m1); #endif + +#ifdef __cplusplus +extern "C" { +#endif + int jniThrowException(JNIEnv* env, const char* className, const char* msg); + +#ifdef __cplusplus +} +#endif diff --git a/app/jni/scan_ifs.c b/app/jni/scan_ifs.c new file mode 100644 index 00000000..e0024c54 --- /dev/null +++ b/app/jni/scan_ifs.c @@ -0,0 +1,109 @@ +#include <jni.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <sys/ioctl.h> +#include <linux/if.h> +#include <android/log.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include "jniglue.h" + +jobjectArray Java_de_blinkt_openvpn_core_NativeUtils_getIfconfig(JNIEnv* env) +{ + + int sd; + if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "Opening socket for intface get failed"); + //jniThrowException(env, "java/lang/IllegalArgumentException", "Opening socket for intface get failed"); + return NULL; + } + + struct ifreq ifs[23]; + + struct ifconf ifc; + ifc.ifc_req = ifs; + ifc.ifc_len = sizeof (ifs); + + if (ioctl (sd, SIOCGIFCONF, &ifc) < 0) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "IOCTL for intface get failed"); + //jniThrowException(env, "java/lang/IllegalArgumentException", "IOTCL socket for intface get failed"); + return NULL; + } + + + + + char buf[NI_MAXHOST]; + + int ji=0; + + /* + jtmp = (*env)->NewStringUTF(env, "HALLO WELT"); + (*env)->SetObjectArrayElement(env, ret, ji++, jtmp); + */ + + size_t num_intf=ifc.ifc_len / sizeof(struct ifreq); + jobjectArray ret= (jobjectArray) (*env)->NewObjectArray(env, num_intf*3,(*env)->FindClass(env, "java/lang/String"), NULL); + + for (struct ifreq* ifr = ifc.ifc_req; ifr < ifs + num_intf; ifr++) { + + if (ifr->ifr_addr.sa_family != AF_INET) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "NOT AF_INET: %s", ifr->ifr_name); + continue; + } + + /* get interface addr, prefilled by SIOGIFCONF */ + + int err; + if (err=getnameinfo(&ifr->ifr_addr, sizeof(struct sockaddr_in), buf, NI_MAXHOST, NULL, 0, + NI_NUMERICHOST) !=0) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "getnameinfo failed for %s: %s", ifr->ifr_name, gai_strerror(err)); + continue; + } + jstring jaddr = (*env)->NewStringUTF(env, buf); + jstring jname = (*env)->NewStringUTF(env, ifr->ifr_name); + + + struct ifreq ifreq; + strncpy (ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); + + /* interface is up */ + if (ioctl (sd, SIOCGIFFLAGS, &ifreq) < 0) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "SIOCGIFFLAGS failed for %s: %s", ifr->ifr_name, strerror(errno)); + continue; + } + + if (!(ifreq.ifr_flags & IFF_UP)) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "IFF_UP failed for %s", ifr->ifr_name); + continue; + } + + /* interface netmask */ + if (ioctl (sd, SIOCGIFNETMASK, &ifreq) < 0) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "SIOCIFNETMASK failed for %s: %s", ifr->ifr_name, strerror(errno)); + continue; + } + + if (err=getnameinfo(&ifreq.ifr_netmask, sizeof(struct sockaddr_in), buf, NI_MAXHOST, NULL, 0, + NI_NUMERICHOST) !=0) { + __android_log_print(ANDROID_LOG_DEBUG, "openvpn", "getnameinfo failed for %s: %s", ifr->ifr_name, gai_strerror(err)); + continue; + } + jstring jnetmask = (*env)->NewStringUTF(env, buf); + + (*env)->SetObjectArrayElement(env, ret, ji++, jname); + (*env)->SetObjectArrayElement(env, ret, ji++, jaddr); + (*env)->SetObjectArrayElement(env, ret, ji++, jnetmask); + } + if (sd >= 0) + close (sd); + + return ret; +} + |