[Android] [NDK] Cross-compiling iproute2
Posted On 01/03/2018
This is a short guide on how to cross-compile iproute2 on Android.
Where the sch_netem kernel module is available, tc – which comes with iproute2 – allows for traffic throttling/packet delay useful to test apps on slower internet connections.
The cross-compilation process will take place on Ubuntu 16.04 LTS (Last LTS as of 01/03), we will create dynamically linked executables using the Android NDK toolchain.
This guide primarily targets Android >= 5.0 (API 21), since Lollipop an additional security measure known as “position independent executables” is enforced, reducing the risk which come from exploiting bugs in the Android framework, hence additional gcc options are needed.
Step 1, downloading the NDK: (Version r12b)
You may download the NDK directly from Google, in alternative any mirror may be used:
git clone https://github.com/innogames/android-ndk
Note: make sure that under platforms/android-21/arch-arm/usr there is an include folder and a lib folder, we will be setting that folder as sysroot for gcc. This means gcc will be looking for libraries and include files in that folder and not in the system root.
Newer NDK versions may split the include and lib folder, the first being in the toolchain /sysroot folder and the second one being under /platforms
Myself, I downloaded the linux version r16b from Google and combined it with the libraries and include files found in the toolchain at the link above.
Step 2, downloading iproute2 sources
We will the using version iproute2-3.4.0, you may pick a later one if you wish.
Step 3, Editing the Makefile
We need to edit the Makefile file in the iproute2 folder and change some of the compilation options, or the build process will fail when using the NDK. Android uses a very limited version of glibc called bionic which greatly complicates things. Also, no DNS resolution library such as nresolv is available, so we need to disable that as well.
Edit the Makefile and change:
DEFINES= -DRESOLVE_HOSTNAMES -DLIBDIR=\”$(LIBDIR)\”
DEFINES= -DLIBDIR=\”$(LIBDIR)\” -D__ANDROID_API__=21
we also need to adjust the CC variable, and point make to the android toolchain:
CC = /home/ingamedeo/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc –sysroot=/root/android-ndk/platforms/android-21/arch-arm -fPIE -pie
/home/ingamedeo/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc with the path to arm-linux-androideabi-gcc (should be inside the folder you downloaded ealier from Google)
/root/android-ndk/platforms/android-21/arch-arm with the path to the usr folder with include and lib inside.
Note: When cross-compiling using the NDK you need to choose a specific platform target (in this example API 21, Android 5.0), the binary will work on any later version of Android. Also, if targeting Android 21 or later you need to add the flags -fPIE -pie to enable position independent executables as required by the more recent security measures.
You can now save the Makefile.
Step 4, Cross-compilation
We are all set, just run make and the compilation should succeed.
Step 5, using tc
We can now enter the tc folder and move the binary to the Android device,
adb push tc /data/local/tmp
adb shell /data/local/tmp/tc qdisc add dev eth0 root netem delay 100ms