[18/19] libxt_TCPOPTSTRIP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Import libxt_TCPOPTSTRIP into iptables.

Signed-off-by: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx>
Cc: Sven Schnelle <svens@xxxxxxxxxxxx>

---
 extensions/libxt_TCPOPTSTRIP.c           |  212 +++++++++++++++++++++++++++++++
 extensions/libxt_TCPOPTSTRIP.man         |    7 +
 include/linux/netfilter/xt_TCPOPTSTRIP.h |   13 +
 4 files changed, 233 insertions(+)

Index: iptables-modules/extensions/libxt_TCPOPTSTRIP.c
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_TCPOPTSTRIP.c
@@ -0,0 +1,212 @@
+/*
+ * Shared library add-on to iptables to add TCPOPTSTRIP target support.
+ * Copyright (c) 2007 Sven Schnelle <svens@xxxxxxxxxxxx>
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx>
+ */
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.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 int option;
+};
+
+static const struct option tcpoptstrip_tg_opts[] = {
+	{.name = "strip-options", .has_arg = true, .val = 's'},
+	{},
+};
+
+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},
+	{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 && string_to_number(arg, 0, 255, &option) == -1)
+			exit_error(PARAMETER_PROBLEM,
+			           "Bad TCP option value \"%s\"", arg);
+
+		if (option < 2)
+			exit_error(PARAMETER_PROBLEM,
+			           "Option value may not be 0 or 1");
+
+		if (tcpoptstrip_test_bit(info->strip_bmap, option))
+			exit_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)
+			exit_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)
+		exit_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       = IPTABLES_VERSION,
+	.name          = "TCPOPTSTRIP",
+	.family        = AF_INET,
+	.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       = IPTABLES_VERSION,
+	.name          = "TCPOPTSTRIP",
+	.family        = AF_INET6,
+	.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);
+}
Index: iptables-modules/extensions/libxt_TCPOPTSTRIP.man
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_TCPOPTSTRIP.man
@@ -0,0 +1,7 @@
+This target will strip TCP options off a TCP packet. (It will actually replace
+them by NO-OPs.) As such, you will need to add the \fB-p tcp\fR parameters.
+.TP
+\fB--strip-options\fR \fIoption\fR[\fB,\fR\fI...\fR]
+Strip the given option(s). The options may be specified by TCP option number or
+by symbolic name. The list of recognized options can be obtained by calling
+iptables with \fB-j TCPOPTSTRIP -h\fR.
Index: iptables-modules/include/linux/netfilter/xt_TCPOPTSTRIP.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter/xt_TCPOPTSTRIP.h
@@ -0,0 +1,13 @@
+#ifndef _XT_TCPOPTSTRIP_H
+#define _XT_TCPOPTSTRIP_H
+
+#define tcpoptstrip_set_bit(bmap, idx) \
+	(bmap[(idx) >> 5] |= 1U << (idx & 31))
+#define tcpoptstrip_test_bit(bmap, idx) \
+	(((1U << (idx & 31)) & bmap[(idx) >> 5]) != 0)
+
+struct xt_tcpoptstrip_target_info {
+	u_int32_t strip_bmap[8];
+};
+
+#endif /* _XT_TCPOPTSTRIP_H */
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux