[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_connbytes.c b/ap/app/iptables/extensions/libxt_connbytes.c
new file mode 100755
index 0000000..9f6af1c
--- /dev/null
+++ b/ap/app/iptables/extensions/libxt_connbytes.c
@@ -0,0 +1,214 @@
+/* Shared library add-on to iptables to add byte tracking support. */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <linux/netfilter/nf_conntrack_common.h>
+#include <linux/netfilter/xt_connbytes.h>
+
+static void connbytes_help(void)
+{
+	printf(
+"connbytes match options:\n"
+" [!] --connbytes from:[to]\n"
+"     --connbytes-dir [original, reply, both]\n"
+"     --connbytes-mode [packets, bytes, avgpkt]\n");
+}
+
+static const struct option connbytes_opts[] = {
+	{ "connbytes", 1, NULL, '1' },
+	{ "connbytes-dir", 1, NULL, '2' },
+	{ "connbytes-mode", 1, NULL, '3' },
+	{ .name = NULL }
+};
+
+static void
+parse_range(const char *arg, struct xt_connbytes_info *si)
+{
+	char *colon,*p;
+
+	si->count.from = strtoul(arg,&colon,10);
+	if (*colon != ':') 
+		xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", arg);
+	si->count.to = strtoul(colon+1,&p,10);
+	if (p == colon+1) {
+		/* second number omited */
+		si->count.to = 0xffffffff;
+	}
+	if (si->count.from > si->count.to)
+		xtables_error(PARAMETER_PROBLEM, "%llu should be less than %llu",
+			   (unsigned long long)si->count.from,
+			   (unsigned long long)si->count.to);
+}
+
+static int
+connbytes_parse(int c, char **argv, int invert, unsigned int *flags,
+                const void *entry, struct xt_entry_match **match)
+{
+	struct xt_connbytes_info *sinfo = (struct xt_connbytes_info *)(*match)->data;
+	unsigned long i;
+
+	switch (c) {
+	case '1':
+		if (xtables_check_inverse(optarg, &invert, &optind, 0))
+			optind++;
+
+		parse_range(argv[optind-1], sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		*flags |= 1;
+		break;
+	case '2':
+		if (!strcmp(optarg, "original"))
+			sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL;
+		else if (!strcmp(optarg, "reply"))
+			sinfo->direction = XT_CONNBYTES_DIR_REPLY;
+		else if (!strcmp(optarg, "both"))
+			sinfo->direction = XT_CONNBYTES_DIR_BOTH;
+		else
+			xtables_error(PARAMETER_PROBLEM,
+				   "Unknown --connbytes-dir `%s'", optarg);
+
+		*flags |= 2;
+		break;
+	case '3':
+		if (!strcmp(optarg, "packets"))
+			sinfo->what = XT_CONNBYTES_PKTS;
+		else if (!strcmp(optarg, "bytes"))
+			sinfo->what = XT_CONNBYTES_BYTES;
+		else if (!strcmp(optarg, "avgpkt"))
+			sinfo->what = XT_CONNBYTES_AVGPKT;
+		else
+			xtables_error(PARAMETER_PROBLEM,
+				   "Unknown --connbytes-mode `%s'", optarg);
+		*flags |= 4;
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void connbytes_check(unsigned int flags)
+{
+	if (flags != 7)
+		xtables_error(PARAMETER_PROBLEM, "You must specify `--connbytes'"
+			   "`--connbytes-dir' and `--connbytes-mode'");
+}
+
+static void print_mode(struct xt_connbytes_info *sinfo)
+{
+	switch (sinfo->what) {
+		case XT_CONNBYTES_PKTS:
+			fputs("packets ", stdout);
+			break;
+		case XT_CONNBYTES_BYTES:
+			fputs("bytes ", stdout);
+			break;
+		case XT_CONNBYTES_AVGPKT:
+			fputs("avgpkt ", stdout);
+			break;
+		default:
+			fputs("unknown ", stdout);
+			break;
+	}
+}
+
+static void print_direction(struct xt_connbytes_info *sinfo)
+{
+	switch (sinfo->direction) {
+		case XT_CONNBYTES_DIR_ORIGINAL:
+			fputs("original ", stdout);
+			break;
+		case XT_CONNBYTES_DIR_REPLY:
+			fputs("reply ", stdout);
+			break;
+		case XT_CONNBYTES_DIR_BOTH:
+			fputs("both ", stdout);
+			break;
+		default:
+			fputs("unknown ", stdout);
+			break;
+	}
+}
+
+static void
+connbytes_print(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+	struct xt_connbytes_info *sinfo = (struct xt_connbytes_info *)match->data;
+
+	if (sinfo->count.from > sinfo->count.to) 
+		printf("connbytes ! %llu:%llu ",
+			(unsigned long long)sinfo->count.to,
+			(unsigned long long)sinfo->count.from);
+	else
+		printf("connbytes %llu:%llu ",
+			(unsigned long long)sinfo->count.from,
+			(unsigned long long)sinfo->count.to);
+
+	fputs("connbytes mode ", stdout);
+	print_mode(sinfo);
+
+	fputs("connbytes direction ", stdout);
+	print_direction(sinfo);
+}
+
+static void connbytes_save(const void *ip, const struct xt_entry_match *match)
+{
+	struct xt_connbytes_info *sinfo = (struct xt_connbytes_info *)match->data;
+
+	if (sinfo->count.from > sinfo->count.to) 
+		printf("! --connbytes %llu:%llu ",
+			(unsigned long long)sinfo->count.to,
+			(unsigned long long)sinfo->count.from);
+	else
+		printf("--connbytes %llu:%llu ",
+			(unsigned long long)sinfo->count.from,
+			(unsigned long long)sinfo->count.to);
+
+	fputs("--connbytes-mode ", stdout);
+	print_mode(sinfo);
+
+	fputs("--connbytes-dir ", stdout);
+	print_direction(sinfo);
+}
+
+static struct xtables_match connbytes_match = {
+	.family		= NFPROTO_IPV4,
+	.name 		= "connbytes",
+	.version 	= XTABLES_VERSION,
+	.size 		= XT_ALIGN(sizeof(struct xt_connbytes_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_connbytes_info)),
+	.help		= connbytes_help,
+	.parse		= connbytes_parse,
+	.final_check	= connbytes_check,
+	.print		= connbytes_print,
+	.save 		= connbytes_save,
+	.extra_opts	= connbytes_opts,
+};
+
+static struct xtables_match connbytes_match6 = {
+	.family		= NFPROTO_IPV6,
+	.name 		= "connbytes",
+	.version 	= XTABLES_VERSION,
+	.size 		= XT_ALIGN(sizeof(struct xt_connbytes_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_connbytes_info)),
+	.help		= connbytes_help,
+	.parse		= connbytes_parse,
+	.final_check	= connbytes_check,
+	.print		= connbytes_print,
+	.save 		= connbytes_save,
+	.extra_opts	= connbytes_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&connbytes_match);
+	xtables_register_match(&connbytes_match6);
+}