Merge remote-tracking branch 'upstream/stable-1.4.20' into update

Conflicts:
	.gitignore
	include/linux/types.h
	libiptc/libiptc.c

Change-Id: I2c949ba9de090db9ae09d914f4ac5c13e5b7d4da
diff --git a/.gitignore b/.gitignore
index fa86c48..b734ea9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,12 @@
 Makefile
 Makefile.in
 
+/extensions/GNUmakefile
+/extensions/initext.c
+/extensions/initext?.c
+/extensions/matches?.man
+/extensions/targets?.man
+
 /include/xtables-version.h
 /include/iptables/internal.h
 
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..31eae91
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,5 @@
+BUILD_IPTABLES_V14 := 1
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/extensions/Android.mk b/extensions/Android.mk
new file mode 100644
index 0000000..3db8008
--- /dev/null
+++ b/extensions/Android.mk
@@ -0,0 +1,36 @@
+LOCAL_PATH:= $(call my-dir)
+#----------------------------------------------------------------
+## extension
+
+MY_srcdir:=$(LOCAL_PATH)
+# Exclude some modules that are problematic to compile (types/header).
+MY_excluded_modules:=TCPOPTSTRIP
+
+MY_pfx_build_mod := $(patsubst ${MY_srcdir}/libxt_%.c,%,$(wildcard ${MY_srcdir}/libxt_*.c))
+MY_pf4_build_mod := $(patsubst ${MY_srcdir}/libipt_%.c,%,$(wildcard ${MY_srcdir}/libipt_*.c))
+MY_pf6_build_mod := $(patsubst ${MY_srcdir}/libip6t_%.c,%,$(wildcard ${MY_srcdir}/libip6t_*.c))
+MY_pfx_build_mod := $(filter-out ${MY_excluded_modules} dccp ipvs,${MY_pfx_build_mod})
+MY_pf4_build_mod := $(filter-out ${MY_excluded_modules} dccp ipvs,${MY_pf4_build_mod})
+MY_pf6_build_mod := $(filter-out ${MY_excluded_modules} dccp ipvs,${MY_pf6_build_mod})
+MY_pfx_objs      := $(patsubst %,libxt_%.o,${MY_pfx_build_mod})
+MY_pf4_objs      := $(patsubst %,libipt_%.o,${MY_pf4_build_mod})
+MY_pf6_objs      := $(patsubst %,libip6t_%.o,${MY_pf6_build_mod})
+MY_warnings      := -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-pointer-arith
+
+libext_suffix :=
+libext_prefix := xt
+libext_build_mod := $(MY_pfx_build_mod)
+include $(LOCAL_PATH)/libext.mk
+
+libext_suffix := 4
+libext_prefix := ipt
+libext_build_mod := $(MY_pf4_build_mod)
+include $(LOCAL_PATH)/libext.mk
+
+libext_suffix := 6
+libext_prefix := ip6t
+libext_build_mod := $(MY_pf6_build_mod)
+include $(LOCAL_PATH)/libext.mk
+
+
+#----------------------------------------------------------------
diff --git a/extensions/filter_init b/extensions/filter_init
new file mode 100755
index 0000000..2fcdd6d
--- /dev/null
+++ b/extensions/filter_init
@@ -0,0 +1,7 @@
+#!/bin/sh
+# This is for working around Android.mk's incapability to handle $* in CFLAGS,
+# even with SECONDEXPNASION.
+# LOCAL_CFLAGS:=-D_INIT=$*_init
+f=${1##*/}
+f=${f%%.*}
+sed "s/\([ ]*\)\(_init\)\(([ ]*void\)/\1${f}_init\3/" $1
diff --git a/extensions/libext.mk b/extensions/libext.mk
new file mode 100644
index 0000000..1255ed0
--- /dev/null
+++ b/extensions/libext.mk
@@ -0,0 +1,60 @@
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE:=libext$(libext_suffix)
+
+# LOCAL_MODULE_CLASS must be defined before calling $(local-generated-sources-dir)
+#
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+MY_gen := $(call local-generated-sources-dir)
+
+# LOCAL_PATH needed because of dirty #include "blabla.c"
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/ \
+	$(MY_gen) \
+	$(LOCAL_PATH)
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+# The $* does not work as expected. It ends up empty. Even with SECONDEXPANSION.
+# LOCAL_CFLAGS+=-D_INIT=lib$*_init
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+LOCAL_CFLAGS += $(MY_warnings)
+
+MY_GEN_INITEXT:= $(MY_gen)/initext.c
+$(MY_GEN_INITEXT): MY_initext_func := $(addprefix $(libext_prefix)_,$(libext_build_mod))
+$(MY_GEN_INITEXT): MY_suffix := $(libext_suffix)
+$(MY_GEN_INITEXT):
+	@mkdir -p $(dir $@)
+	@( \
+	echo "" >$@; \
+	for i in $(MY_initext_func); do \
+		echo "extern void lib$${i}_init(void);" >>$@; \
+	done; \
+	echo "void init_extensions$(MY_suffix)(void);" >>$@; \
+	echo "void init_extensions$(MY_suffix)(void)" >>$@; \
+	echo "{" >>$@; \
+	for i in $(MY_initext_func); do \
+		echo " ""lib$${i}_init();" >>$@; \
+	done; \
+	echo "}" >>$@; \
+	);
+
+MY_lib_sources:= \
+	$(patsubst %,$(LOCAL_PATH)/lib$(libext_prefix)_%.c,$(libext_build_mod))
+
+MY_gen_lib_sources:= $(patsubst $(LOCAL_PATH)/%,${MY_gen}/%,${MY_lib_sources})
+
+${MY_gen_lib_sources}: PRIVATE_PATH := $(LOCAL_PATH)
+${MY_gen_lib_sources}: PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/filter_init $(PRIVATE_PATH)/$(notdir $@) > $@
+${MY_gen_lib_sources}: PRIVATE_MODULE := $(LOCAL_MODULE)
+${MY_gen_lib_sources}: PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)
+${MY_gen_lib_sources}: ${MY_gen}/% : $(LOCAL_PATH)/%
+	$(transform-generated-source)
+
+$(MY_GEN_INITEXT): $(MY_gen_lib_sources)
+
+LOCAL_GENERATED_SOURCES:= $(MY_GEN_INITEXT) $(MY_gen_lib_sources)
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/extensions/libipt_ULOG.c b/extensions/libipt_ULOG.c
index fafb220..5163eea 100644
--- a/extensions/libipt_ULOG.c
+++ b/extensions/libipt_ULOG.c
@@ -11,6 +11,7 @@
  */
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include <xtables.h>
 /* For 64bit kernel / 32bit userspace */
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
diff --git a/extensions/libxt_IDLETIMER.c b/extensions/libxt_IDLETIMER.c
index 21004a4..5f1b9fe 100644
--- a/extensions/libxt_IDLETIMER.c
+++ b/extensions/libxt_IDLETIMER.c
@@ -27,6 +27,7 @@
 enum {
 	O_TIMEOUT = 0,
 	O_LABEL,
+	O_NETLINK,
 };
 
 #define s struct idletimer_tg_info
@@ -35,6 +36,8 @@
 	 .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, timeout)},
 	{.name = "label", .id = O_LABEL, .type = XTTYPE_STRING,
 	 .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, label)},
+	{.name = "send_nl_msg", .id = O_NETLINK, .type = XTTYPE_UINT8,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, send_nl_msg)},
 	XTOPT_TABLEEND,
 };
 #undef s
@@ -45,6 +48,8 @@
 "IDLETIMER target options:\n"
 " --timeout time	Timeout until the notification is sent (in seconds)\n"
 " --label string	Unique rule identifier\n"
+" --send_nl_msg		(0/1) Enable netlink messages,"
+			" and show remaining time in sysfs. Defaults to 0.\n"
 "\n");
 }
 
@@ -57,6 +62,7 @@
 
 	printf(" timeout:%u", info->timeout);
 	printf(" label:%s", info->label);
+	printf(" send_nl_msg:%u", info->send_nl_msg);
 }
 
 static void idletimer_tg_save(const void *ip,
@@ -67,13 +73,14 @@
 
 	printf(" --timeout %u", info->timeout);
 	printf(" --label %s", info->label);
+	printf(" --send_nl_msg %u", info->send_nl_msg);
 }
 
 static struct xtables_target idletimer_tg_reg = {
 	.family	       = NFPROTO_UNSPEC,
 	.name	       = "IDLETIMER",
 	.version       = XTABLES_VERSION,
-	.revision      = 0,
+	.revision      = 1,
 	.size	       = XT_ALIGN(sizeof(struct idletimer_tg_info)),
 	.userspacesize = offsetof(struct idletimer_tg_info, timer),
 	.help	       = idletimer_tg_help,
diff --git a/extensions/libxt_IDLETIMER.man b/extensions/libxt_IDLETIMER.man
index e3c91ce..3b5188d 100644
--- a/extensions/libxt_IDLETIMER.man
+++ b/extensions/libxt_IDLETIMER.man
@@ -18,3 +18,7 @@
 \fB\-\-label\fP \fIstring\fP
 This is a unique identifier for the timer.  The maximum length for the
 label string is 27 characters.
+.TP
+\fB\-\---send_nl_msg\fP \fI(0/1)\fP
+Send netlink messages in addition to sysfs notifications and show remaining
+time. Defaults to 0.
diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c
index ff498da..26fba0b 100644
--- a/extensions/libxt_quota.c
+++ b/extensions/libxt_quota.c
@@ -48,6 +48,7 @@
 	xtables_option_parse(cb);
 	if (cb->invert)
 		info->flags |= XT_QUOTA_INVERT;
+	info->quota = cb->val.u64;
 }
 
 static struct xtables_match quota_match = {
diff --git a/extensions/libxt_quota2.c b/extensions/libxt_quota2.c
new file mode 100644
index 0000000..d004cca
--- /dev/null
+++ b/extensions/libxt_quota2.c
@@ -0,0 +1,141 @@
+/*
+ *	"quota2" match extension for iptables
+ *	Sam Johnston <samj [at] samj net>
+ *	Jan Engelhardt <jengelh [at] medozas de>, 2008
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License; either
+ *	version 2 of the License, or any later version, as published by the
+ *	Free Software Foundation.
+ */
+#include <getopt.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <xtables.h>
+#include <linux/netfilter/xt_quota2.h>
+
+enum {
+	FL_QUOTA     = 1 << 0,
+	FL_NAME      = 1 << 1,
+	FL_GROW      = 1 << 2,
+	FL_PACKET    = 1 << 3,
+	FL_NO_CHANGE = 1 << 4,
+};
+
+enum {
+	O_QUOTA     = 0,
+	O_NAME,
+	O_GROW,
+	O_PACKET,
+	O_NO_CHANGE,
+};
+
+
+static const struct xt_option_entry quota_mt2_opts[] = {
+	{.name = "grow", .id = O_GROW, .type = XTTYPE_NONE},
+	{.name = "no-change", .id = O_NO_CHANGE, .type = XTTYPE_NONE},
+	{.name = "name", .id = O_NAME, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_quota_mtinfo2, name)},
+	{.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64,
+	 .flags = XTOPT_INVERT | XTOPT_PUT,
+	 XTOPT_POINTER(struct xt_quota_mtinfo2, quota)},
+	{.name = "packets", .id = O_PACKET, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+
+static void quota_mt2_help(void)
+{
+	printf(
+	"quota match options:\n"
+	"    --grow           provide an increasing counter\n"
+	"    --no-change      never change counter/quota value for matching packets\n"
+	"    --name name      name for the file in sysfs\n"
+	"[!] --quota quota    initial quota (bytes or packets)\n"
+	"    --packets        count packets instead of bytes\n"
+	);
+}
+
+static void quota_mt2_parse(struct xt_option_call *cb)
+{
+	struct xt_quota_mtinfo2 *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_GROW:
+		info->flags |= XT_QUOTA_GROW;
+		break;
+	case O_NO_CHANGE:
+		info->flags |= XT_QUOTA_NO_CHANGE;
+		break;
+	case O_NAME:
+		break;
+	case O_PACKET:
+		info->flags |= XT_QUOTA_PACKET;
+		break;
+	case O_QUOTA:
+		if (cb->invert)
+			info->flags |= XT_QUOTA_INVERT;
+		break;
+	}
+}
+
+static void
+quota_mt2_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_quota_mtinfo2 *q = (void *)match->data;
+
+	if (q->flags & XT_QUOTA_INVERT)
+		printf(" !");
+	if (q->flags & XT_QUOTA_GROW)
+		printf(" --grow ");
+	if (q->flags & XT_QUOTA_NO_CHANGE)
+		printf(" --no-change ");
+	if (q->flags & XT_QUOTA_PACKET)
+		printf(" --packets ");
+	if (*q->name != '\0')
+		printf(" --name %s ", q->name);
+	printf(" --quota %llu ", (unsigned long long)q->quota);
+}
+
+static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
+                            int numeric)
+{
+	const struct xt_quota_mtinfo2 *q = (const void *)match->data;
+
+	if (q->flags & XT_QUOTA_INVERT)
+		printf(" !");
+	if (q->flags & XT_QUOTA_GROW)
+		printf(" counter");
+	else
+		printf(" quota");
+	if (*q->name != '\0')
+		printf(" %s:", q->name);
+	printf(" %llu ", (unsigned long long)q->quota);
+	if (q->flags & XT_QUOTA_PACKET)
+		printf("packets ");
+	else
+		printf("bytes ");
+	if (q->flags & XT_QUOTA_NO_CHANGE)
+		printf("(no-change mode) ");
+}
+
+static struct xtables_match quota_mt2_reg = {
+	.family        = NFPROTO_UNSPEC,
+	.revision      = 3,
+	.name          = "quota2",
+	.version       = XTABLES_VERSION,
+	.size          = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
+	.userspacesize = offsetof(struct xt_quota_mtinfo2, quota),
+	.help          = quota_mt2_help,
+	.x6_parse      = quota_mt2_parse,
+	.print         = quota_mt2_print,
+	.save          = quota_mt2_save,
+	.x6_options    = quota_mt2_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&quota_mt2_reg);
+}
diff --git a/extensions/libxt_quota2.man b/extensions/libxt_quota2.man
new file mode 100644
index 0000000..c2e6b44
--- /dev/null
+++ b/extensions/libxt_quota2.man
@@ -0,0 +1,37 @@
+The "quota2" implements a named counter which can be increased or decreased
+on a per-match basis. Available modes are packet counting or byte counting.
+The value of the counter can be read and reset through procfs, thereby making
+this match a minimalist accounting tool.
+.PP
+When counting down from the initial quota, the counter will stop at 0 and
+the match will return false, just like the original "quota" match. In growing
+(upcounting) mode, it will always return true.
+.TP
+\fB\-\-grow\fP
+Count upwards instead of downwards.
+.TP
+\fB\-\-no\-change\fP
+Makes it so the counter or quota amount is never changed by packets matching
+this rule. This is only really useful in "quota" mode, as it will allow you to
+use complex prerouting rules in association with the quota system, without
+counting a packet twice.
+.TP
+\fB\-\-name\fP \fIname\fP
+Assign the counter a specific name. This option must be present, as an empty
+name is not allowed. Names starting with a dot or names containing a slash are
+prohibited.
+.TP
+[\fB!\fP] \fB\-\-quota\fP \fIiq\fP
+Specify the initial quota for this counter. If the counter already exists,
+it is not reset. An "!" may be used to invert the result of the match. The
+negation has no effect when \fB\-\-grow\fP is used.
+.TP
+\fB\-\-packets\fP
+Count packets instead of bytes that passed the quota2 match.
+.PP
+Because counters in quota2 can be shared, you can combine them for various
+purposes, for example, a bytebucket filter that only lets as much traffic go
+out as has come in:
+.PP
+\-A INPUT \-p tcp \-\-dport 6881 \-m quota \-\-name bt \-\-grow;
+\-A OUTPUT \-p tcp \-\-sport 6881 \-m quota \-\-name bt;
diff --git a/include/iptables/internal.h b/include/iptables/internal.h
new file mode 100644
index 0000000..8d8f023
--- /dev/null
+++ b/include/iptables/internal.h
@@ -0,0 +1,13 @@
+#ifndef IPTABLES_INTERNAL_H
+#define IPTABLES_INTERNAL_H 1
+
+#define IPTABLES_VERSION "1.4.11.1"
+
+/**
+ * Program's own name and version.
+ */
+extern const char *program_name, *program_version;
+
+extern int line;
+
+#endif /* IPTABLES_INTERNAL_H */
diff --git a/include/libiptc/ipt_kernel_headers.h b/include/libiptc/ipt_kernel_headers.h
index 18861fe..60c7998 100644
--- a/include/libiptc/ipt_kernel_headers.h
+++ b/include/libiptc/ipt_kernel_headers.h
@@ -5,7 +5,7 @@
 
 #include <limits.h>
 
-#if defined(__GLIBC__) && __GLIBC__ == 2
+#if defined(__ANDROID__) || (defined(__GLIBC__) && __GLIBC__ == 2)
 #include <netinet/ip.h>
 #include <netinet/in.h>
 #include <netinet/ip_icmp.h>
diff --git a/include/linux/netfilter/xt_IDLETIMER.h b/include/linux/netfilter/xt_IDLETIMER.h
index 208ae93..faaa28b 100644
--- a/include/linux/netfilter/xt_IDLETIMER.h
+++ b/include/linux/netfilter/xt_IDLETIMER.h
@@ -4,6 +4,7 @@
  * Header file for Xtables timer target module.
  *
  * Copyright (C) 2004, 2010 Nokia Corporation
+ *
  * Written by Timo Teras <ext-timo.teras@nokia.com>
  *
  * Converted to x_tables and forward-ported to 2.6.34
@@ -32,12 +33,19 @@
 #include <linux/types.h>
 
 #define MAX_IDLETIMER_LABEL_SIZE 28
+#define NLMSG_MAX_SIZE 64
+
+#define NL_EVENT_TYPE_INACTIVE 0
+#define NL_EVENT_TYPE_ACTIVE 1
 
 struct idletimer_tg_info {
 	__u32 timeout;
 
 	char label[MAX_IDLETIMER_LABEL_SIZE];
 
+	/* Use netlink messages for notification in addition to sysfs */
+	__u8 send_nl_msg;
+
 	/* for kernel module internal use only */
 	struct idletimer_tg *timer __attribute__((aligned(8)));
 };
diff --git a/include/linux/netfilter/xt_quota2.h b/include/linux/netfilter/xt_quota2.h
new file mode 100644
index 0000000..eadc690
--- /dev/null
+++ b/include/linux/netfilter/xt_quota2.h
@@ -0,0 +1,25 @@
+#ifndef _XT_QUOTA_H
+#define _XT_QUOTA_H
+
+enum xt_quota_flags {
+	XT_QUOTA_INVERT    = 1 << 0,
+	XT_QUOTA_GROW      = 1 << 1,
+	XT_QUOTA_PACKET    = 1 << 2,
+	XT_QUOTA_NO_CHANGE = 1 << 3,
+	XT_QUOTA_MASK      = 0x0F,
+};
+
+struct xt_quota_counter;
+
+struct xt_quota_mtinfo2 {
+	char name[15];
+	u_int8_t flags;
+
+	/* Comparison-invariant */
+	aligned_u64 quota;
+
+	/* Used internally by the kernel */
+	struct xt_quota_counter *master __attribute__((aligned(8)));
+};
+
+#endif /* _XT_QUOTA_H */
diff --git a/iptables/Android.mk b/iptables/Android.mk
new file mode 100644
index 0000000..736c59a
--- /dev/null
+++ b/iptables/Android.mk
@@ -0,0 +1,85 @@
+LOCAL_PATH:= $(call my-dir)
+My_intermediaries := $(call local-intermediates-dir)
+#----------------------------------------------------------------
+# libxtables
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/ \
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+LOCAL_CFLAGS+=-DXTABLES_LIBDIR=\"xtables_libdir_not_used\"
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+LOCAL_CFLAGS += -Wno-sign-compare -Wno-pointer-arith -Wno-type-limits -Wno-missing-field-initializers -Wno-unused-parameter -Wno-clobbered
+
+LOCAL_LDFLAGS:=-version-info 6:0:0
+LOCAL_SRC_FILES:= \
+	xtables.c xtoptions.c
+
+LOCAL_MODULE:=libxtables
+
+include $(BUILD_STATIC_LIBRARY)
+
+#----------------------------------------------------------------
+# iptables
+
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+LOCAL_CFLAGS+=-DALL_INCLUSIVE
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+LOCAL_CFLAGS += -Wno-sign-compare -Wno-pointer-arith
+
+LOCAL_SRC_FILES:= \
+	iptables-standalone.c iptables.c xshared.c
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:=iptables
+
+LOCAL_STATIC_LIBRARIES := \
+	libext \
+	libext4 \
+	libip4tc \
+	libxtables
+
+include $(BUILD_EXECUTABLE)
+
+#----------------------------------------------------------------
+# ip6tables
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+LOCAL_CFLAGS+=-DALL_INCLUSIVE
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+LOCAL_CFLAGS += -Wno-pointer-arith -Wno-sign-compare
+
+LOCAL_SRC_FILES:= \
+	ip6tables-standalone.c ip6tables.c xshared.c
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:=ip6tables
+
+LOCAL_STATIC_LIBRARIES := \
+	libext \
+	libext6 \
+	libip6tc \
+	libxtables
+
+include $(BUILD_EXECUTABLE)
+
+
+#----------------------------------------------------------------
diff --git a/iptables/iptables-standalone.c b/iptables/iptables-standalone.c
index 4da1d7f..c60b4b7 100644
--- a/iptables/iptables-standalone.c
+++ b/iptables/iptables-standalone.c
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <signal.h>
 #include <string.h>
 #include <iptables.h>
 #include "iptables-multi.h"
@@ -45,6 +46,8 @@
 	char *table = "filter";
 	struct xtc_handle *handle = NULL;
 
+	signal(SIGPIPE, SIG_IGN);
+
 	iptables_globals.program_name = "iptables";
 	ret = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
 	if (ret < 0) {
diff --git a/libiptc/Android.mk b/libiptc/Android.mk
new file mode 100644
index 0000000..e46ecba
--- /dev/null
+++ b/libiptc/Android.mk
@@ -0,0 +1,46 @@
+LOCAL_PATH:= $(call my-dir)
+
+#----------------------------------------------------------------
+# libip4tc
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/
+
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS:=-D__ANDROID__
+LOCAL_CFLAGS += -Wno-pointer-arith -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign
+
+LOCAL_SRC_FILES:= \
+	libip4tc.c \
+
+
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE:=libip4tc
+
+include $(BUILD_STATIC_LIBRARY)
+
+
+#----------------------------------------------------------------
+# libip6tc
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/
+
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS:=-D__ANDROID__
+LOCAL_CFLAGS += -Wno-pointer-arith -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign
+
+LOCAL_SRC_FILES:= \
+	libip6tc.c \
+
+
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE:=libip6tc
+
+include $(BUILD_STATIC_LIBRARY)
+
+#----------------------------------------------------------------
diff --git a/libiptc/libip4tc.c b/libiptc/libip4tc.c
index dd59951..2b029d4 100644
--- a/libiptc/libip4tc.c
+++ b/libiptc/libip4tc.c
@@ -22,7 +22,7 @@
 #define inline
 #endif
 
-#if !defined(__GLIBC__) || (__GLIBC__ < 2)
+#if !defined(__ANDROID__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
 typedef unsigned int socklen_t;
 #endif
 
diff --git a/libiptc/libip6tc.c b/libiptc/libip6tc.c
index ca01bcb..4e47e69 100644
--- a/libiptc/libip6tc.c
+++ b/libiptc/libip6tc.c
@@ -23,7 +23,7 @@
 #define inline
 #endif
 
-#if !defined(__GLIBC__) || (__GLIBC__ < 2)
+#if !defined(__ANDROID__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
 typedef unsigned int socklen_t;
 #endif
 
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index f0f7815..3a8e143 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -67,6 +67,13 @@
 };
 
 /* Convenience structures */
+#undef ipt_error_target /* uapi includes this already. */
+struct ipt_error_target
+{
+	STRUCT_ENTRY_TARGET t;
+	char error[TABLE_MAXNAMELEN];
+};
+
 struct chain_head;
 struct rule_head;