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.
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
.
Meow!