[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/tos_values.c b/ap/app/iptables/extensions/tos_values.c
new file mode 100755
index 0000000..2676d81
--- /dev/null
+++ b/ap/app/iptables/extensions/tos_values.c
@@ -0,0 +1,92 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <linux/ip.h>
+
+struct tos_value_mask {
+	uint8_t value, mask;
+};
+
+static const struct tos_symbol_info {
+	unsigned char value;
+	const char *name;
+} tos_symbol_names[] = {
+	{IPTOS_LOWDELAY,    "Minimize-Delay"},
+	{IPTOS_THROUGHPUT,  "Maximize-Throughput"},
+	{IPTOS_RELIABILITY, "Maximize-Reliability"},
+	{IPTOS_MINCOST,     "Minimize-Cost"},
+	{IPTOS_NORMALSVC,   "Normal-Service"},
+	{ .name = NULL }
+};
+
+/*
+ * tos_parse_numeric - parse sth. like "15/255"
+ *
+ * @s:		input string
+ * @info:	accompanying structure
+ * @bits:	number of bits that are allowed
+ *		(8 for IPv4 TOS field, 4 for IPv6 Priority Field)
+ */
+static bool tos_parse_numeric(const char *str, struct tos_value_mask *tvm,
+                              unsigned int bits)
+{
+	const unsigned int max = (1 << bits) - 1;
+	unsigned int value;
+	char *end;
+
+	xtables_strtoui(str, &end, &value, 0, max);
+	tvm->value = value;
+	tvm->mask  = max;
+
+	if (*end == '/') {
+		const char *p = end + 1;
+
+		if (!xtables_strtoui(p, &end, &value, 0, max))
+			xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"",
+			           str);
+		tvm->mask = value;
+	}
+
+	if (*end != '\0')
+		xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", str);
+	return true;
+}
+
+static bool tos_parse_symbolic(const char *str, struct tos_value_mask *tvm,
+    unsigned int def_mask)
+{
+	const unsigned int max = UINT8_MAX;
+	const struct tos_symbol_info *symbol;
+	char *tmp;
+
+	if (xtables_strtoui(str, &tmp, NULL, 0, max))
+		return tos_parse_numeric(str, tvm, max);
+
+	/* Do not consider ECN bits */
+	tvm->mask = def_mask;
+	for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
+		if (strcasecmp(str, symbol->name) == 0) {
+			tvm->value = symbol->value;
+			return true;
+		}
+
+	xtables_error(PARAMETER_PROBLEM, "Symbolic name \"%s\" is unknown", str);
+	return false;
+}
+
+static bool tos_try_print_symbolic(const char *prefix,
+    u_int8_t value, u_int8_t mask)
+{
+	const struct tos_symbol_info *symbol;
+
+	if (mask != 0x3F)
+		return false;
+
+	for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
+		if (value == symbol->value) {
+			printf("%s%s ", prefix, symbol->name);
+			return true;
+		}
+
+	return false;
+}