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