Wednesday, March 23, 2011

Porting iptables 1.4.10 to Android

(Update 25 Aprile 2011: This port is now in Google Code called iptables4n1).

Introduction 

The Android source comes with iptables 1.3.7. But that distribution is not compatible with Linux kernel 2.6.32 or newer versions. For example, even though iptables 1.3.7 can be built into the Android Emulator and Google Dev Phone 2 (a.k.a. HTC Magic) which are based on Linux kernel 2.6.29, it won't compile with kernel 2.6.32 used in Nexus One and many newer Android devices. The main difference between iptables 1.3.7 and 1.4.x is the emergence of "xtables" in the latter version. Fortunately, Google has done a commendable job in keeping Android in sync with Linux kernel releases. This makes porting a new version of iptables to Android largely an exercise of makefile changes. I will outline the steps here as a service to the open source community.

Steps

Below are steps for porting iptables 1.4.10 to Android/Linux kernel 2.6.32.
  1. Check out the Android source.
  2. Download iptables 1.4.10 source from the Netfilter project.
  3. Go to the checked out Android source and change to $SRC/external/iptables. Delete the content underneath that directory (or make a backup if you want) and then copy the downloaded iptables 1.4.10 content to that directory.
  4. Create a new Android.mk file under $SRC/external/iptables. This is the Android makefile. You can model yours after the one from the original Android source but you need to accommodate naming changes to iptable extensions that went from libiptXXX in 1.3.7 to libxtXXX in 1.4.10.
  5. Change to $SRC/external/iptables/extensions and create a new create_initext4 file there. 
  6. Change back to $SRC/external/iptables and run make. Fix header inclusion issues as needed.
Sample Android.mk

ifneq ($(TARGET_SIMULATOR),true)
  BUILD_IPTABLES := 1
endif
ifeq ($(BUILD_IPTABLES),1)
LOCAL_PATH:= $(call my-dir)
#
# Build libraries
#
# libxtables
include $(CLEAR_VARS)
LOCAL_C_INCLUDES:= \
    $(LOCAL_PATH)/include/ \
    $(KERNEL_HEADERS)
LOCAL_CFLAGS:=-DNO_SHARED_LIBS
LOCAL_CFLAGS+=-DXTABLES_INTERNAL
LOCAL_CFLAGS+=-DIPTABLES_VERSION=\"1.4.10\"
LOCAL_CFLAGS+=-DXTABLES_VERSION=\"1.4.10\" # -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\"
LOCAL_CFLAGS+=-DXTABLES_LIBDIR
LOCAL_SRC_FILES:= \
    xtables.c
LOCAL_MODULE_TAGS:=
LOCAL_MODULE:=libxtables
include $(BUILD_STATIC_LIBRARY)
# libip4tc
include $(CLEAR_VARS)
LOCAL_C_INCLUDES:= \
    $(KERNEL_HEADERS) \
    $(LOCAL_PATH)/include/
LOCAL_CFLAGS:=-DNO_SHARED_LIBS
LOCAL_CFLAGS+=-DXTABLES_INTERNAL
LOCAL_SRC_FILES:= \
    libiptc/libip4tc.c
LOCAL_MODULE_TAGS:=
LOCAL_MODULE:=libip4tc
include $(BUILD_STATIC_LIBRARY)
# libext4
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:=
LOCAL_MODULE:=libext4
# LOCAL_MODULE_CLASS must be defined before calling $(local-intermediates-dir)
#
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
intermediates := $(call local-intermediates-dir)
LOCAL_C_INCLUDES:= \
    $(LOCAL_PATH)/include/ \
    $(KERNEL_HEADERS) \
    $(intermediates)/extensions/
LOCAL_CFLAGS:=-DNO_SHARED_LIBS
LOCAL_CFLAGS+=-DXTABLES_INTERNAL
LOCAL_CFLAGS+=-D_INIT=$*_init
LOCAL_CFLAGS+=-DIPTABLES_VERSION=\"1.4.10\"
LOCAL_CFLAGS+=-DXTABLES_VERSION=\"1.4.10\"
PF_EXT_SLIB:=ah addrtype ecn 
PF_EXT_SLIB+=icmp #2mark
PF_EXT_SLIB+=realm
PF_EXT_SLIB+=ttl unclean DNAT LOG #DSCP ECN
PF_EXT_SLIB+=MASQUERADE MIRROR NETMAP REDIRECT REJECT #MARK
PF_EXT_SLIB+=SAME SNAT ULOG # TOS TCPMSS TTL
PF_EXT_SLIB+=TAG
EXT_FUNC+=$(foreach T,$(PF_EXT_SLIB),ipt_$(T))
# xtable stuff
NEW_PF_EXT_SLIB:=comment conntrack connmark dscp tcpmss esp
NEW_PF_EXT_SLIB+=hashlimit helper iprange length limit mac multiport
NEW_PF_EXT_SLIB+=owner physdev pkttype policy sctp standard state tcp
NEW_PF_EXT_SLIB+=tos udp CLASSIFY CONNMARK
NEW_PF_EXT_SLIB+=NFQUEUE NOTRACK
EXT_FUNC+=$(foreach N,$(NEW_PF_EXT_SLIB),xt_$(N))
# generated headers
GEN_INITEXT:= $(intermediates)/extensions/gen_initext4.c
$(GEN_INITEXT): PRIVATE_PATH := $(LOCAL_PATH)
$(GEN_INITEXT): PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/extensions/create_initext4 "$(EXT_FUNC)" > $@
$(GEN_INITEXT): PRIVATE_MODULE := $(LOCAL_MODULE)
$(GEN_INITEXT):
    $(transform-generated-source)
$(intermediates)/extensions/initext4.o : $(GEN_INITEXT)
LOCAL_GENERATED_SOURCES:= $(GEN_INITEXT)
LOCAL_SRC_FILES:= \
    $(foreach T,$(PF_EXT_SLIB),extensions/libipt_$(T).c) \
    $(foreach N,$(NEW_PF_EXT_SLIB),extensions/libxt_$(N).c) \
    extensions/initext4.c
LOCAL_STATIC_LIBRARIES := \
    libc
include $(BUILD_STATIC_LIBRARY)
#
# Build iptables
#
include $(CLEAR_VARS)
LOCAL_C_INCLUDES:= \
    $(LOCAL_PATH)/include/ \
    $(KERNEL_HEADERS)
LOCAL_CFLAGS:=-DNO_SHARED_LIBS
LOCAL_CFLAGS+=-DXTABLES_INTERNAL
LOCAL_CFLAGS+=-DIPTABLES_VERSION=\"1.4.10\"
LOCAL_CFLAGS+=-DXTABLES_VERSION=\"1.4.10\" # -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\"
#LOCAL_CFLAGS+=-DIPT_LIB_DIR=\"$(IPT_LIBDIR)\"
LOCAL_SRC_FILES:= \
    iptables.c \
    iptables-standalone.c \
        xshared.c
LOCAL_MODULE_TAGS:=
LOCAL_MODULE:=iptables
LOCAL_STATIC_LIBRARIES := \
    libip4tc \
    libext4  \
        libxtables
include $(BUILD_EXECUTABLE)
endif


Sample create_initext4

#!/bin/sh
echo ""
for i in $1; do
    echo "extern void lib${i}_init(void);";
done;
echo "void init_extensions(void);"
echo "void init_extensions(void) {"
for i in $1; do
    echo "    lib${i}_init();";
done
echo "}"



That is all. Happy hacking!


6 comments:

  1. please be little more descriptive. The link for android source in the above post doesn't work. and also there is no idea where all this $SRC/ directories should be created and how to carry the rest process. I am a beginner, and want to use your way.

    I want to enable full netfilter functionality in the newly compiled kernel and successfully deploy it on to the emulator.
    please help.

    ReplyDelete
  2. please check this thread, i am stuck with this.

    http://stackoverflow.com/questions/5406549/error-while-loading-new-compiled-linux-kernel-image-into-the-android-emulator1-5

    ReplyDelete
  3. I am getting this error when executing the make command after ./configure:


    In file included from ../include/xtables.h:15,
    from libxt_CHECKSUM.c:17:
    ../include/linux/types.h:4:23: warning: asm/types.h: No such file or directory
    ../include/linux/types.h:8:31: warning: linux/posix_types.h: No such file or directory
    In file included from ../include/xtables.h:15,
    from libxt_CHECKSUM.c:17:
    ../include/linux/types.h:27: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__le16’
    ../include/linux/types.h:28: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__be16’
    ../include/linux/types.h:29: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__le32’
    ../include/linux/types.h:30: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__be32’
    ../include/linux/types.h:31: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__le64’
    ../include/linux/types.h:32: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__be64’
    ../include/linux/types.h:34: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__sum16’
    ../include/linux/types.h:35: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__wsum’
    In file included from ../include/xtables.h:16,
    from libxt_CHECKSUM.c:17:
    ../include/linux/netfilter.h:52: error: expected specifier-qualifier-list before ‘__u32’
    In file included from ../include/xtables.h:17,
    from libxt_CHECKSUM.c:17:
    ../include/linux/netfilter/x_tables.h:13: error: expected specifier-qualifier-list before ‘__u16’
    ../include/linux/netfilter/x_tables.h:20: error: expected specifier-qualifier-list before ‘__u16’
    ../include/linux/netfilter/x_tables.h:27: error: expected specifier-qualifier-list before ‘__u16’
    ../include/linux/netfilter/x_tables.h:36: error: expected specifier-qualifier-list before ‘__u16’
    ../include/linux/netfilter/x_tables.h:43: error: expected specifier-qualifier-list before ‘__u16’
    ../include/linux/netfilter/x_tables.h:50: error: expected specifier-qualifier-list before ‘__u16’
    ../include/linux/netfilter/x_tables.h:73: error: expected specifier-qualifier-list before ‘__u8’
    ../include/linux/netfilter/x_tables.h:88: error: expected specifier-qualifier-list before ‘__u8’
    ../include/linux/netfilter/x_tables.h:105: error: expected specifier-qualifier-list before ‘__u64’
    In file included from libxt_CHECKSUM.c:18:
    ../include/linux/netfilter/xt_CHECKSUM.h:15: error: expected specifier-qualifier-list before ‘__u8’
    libxt_CHECKSUM.c: In function ‘CHECKSUM_parse’:
    libxt_CHECKSUM.c:42: error: ‘struct xt_CHECKSUM_info’ has no member named ‘operation’
    libxt_CHECKSUM.c: In function ‘CHECKSUM_print’:
    libxt_CHECKSUM.c:67: error: ‘const struct xt_CHECKSUM_info’ has no member named ‘operation’
    libxt_CHECKSUM.c: In function ‘CHECKSUM_save’:
    libxt_CHECKSUM.c:76: error: ‘const struct xt_CHECKSUM_info’ has no member named ‘operation’
    make[2]: *** [libxt_CHECKSUM.oo] Error 1
    make[1]: *** [all-recursive] Error 1
    make: *** [all] Error 2


    thoughts?

    ReplyDelete
  4. Follow-up: where are we supposed to put the Makefile in the platform distro? For example, I am trying to build and image for my nook color platform and the original source has a "net" folder that has a bunch of makefiles - which one(s) am I supposed to update: ip4, ip6, etc?

    ReplyDelete
  5. This port is now in Googe code. It is called iptables4n1. Check it out at http://code.google.com/p/iptables4n1/. Hope that will answer all questions posted here.

    ReplyDelete
  6. Hi ,

    I m trying o port iptables on Android msm kernel 2.6.35. However it comes installed with iptables 1.3.7 and when I replace it with the sources of iptables 1.4.11 and the make file as above. Server warnings and errors are thrown. Do you have an updated make file(Android.mk) for it? Please help me.

    ReplyDelete