Port Forwarding an Android Local Port

There don’t seem to be many reasons to want to forward a local Android port (listening for connections from localhost only) to a port that can be accessed externally (via LAN, etc.). There are some applications around that allow to forward an Android local port to another one but they offer a lot of overhead, are confusing and some even require root access.

Port Forwarding Android Ports With netcat

Compiling netcat for Android was the way I decided to go, it’s only known to be the “swiss-army knife” of networking. The Android source code contains a limited version of nc which can be compiled by the simple make nc (after having setup the build environment of course). This version of netcat does not offer port forwarding functionality.

Grabbing the latest GNU netcat source and compiling it against the NDK-provided toolchain was the next logical step. Compiling netcat for my Android device (it’s an unrooted Google Nexus One) was quite straight-forward. Compiling requires the NDK. Inside the $NDK/build/tools directory there’s a neat utility called make-standalone-toolchain.sh, invoke this with ./make-standalone-toolchain.sh --platform=android-9 --install-dir=/tmp/android-toolchain --ndk-dir=../../. This will install a standalone toolchain that can be used to compile C and C++ code for the Android ARM platform.

Head over to the netcat source and setup the cross-compilation environment variables by issuing export PATH=/tmp/android-toolchain/bin:$PATH and export CC=arm-linux-androideabi-gcc. Then ./configure --host=arm && make was enough, although I suspect some features may not work or segfault since I did not indicate the specific toolchain library paths. Compiling other software from source may require specifying the correct headers (look at ./configure --help).

The netcat binary ends up in the src directory. Issuing a file src/netcat on it should yield something like: netcat: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped (see how it uses shared library functions arm-linux-androideabi-readelf src/netcat -Ds, the correct way is to use the Android system headers for these provided by the toolchain and not the headers provided by default).

Native binaries for Android cannot be executed from any other context other than from /data/local/ without rooting the device. So adb push src/netcat /data/local/ should transfer an executable binary. Try it out adb shell /data/local/./netcat -l -p 9990 and nc [device IP] 9990 -v. Everything should work fine with both “cats” able to communicate.

Forwarding a local Android port requires one to adb shell /data/local/./netcat -L localhost:9990 -p 9998. This exposes the restricted 9990 port (one which refuses connections from anything but localhost) via port 9998 which is unfiltered by netcat.