summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfan.du <fan.du@windriver.com>2013-12-18 11:27:22 +0800
committerPablo Neira Ayuso <pablo@netfilter.org>2013-12-24 12:46:20 +0100
commit0bb8765cc28cf1ddde70f3f5bfed96a067b1ead3 (patch)
tree5526af0109f6c4552ce46b20cc5587d66b54cd96
parent99b85b7837707bd6c6d578c9328e1321fceb8082 (diff)
iptables: Add IPv4/6 IPcomp match support
This patch enables user to set iptables ACTIONs for IPcomp flow specified by its SPI value. For example: iptables -A OUTPUT -p 108 -m ipcomp --ipcompspi 0x12 -j DROP ip6tables -A OUTPUT -p 108 -m ipcomp --ipcompspi 0x12 -j DROP IPcomp packet with spi as 0x12 will be dropped. Signed-off-by: Fan Du <fan.du@windriver.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--extensions/libxt_ipcomp.c116
-rw-r--r--extensions/libxt_ipcomp.c.man7
-rw-r--r--include/linux/netfilter/xt_ipcomp.h16
3 files changed, 139 insertions, 0 deletions
diff --git a/extensions/libxt_ipcomp.c b/extensions/libxt_ipcomp.c
new file mode 100644
index 00000000..b157e7b1
--- /dev/null
+++ b/extensions/libxt_ipcomp.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <xtables.h>
+#include <linux/netfilter/xt_ipcomp.h>
+
+enum {
+ O_compSPI = 0,
+ O_compRES,
+};
+
+static void comp_help(void)
+{
+ printf(
+"comp match options:\n"
+"[!] --ipcompspi spi[:spi]\n"
+" match spi (range)\n");
+}
+
+static const struct xt_option_entry comp_opts[] = {
+ {.name = "ipcompspi", .id = O_compSPI, .type = XTTYPE_UINT32RC,
+ .flags = XTOPT_INVERT | XTOPT_PUT,
+ XTOPT_POINTER(struct xt_ipcomp, spis)},
+ {.name = "compres", .id = O_compRES, .type = XTTYPE_NONE},
+ XTOPT_TABLEEND,
+};
+#undef s
+
+static void comp_parse(struct xt_option_call *cb)
+{
+ struct xt_ipcomp *compinfo = cb->data;
+
+ xtables_option_parse(cb);
+ switch (cb->entry->id) {
+ case O_compSPI:
+ if (cb->nvals == 1)
+ compinfo->spis[1] = compinfo->spis[0];
+ if (cb->invert)
+ compinfo->invflags |= XT_IPCOMP_INV_SPI;
+ break;
+ case O_compRES:
+ compinfo->hdrres = 1;
+ break;
+ }
+}
+
+static void
+print_spis(const char *name, uint32_t min, uint32_t max,
+ int invert)
+{
+ const char *inv = invert ? "!" : "";
+
+ if (min != 0 || max != 0xFFFFFFFF || invert) {
+ if (min == max)
+ printf("%s:%s%u", name, inv, min);
+ else
+ printf("%ss:%s%u:%u", name, inv, min, max);
+ }
+}
+
+static void comp_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ const struct xt_ipcomp *comp = (struct xt_ipcomp *)match->data;
+
+ printf(" comp ");
+ print_spis("spi", comp->spis[0], comp->spis[1],
+ comp->invflags & XT_IPCOMP_INV_SPI);
+
+ if (comp->hdrres)
+ printf(" reserved");
+
+ if (comp->invflags & ~XT_IPCOMP_INV_MASK)
+ printf(" Unknown invflags: 0x%X",
+ comp->invflags & ~XT_IPCOMP_INV_MASK);
+}
+
+static void comp_save(const void *ip, const struct xt_entry_match *match)
+{
+ const struct xt_ipcomp *compinfo = (struct xt_ipcomp *)match->data;
+
+ if (!(compinfo->spis[0] == 0
+ && compinfo->spis[1] == 0xFFFFFFFF)) {
+ printf("%s --ipcompspi ",
+ (compinfo->invflags & XT_IPCOMP_INV_SPI) ? " !" : "");
+ if (compinfo->spis[0]
+ != compinfo->spis[1])
+ printf("%u:%u",
+ compinfo->spis[0],
+ compinfo->spis[1]);
+ else
+ printf("%u",
+ compinfo->spis[0]);
+ }
+
+ if (compinfo->hdrres != 0 )
+ printf(" --compres");
+}
+
+static struct xtables_match comp_mt_reg = {
+ .name = "ipcomp",
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_UNSPEC,
+ .size = XT_ALIGN(sizeof(struct xt_ipcomp)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_ipcomp)),
+ .help = comp_help,
+ .print = comp_print,
+ .save = comp_save,
+ .x6_parse = comp_parse,
+ .x6_options = comp_opts,
+};
+
+void
+_init(void)
+{
+ xtables_register_match(&comp_mt_reg);
+};
+
diff --git a/extensions/libxt_ipcomp.c.man b/extensions/libxt_ipcomp.c.man
new file mode 100644
index 00000000..f3b17d21
--- /dev/null
+++ b/extensions/libxt_ipcomp.c.man
@@ -0,0 +1,7 @@
+This module matches the parameters in IPcomp header of IPsec packets.
+.TP
+[\fB!\fP] \fB\-\-ipcompspi\fP \fIspi\fP[\fB:\fP\fIspi\fP]
+Matches IPcomp header CPI value.
+.TP
+\fB\-\-compres\fP
+Matches if the reserved field is filled with zero.
diff --git a/include/linux/netfilter/xt_ipcomp.h b/include/linux/netfilter/xt_ipcomp.h
new file mode 100644
index 00000000..45c7e40e
--- /dev/null
+++ b/include/linux/netfilter/xt_ipcomp.h
@@ -0,0 +1,16 @@
+#ifndef _XT_IPCOMP_H
+#define _XT_IPCOMP_H
+
+#include <linux/types.h>
+
+struct xt_ipcomp {
+ __u32 spis[2]; /* Security Parameter Index */
+ __u8 invflags; /* Inverse flags */
+ __u8 hdrres; /* Test of the Reserved Filed */
+};
+
+/* Values for "invflags" field in struct xt_ipcomp. */
+#define XT_IPCOMP_INV_SPI 0x01 /* Invert the sense of spi. */
+#define XT_IPCOMP_INV_MASK 0x01 /* All possible flags. */
+
+#endif /*_XT_IPCOMP_H*/