Friday, May 20, 2011

libpcap for Android


The Android project includes libpcap as an external library as can be seen from the source here on kernel.org and Github

My project for Google Summer of Code - The mobile network scanner requires the use of libpcap or tcpdump. I was successful in compiling libpcap from its source and loading the library to use the native functions in JNI. But since an Android application does not run with Root privileges, it is a challenge to get the native functions to work in the same process.

The native code and the Java code for an android application runs in the same process. So the native code does not have root privileges. So as of now, it is not possible to get libpcap functions to work using the NDK. But there are alternatives which I will be suggesting in this blog post.

First of all, here are the instructions to successfully compile the libpcap.so library for use in the JNI code.

Create a folder called jni in the application root.

Android.mk

LOCAL_PATH := ./jni  

include $(CLEAR_VARS)  
LOCAL_MODULE    := pcaptest  
LOCAL_SRC_FILES := libpcap-native.c  

LOCAL_C_INCLUDES := $(NDK_ROOT)/external/libpcap   

LOCAL_STATIC_LIBRARIES := libpcap  

LOCAL_LDLIBS := -ldl -llog  

include $(BUILD_SHARED_LIBRARY)   

include $(NDK_ROOT)/external/libpcap/Android.mk  

Libpcap for android is built as a static library and its functions are then used as a shared library.
A shared library build specifications are defined in the Android.mk make file in the JNI folder of the project. The JNI folder contains the make files for the library. It also contains the native C code with function definitions according to the Java package.


This is a sample JNI code for getting the list of available network interfaces by using the pcap_lookupdevs function

#include   
#include   
#include   
#include   

#define DEBUG_TAG "Sample_LIBPCAP_DEBUGGING"  

void Java_org_umit_android_libpcaptest_libpcaptest_testLog(JNIEnv *env, jclass clazz, jstring message)  
{  
    char errbuf[1024];  
    errbuf[0] = '\0';  

    char *szLogThis;  
    char *dev = pcap_lookupdev(errbuf);  

    if (dev == NULL) {  
        szLogThis = "Couldn't find default device";       
    }  
    else szLogThis = dev;  

    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "Device status: [%s]", szLogThis);  
    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "errbuf [%s]", errbuf);  

    (*env)->ReleaseStringUTFChars(env, message, szLogThis);  
}  
The C code can now be called as native functions from inside Java code by loading the shared library

static{  
    System.loadLibrary("pcaptest");  
}  

private native void testLog(String logThis);  



The native code needs to compiled with ndk-build command and requires the android-ndk to be downloaded from the official website.

For now, I am getting the error

D/Sample_LIBPCAP_DEBUGGING( 364): Device status: [Couldn't open device]

                                          
D/Sample_LIBPCAP_DEBUGGING( 364): errbuf [socket: Operation not permitted]



And when I try and use the pcap_open_live function, I get the following error
 D/Sample_LIBPCAP_DEBUGGING(  310): errbuf [socket: Operation not permitted]

The reason for this error is that the native code and the application both lie in the same process. Invoking a "su" here would not work because an "su" just forks a new process that has root privileges but that process would not contain our native code.

So a work around for this is that a binary or a unix library should be compiled before hand and then supplied with the apk. The binary can be extracted from the apk. The binary may require root privileges but it would be as easy as forking another process with "su" command.

Here is a blog post explaining that http://nerdposts.blogspot.com/2010/11/android-superuser-shared-jni-libs.html

For now, I am just sticking to tcpdump for the requirements of this project. If we need a specific implementation of packet sniffing from libpcap, the plan is to compile a binary or a unix shared library and supply it with the apk.

8 comments:

  1. Sunday, November 06, 2011 6:17:00 AM
    Reply
  2. Sunday, November 06, 2011 6:19:00 AM
    Reply
  3. Thursday, December 29, 2011 3:37:00 PM
    Reply
  4. Monday, April 02, 2012 2:59:00 PM
    Reply
  5. Sunday, April 22, 2012 8:53:00 AM
    Reply
  6. Thursday, June 14, 2012 6:08:00 AM
    Reply
  7. Monday, October 22, 2012 1:37:00 AM
    Reply
  8. Monday, March 18, 2013 1:10:00 PM
    Reply

Newer Post Older Post Home