Video Screencast Help
Security Community Blog

Monitoring Android Network Traffic Part II: Cross Compiling TCPDUMP

Created: 10 Feb 2014 • Updated: 18 Aug 2014
Vince Kornacki's picture
+5 5 Votes
Login to vote

In the previous installment we installed our mobile development toolchain. Let's keep the party rockin' and download the latest versions of LIBPCAP and TCPDUMP. LIBPCAP is the packet capture library required by TCPDUMP. First let's unpack LIBPCAP and move into the newly created LIBPCAP directory:

root@debian $ tar zxvf libpcap-1.6.1.tar.gz
libpcap-1.6.1/
libpcap-1.6.1/grammar.y
libpcap-1.6.1/pcap_setnonblock.3pcap
libpcap-1.6.1/fad-glifc.c
[OUTPUT TRUNCATED]

root@debian $ cd libpcap-1.6.1

Now it’s time to make the magic happen! Time to cross compile TCPDUMP! I know that’s not as exciting as pulling a rabbit out of hat or sawing a lovely assistant in half, but you can only do so much in a blog post. First we'll need to set the "CC" environment variable to specify the ARM C compiler:

root@debian $ export CC=arm-linux-gnueabi-gcc

Note this environment variable syntax is specific to Bash and other Bourne shell derivatives. Next let's configure LIBPCAP:

root@debian $ ./configure --host=arm-linux --with-pcap=linux
checking build system type... x86_64-unknown-linux-gnu
checking host system type... arm-unknown-linux-gnu
checking target system type... arm-unknown-linux-gnu
checking for arm-linux-gcc... arm-linux-gnueabi-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... yes
[OUTPUT TRUNCATED]

Note that the configure script successfully located the "arm-linux-gnueabi-gcc" compiler through the "CC" environment variable, and knows that we're cross compiling because of the "--host=arm-linux" command line option. Now let's make LIBPCAP:

root@debian $ make
arm-linux-gnueabi-gcc -fpic -I.  -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2 -c ./pcap-linux.c
arm-linux-gnueabi-gcc -fpic -I.  -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2 -c ./pcap-usb-linux.c
arm-linux-gnueabi-gcc -fpic -I.  -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2 -c ./pcap-can-linux.c
arm-linux-gnueabi-gcc -fpic -I.  -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2 -c ./fad-getad.c
[OUTPUT TRUNCATED]

Next let's exit the LIBPCAP directory, unpack TCPDUMP, and move into the newly created TCPDUMP directory:

root@debian $ cd ..

root@debian $ tar zxvf tcpdump-4.6.1.tar.gz
tcpdump-4.6.1/
tcpdump-4.6.1/nfsfh.h
tcpdump-4.6.1/llc.h
tcpdump-4.6.1/print-lwres.c
[OUTPUT TRUNCATED]

root@debian $ cd tcpdump-4.6.1

To compile TCPDUMP one additional environment variable needs to be set. The "ac_cv_linux_vers" variable informs TCPDUMP of the kernel major version number. The following commands list the kernel version and set the "ac_cv_linux_vers" environment variable to the kernel major version number:

root@debian $ uname -v
#1 SMP Debian 3.14.15-2 (2014-08-09)

root@debian $ export ac_cv_linux_vers=3

Once again note this environment variable syntax is specific to Bash and other Bourne shell derivatives. Now let's configure TCPDUMP:

root@debian $ ./configure --host=arm-linux --disable-ipv6
checking build system type... x86_64-unknown-linux-gnu
checking host system type... arm-unknown-linux-gnu
checking for arm-linux-gcc... arm-linux-gnueabi-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... yes
[OUTPUT TRUNCATED]

Once again note that the configure script successfully located the "arm-linux-gnueabi-gcc" compiler through the "CC" environment variable, and knows that we are cross compiling because of the "--host=arm-linux" command line option. In addition, note that IPv6 is disabled because of the "--disable-ipv6" command line option. Because shared libraries will not be installed on our CyanogenMod Mobile Device we'll need to set the "CFLAGS", "CPPFLAGS", and "LDFLAGS" environment variables to specify that TCPDUMP should be statically linked:

root@debian $ export CFLAGS=-static

root@debian $ export CPPFLAGS=-static

root@debian $ export LDFLAGS=-static

Note that only the "CFLAGS" environment variable is explicitly required in order to statically link TCPDUMP, but setting all three environment variables is a good practice. Now let's make TCPDUMP:

root@debian $ make
arm-linux-gnueabi-gcc -ffloat-store -DHAVE_CONFIG_H  -I./missing  -D_U_="__attribute__((unused))" -I. -I./../libpcap-1.6.1  -I./missing -g -O2 -c ./setsignal.c
arm-linux-gnueabi-gcc -ffloat-store -DHAVE_CONFIG_H  -I./missing  -D_U_="__attribute__((unused))" -I. -I./../libpcap-1.6.1  -I./missing -g -O2 -c ./tcpdump.c
[OUTPUT TRUNCATED]

That's it! Thar she blows:

root@debian $ file tcpdump
tcpdump: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.18, BuildID[sha1]=5a7f6e82ddc0c7530856dd8f5684ccea0dbe9d12, not stripped

Finally let's decrease the file size by more than 40% by stripping the symbols:

root@debian $ ls -lh tcpdump
-rwx------ 1 root root 2.8M Aug 18 20:49 tcpdump

root@debian $ arm-linux-gnueabi-strip tcpdump

root@debian $ ls -lh tcpdump
-rwx------ 1 root root 1.5M Aug 18 20:50 tcpdump

Phew! That was intense, but it was worth it as we successfully cross compiled LIBPCAP and TCPDUMP for ARM processors!  In our next installment we'll install and run TCPDUMP on our CyanogenMod Mobile Device.

Blog Entry Filed Under: