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 <jni.h>  
#include <string.h>  
#include <android/log.h>  
#include <pcap.h>  

#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.

Thursday, May 19, 2011

Using Apache Maven as a build manager for Android projects

Maven [1] is a powerful tool for managing and building Java projects. Naturally, it can also be used for Android projects. For this post, I will assume that the reader has some working knowledge of Maven. If not, the reader is referred to the Maven 5-minute guide [2].

Just like any Java project, an Android project that uses Maven as a build manager also has an underlying Project Object Model (POM). The POM is an XML file that contains all the information about the project. In case of Android, there's a Maven plugin [3] available that we will use.

The first order of the day is to install Apache Maven (v 2.2.1+). We don't need to explicitly install the Maven Android Plugin; That's a task that will seamlessly be handled by Maven for us, as we will later on see. After installing Maven, make sure that your ANDROID_HOME environment variable is set and $ANDROID_HOME/tools and $ANDROID_HOME/platform-tools are on your $PATH. If not, do so in your .bashrc file (in case of a Debian-based Linux distribution). Additionally, if you are an Eclipse user, make sure you install the Maven Integration for ADTs Eclipse plug-in [4].

Now that we have everything set-up, we add a pom.xml to our Android project. Following is a general template for pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
</project>

We will now add entities step by step to this POM (within the <project> </project> tags).

First and foremost, we need to configure the groupId, artifactId, version, packaging and name. Similar to:

<groupId>org.umit.icm.mobile</groupId>
<artifactId>icm-mobile</artifactId>
<version>1.0.0-test-maven</version>
<packaging>apk</packaging>
<name>UMITICMMobile</name>

Note that, the packaging is apk as opposed to the standard Java jar.

We now move on to dependencies. The most basic dependency for every Android project would obviously be the SDK. This dependency will be resolved from the Maven Central Repository. Assuming that we are using SDK 1.6:

<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.6_r2</version>
<scope>provided</scope>
</dependency>
</dependencies>

Finally, we add build information:

<build>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>maven-android-plugin</artifactId>
<version>2.8.4</version>
<configuration>
<sdk>
<platform>4</platform>
</sdk>
<emulator>
<avd>16</avd>
</emulator>
<deleteConflictingFiles>true</deleteConflictingFiles>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
</configuration>
<extensions>true</extensions>
</plugin>
</plugins>
</build>

As mentioned earlier, the Maven Android Plugin will automatically be downloaded and installed. It's important to highlight that SDK platform is 4 because we are working with SDK 1.6. Likewise, the name of the AVD device is 16.

Now, we are ready to build our project and deploy it on the AVD. Using the terminal, we go to the project root where the pom.xml is located. To build the project we simply issue the command:

mvn install

To deploy the apk to the device we use:

mvn android:deploy

Our application is now ready to be used on the emulator.

Eclipse users, instead of using the terminal, can import the project through File > Import > Maven > Existing Maven Projects. It is important to mention that Eclipse will not recognize the gen/ folder as a source folder automatically. To remedy this, we right-click on the project folder, followed by properties and Java Build Path. From here we go to Source and then Add Folder. We select the gen/ folder and click on OK twice.


Monday, May 16, 2011

i10n and L8n in Android

One of the strongest features of open source software is its global reachability. But sometimes language and local convention might be a hindrance. That's where Internationalization (i10n) and Localization (L8n) come in. The combination of both - known as Globalization - is a process which allows software to be molded according to local languages and convention without making any changes to the codebase, for example, changing the language from English to French or changing the currency symbol from the dollar to the pound.
Android by default allows the programmer to decouple the code and the non-code assets such as text, images and formatting. These "resources" are present under the res/ directory [1]. The default text for example is present inside res/values/strings.xml. For instance, if your default language is English and you want to allow your application's text to localize to French when the device's language is changed to French, the application would need to have an alternative locale-specific resource directory, res/values-fr/strings.xml in this case [2].
Let's now consider an example. We have an application interface which contains a button which should have the label "Send" in English and "Envoyer" in French. We first add the following line to res/values/strings.xml:

<string name="string_send">Send</string>

And then add

<string name="string_send">Envoyer</string>

to res/values-fr/strings.xml. Inside the layout XML for this button's interface, within the button's definition tag (<button></button>), we add android:text="@string/string_send". Essentially, what we have done is that by way of indirection, we have pointed the Android runtime to access our string resource using @string. To access the same string programmatically in Java we would use getString(R.string.string_send). Our button has now been localized to French. The same strategy can also be used to localize graphics, i.e. by providing graphics in both res/drawable/ and res/drawable-fr/. The two-letter ISO 639-1 code for other languages can be found at [3].

An extra tip: If you want to post XML code in your blog post for example, encode it using [4] instead of posting it directly because otherwise it will be treated as actionable HTML.

Saturday, May 14, 2011

Unstaged Changes in Git

Most of us are familiar with the staging area in git, i.e. the state between your working tree and your repository. To stage changes one has to make use of the command:
git add

The opposite of staging is unstaging which occurs when one makes changes to the local working tree but the changes are not reflected by the remote repository. For example, consider a file named foo inside a folder oldFolder. If foo is moved from one folder to another, say from oldFolder to newFolder, followed by git add, git commit and git push, in the local working tree foo would now be present inside newFolder instead of oldFolder, while in the remote repository foo would be present inside both newFolder and oldFolder. Both a git pull and git push would tell you that your working tree is up-to-date. Using git status one can see that there's one unstaged change pending, i.e. the deletion of foo from oldFolder. The simplest and most convenient way to handle this situation is using git-gui. To install git-gui on a Debian based Linux distribution use:

sudo apt-get install git-gui

Once git-gui has been installed, load it by typing git gui inside your working tree. On the top left corner under the heading "Unstaged Changes", all files that need to be unstaged will be listed. Now we simply select each file and click "Stage Changed". Once all files move under the heading "Staged Changes (Will Commit)", we need to click "Commit" after entering a commit message. Finally, clicking on "Push" will push these unstaged changes to the remote repository.
Thank you Rodolfo Carvalho for the tip.

Monday, May 02, 2011

Umit Summer of Code 2011 - First Announcement

I'm pleased to announce the first selected students for Umit Summer of Code 2011. This year we had several students applying with really good ideas, and even had some of them working on their proposals before the actual beginning of the USoC. Please, join me welcoming our talented USoC 2010 team:

  • Gautam Bajaj will be working on an open source mobile application to Android which aims to sniff packets. The main goal is to create an abstraction quite similar of what PacketManipulator does for the Desktop Version.
  • Charith Madusanka is a student that has a lot of experience with Web developing and will be helping us out in our Cloud initiatives.
  • Tiago Serra is going to work on PacketManipulator improvements, and also with our Audit Framework.
  • Gunjan Bansal is one of our USoC 2010 participant and this year is back for another around. He is the author of NetPID plugin and integration of BTSniffer in PacketManipulator. This year he'll be helping us out with the Packet Manipulator.
  • Niteesh Kumar is another student from USoC 2010. Last year he had contributed with improvements on the Message Sequence Chart Plugin. Moreover, he did a Umit Bluetooth integration that lives nowadays in the trunk branch of Network Scanner. This year he will continue his work with the Network Scanner and plans to contribute with the Packet Tracker Platform.
  • Eugene Melnichenko is a aiming at delivering some Zion improvements.
  • Amit Pal is a student that will get his hands dirty with our Cloud initiatives.
  • Dhritiman Hazarika is going to work in the Internet Connectivity Monitor team.
  • Anurag Panda proposed to work with Network Scanner.
  • Thiago Carísio will be working on new audits for the Packet Manipulator.
  • Anunay Inuganti is proposing to work on decoding of protocols for our Packet Manipulator.
  • Paul Pei will work in Internet Connectivity Monitor.
  • Thales Ribeiro will work on our Android Mobile initiatives.

This is our team for Umit Summer of Code 2011, and I'm pretty sure it is a winning one. Moreover, they will interect with other members of community and others mentors. As a community we're thrilled to have these ultra talented students helping us improve Umit's Open Source Softwares and make life easier for Network Administrators and Developers. Several kudos for all of you, and let the Umit Summer of Code begin!


PS: On the next steps - We’re creating a special mailing list for usoc purposes, and will be adding all of you to it. As soon as we get that done, we’ll be able to actually get started!