[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/iptables/extensions/libxt_TCPOPTSTRIP.c b/ap/app/iptables/extensions/libxt_TCPOPTSTRIP.c
new file mode 100755
index 0000000..cf946fc
--- /dev/null
+++ b/ap/app/iptables/extensions/libxt_TCPOPTSTRIP.c
@@ -0,0 +1,214 @@
+/*
+ * Shared library add-on to iptables to add TCPOPTSTRIP target support.
+ * Copyright (c) 2007 Sven Schnelle <svens@bitebene.org>
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Jan Engelhardt <jengelh@computergmbh.de>
+ */
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.h>
+#include <netinet/tcp.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TCPOPTSTRIP.h>
+#ifndef TCPOPT_MD5SIG
+#	define TCPOPT_MD5SIG 19
+#endif
+
+enum {
+	FLAG_STRIP = 1 << 0,
+};
+
+struct tcp_optionmap {
+	const char *name, *desc;
+	const unsigned int option;
+};
+
+static const struct option tcpoptstrip_tg_opts[] = {
+	{.name = "strip-options", .has_arg = true, .val = 's'},
+	{ .name = NULL }
+};
+
+static const struct tcp_optionmap tcp_optionmap[] = {
+	{"wscale",         "Window scale",         TCPOPT_WINDOW},
+	{"mss",            "Maximum Segment Size", TCPOPT_MAXSEG},
+	{"sack-permitted", "SACK permitted",       TCPOPT_SACK_PERMITTED},
+	{"sack",           "Selective ACK",        TCPOPT_SACK},
+	{"timestamp",      "Timestamp",            TCPOPT_TIMESTAMP},
+	{"md5",            "MD5 signature",        TCPOPT_MD5SIG},
+	{ .name = NULL }
+};
+
+static void tcpoptstrip_tg_help(void)
+{
+	const struct tcp_optionmap *w;
+
+	printf(
+"TCPOPTSTRIP target options:\n"
+"  --strip-options value     strip specified TCP options denoted by value\n"
+"                            (separated by comma) from TCP header\n"
+"  Instead of the numeric value, you can also use the following names:\n"
+	);
+
+	for (w = tcp_optionmap; w->name != NULL; ++w)
+		printf("    %-14s    strip \"%s\" option\n", w->name, w->desc);
+}
+
+static void tcpoptstrip_tg_init(struct xt_entry_target *t)
+{
+	struct xt_tcpoptstrip_target_info *info = (void *)t->data;
+
+	/* strictly necessary? play safe for now. */
+	memset(info->strip_bmap, 0, sizeof(info->strip_bmap));
+}
+
+static void parse_list(struct xt_tcpoptstrip_target_info *info, char *arg)
+{
+	unsigned int option;
+	char *p;
+	int i;
+
+	while (true) {
+		p = strchr(arg, ',');
+		if (p != NULL)
+			*p = '\0';
+
+		option = 0;
+		for (i = 0; tcp_optionmap[i].name != NULL; ++i)
+			if (strcmp(tcp_optionmap[i].name, arg) == 0) {
+				option = tcp_optionmap[i].option;
+				break;
+			}
+
+		if (option == 0 &&
+		    !xtables_strtoui(arg, NULL, &option, 0, UINT8_MAX))
+			xtables_error(PARAMETER_PROBLEM,
+			           "Bad TCP option value \"%s\"", arg);
+
+		if (option < 2)
+			xtables_error(PARAMETER_PROBLEM,
+			           "Option value may not be 0 or 1");
+
+		if (tcpoptstrip_test_bit(info->strip_bmap, option))
+			xtables_error(PARAMETER_PROBLEM,
+			           "Option \"%s\" already specified", arg);
+
+		tcpoptstrip_set_bit(info->strip_bmap, option);
+		if (p == NULL)
+			break;
+		arg = p + 1;
+	}
+}
+
+static int tcpoptstrip_tg_parse(int c, char **argv, int invert,
+                                unsigned int *flags, const void *entry,
+                                struct xt_entry_target **target)
+{
+	struct xt_tcpoptstrip_target_info *info = (void *)(*target)->data;
+
+	switch (c) {
+	case 's':
+		if (*flags & FLAG_STRIP)
+			xtables_error(PARAMETER_PROBLEM,
+			           "You can specify --strip-options only once");
+		parse_list(info, optarg);
+		*flags |= FLAG_STRIP;
+		return true;
+	}
+
+	return false;
+}
+
+static void tcpoptstrip_tg_check(unsigned int flags)
+{
+	if (flags == 0)
+		xtables_error(PARAMETER_PROBLEM,
+		           "TCPOPTSTRIP: --strip-options parameter required");
+}
+
+static void
+tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info,
+                       bool numeric)
+{
+	unsigned int i, j;
+	const char *name;
+	bool first = true;
+
+	for (i = 0; i < 256; ++i) {
+		if (!tcpoptstrip_test_bit(info->strip_bmap, i))
+			continue;
+		if (!first)
+			printf(",");
+
+		first = false;
+		name  = NULL;
+		if (!numeric)
+			for (j = 0; tcp_optionmap[j].name != NULL; ++j)
+				if (tcp_optionmap[j].option == i)
+					name = tcp_optionmap[j].name;
+
+		if (name != NULL)
+			printf("%s", name);
+		else
+			printf("%u", i);
+	}
+}
+
+static void
+tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target,
+                     int numeric)
+{
+	const struct xt_tcpoptstrip_target_info *info =
+		(const void *)target->data;
+
+	printf("TCPOPTSTRIP options ");
+	tcpoptstrip_print_list(info, numeric);
+}
+
+static void
+tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_tcpoptstrip_target_info *info =
+		(const void *)target->data;
+
+	printf("--strip-options ");
+	tcpoptstrip_print_list(info, true);
+}
+
+static struct xtables_target tcpoptstrip_tg_reg = {
+	.version       = XTABLES_VERSION,
+	.name          = "TCPOPTSTRIP",
+	.family        = NFPROTO_IPV4,
+	.size          = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.help          = tcpoptstrip_tg_help,
+	.init          = tcpoptstrip_tg_init,
+	.parse         = tcpoptstrip_tg_parse,
+	.final_check   = tcpoptstrip_tg_check,
+	.print         = tcpoptstrip_tg_print,
+	.save          = tcpoptstrip_tg_save,
+	.extra_opts    = tcpoptstrip_tg_opts,
+};
+
+static struct xtables_target tcpoptstrip_tg6_reg = {
+	.version       = XTABLES_VERSION,
+	.name          = "TCPOPTSTRIP",
+	.family        = NFPROTO_IPV6,
+	.size          = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.help          = tcpoptstrip_tg_help,
+	.init          = tcpoptstrip_tg_init,
+	.parse         = tcpoptstrip_tg_parse,
+	.final_check   = tcpoptstrip_tg_check,
+	.print         = tcpoptstrip_tg_print,
+	.save          = tcpoptstrip_tg_save,
+	.extra_opts    = tcpoptstrip_tg_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&tcpoptstrip_tg_reg);
+	xtables_register_target(&tcpoptstrip_tg6_reg);
+}