linux/net/netfilter/xt_esp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Kernel module to match ESP parameters. */
   3
   4/* (C) 1999-2000 Yon Uriarte <yon@astaro.de>
   5 */
   6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   7#include <linux/module.h>
   8#include <linux/skbuff.h>
   9#include <linux/in.h>
  10#include <linux/ip.h>
  11
  12#include <linux/netfilter/xt_esp.h>
  13#include <linux/netfilter/x_tables.h>
  14
  15#include <linux/netfilter_ipv4/ip_tables.h>
  16#include <linux/netfilter_ipv6/ip6_tables.h>
  17
  18MODULE_LICENSE("GPL");
  19MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
  20MODULE_DESCRIPTION("Xtables: IPsec-ESP packet match");
  21MODULE_ALIAS("ipt_esp");
  22MODULE_ALIAS("ip6t_esp");
  23
  24/* Returns 1 if the spi is matched by the range, 0 otherwise */
  25static inline bool
  26spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
  27{
  28        bool r;
  29        pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
  30                 invert ? '!' : ' ', min, spi, max);
  31        r = (spi >= min && spi <= max) ^ invert;
  32        pr_debug(" result %s\n", r ? "PASS" : "FAILED");
  33        return r;
  34}
  35
  36static bool esp_mt(const struct sk_buff *skb, struct xt_action_param *par)
  37{
  38        const struct ip_esp_hdr *eh;
  39        struct ip_esp_hdr _esp;
  40        const struct xt_esp *espinfo = par->matchinfo;
  41
  42        /* Must not be a fragment. */
  43        if (par->fragoff != 0)
  44                return false;
  45
  46        eh = skb_header_pointer(skb, par->thoff, sizeof(_esp), &_esp);
  47        if (eh == NULL) {
  48                /* We've been asked to examine this packet, and we
  49                 * can't.  Hence, no choice but to drop.
  50                 */
  51                pr_debug("Dropping evil ESP tinygram.\n");
  52                par->hotdrop = true;
  53                return false;
  54        }
  55
  56        return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
  57                         !!(espinfo->invflags & XT_ESP_INV_SPI));
  58}
  59
  60static int esp_mt_check(const struct xt_mtchk_param *par)
  61{
  62        const struct xt_esp *espinfo = par->matchinfo;
  63
  64        if (espinfo->invflags & ~XT_ESP_INV_MASK) {
  65                pr_debug("unknown flags %X\n", espinfo->invflags);
  66                return -EINVAL;
  67        }
  68
  69        return 0;
  70}
  71
  72static struct xt_match esp_mt_reg[] __read_mostly = {
  73        {
  74                .name           = "esp",
  75                .family         = NFPROTO_IPV4,
  76                .checkentry     = esp_mt_check,
  77                .match          = esp_mt,
  78                .matchsize      = sizeof(struct xt_esp),
  79                .proto          = IPPROTO_ESP,
  80                .me             = THIS_MODULE,
  81        },
  82        {
  83                .name           = "esp",
  84                .family         = NFPROTO_IPV6,
  85                .checkentry     = esp_mt_check,
  86                .match          = esp_mt,
  87                .matchsize      = sizeof(struct xt_esp),
  88                .proto          = IPPROTO_ESP,
  89                .me             = THIS_MODULE,
  90        },
  91};
  92
  93static int __init esp_mt_init(void)
  94{
  95        return xt_register_matches(esp_mt_reg, ARRAY_SIZE(esp_mt_reg));
  96}
  97
  98static void __exit esp_mt_exit(void)
  99{
 100        xt_unregister_matches(esp_mt_reg, ARRAY_SIZE(esp_mt_reg));
 101}
 102
 103module_init(esp_mt_init);
 104module_exit(esp_mt_exit);
 105