From dc5ab2faece3b7473931357db7f63f596678481d Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Sat, 1 Apr 2006 02:22:30 -0800 Subject: [NETFILTER]: x_tables: unify IPv4/IPv6 esp match This unifies ipt_esp and ip6t_esp to xt_esp. Please note that now a user program needs to specify IPPROTO_ESP as protocol to use esp match with IPv6. This means that ip6tables requires '-p esp' like iptables. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/Kconfig | 9 ++++ net/netfilter/Makefile | 1 + net/netfilter/xt_esp.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 net/netfilter/xt_esp.c (limited to 'net/netfilter') diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 332acb37b38..5fe51894b12 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -231,6 +231,15 @@ config NETFILTER_XT_MATCH_DCCP If you want to compile it as a module, say M here and read . If unsure, say `N'. +config NETFILTER_XT_MATCH_ESP + tristate '"ESP" match support' + depends on NETFILTER_XTABLES + help + This match extension allows you to match a range of SPIs + inside ESP header of IPSec packets. + + To compile it as a module, choose M here. If unsure, say N. + config NETFILTER_XT_MATCH_HELPER tristate '"helper" match support' depends on NETFILTER_XTABLES diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 9558727f5e7..8f02486101a 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o +obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c new file mode 100644 index 00000000000..9dad6281e0c --- /dev/null +++ b/net/netfilter/xt_esp.c @@ -0,0 +1,136 @@ +/* Kernel module to match ESP parameters. */ + +/* (C) 1999-2000 Yon Uriarte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yon Uriarte "); +MODULE_DESCRIPTION("x_tables ESP SPI match module"); +MODULE_ALIAS("ipt_esp"); +MODULE_ALIAS("ip6t_esp"); + +#if 0 +#define duprintf(format, args...) printk(format , ## args) +#else +#define duprintf(format, args...) +#endif + +/* Returns 1 if the spi is matched by the range, 0 otherwise */ +static inline int +spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) +{ + int r = 0; + duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ', + min, spi, max); + r = (spi >= min && spi <= max) ^ invert; + duprintf(" result %s\n", r ? "PASS" : "FAILED"); + return r; +} + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct xt_match *match, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + struct ip_esp_hdr _esp, *eh; + const struct xt_esp *espinfo = matchinfo; + + /* Must not be a fragment. */ + if (offset) + return 0; + + eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp); + if (eh == NULL) { + /* We've been asked to examine this packet, and we + * can't. Hence, no choice but to drop. + */ + duprintf("Dropping evil ESP tinygram.\n"); + *hotdrop = 1; + return 0; + } + + return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi), + !!(espinfo->invflags & XT_ESP_INV_SPI)); +} + +/* Called when user tries to insert an entry of this type. */ +static int +checkentry(const char *tablename, + const void *ip_void, + const struct xt_match *match, + void *matchinfo, + unsigned int matchinfosize, + unsigned int hook_mask) +{ + const struct xt_esp *espinfo = matchinfo; + + if (espinfo->invflags & ~XT_ESP_INV_MASK) { + duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); + return 0; + } + + return 1; +} + +static struct xt_match esp_match = { + .name = "esp", + .family = AF_INET, + .proto = IPPROTO_ESP, + .match = &match, + .matchsize = sizeof(struct xt_esp), + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static struct xt_match esp6_match = { + .name = "esp", + .family = AF_INET6, + .proto = IPPROTO_ESP, + .match = &match, + .matchsize = sizeof(struct xt_esp), + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init xt_esp_init(void) +{ + int ret; + ret = xt_register_match(&esp_match); + if (ret) + return ret; + + ret = xt_register_match(&esp6_match); + if (ret) + xt_unregister_match(&esp_match); + + return ret; +} + +static void __exit xt_esp_cleanup(void) +{ + xt_unregister_match(&esp_match); + xt_unregister_match(&esp6_match); +} + +module_init(xt_esp_init); +module_exit(xt_esp_cleanup); -- cgit v1.2.3