root/net/netfilter/xt_iprange.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iprange_mt4
  2. iprange_ipv6_lt
  3. iprange_mt6
  4. iprange_mt_init
  5. iprange_mt_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *      xt_iprange - Netfilter module to match IP address ranges
   4  *
   5  *      (C) 2003 Jozsef Kadlecsik <kadlec@netfilter.org>
   6  *      (C) CC Computer Consultants GmbH, 2008
   7  */
   8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9 #include <linux/module.h>
  10 #include <linux/skbuff.h>
  11 #include <linux/ip.h>
  12 #include <linux/ipv6.h>
  13 #include <linux/netfilter/x_tables.h>
  14 #include <linux/netfilter/xt_iprange.h>
  15 
  16 static bool
  17 iprange_mt4(const struct sk_buff *skb, struct xt_action_param *par)
  18 {
  19         const struct xt_iprange_mtinfo *info = par->matchinfo;
  20         const struct iphdr *iph = ip_hdr(skb);
  21         bool m;
  22 
  23         if (info->flags & IPRANGE_SRC) {
  24                 m  = ntohl(iph->saddr) < ntohl(info->src_min.ip);
  25                 m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
  26                 m ^= !!(info->flags & IPRANGE_SRC_INV);
  27                 if (m) {
  28                         pr_debug("src IP %pI4 NOT in range %s%pI4-%pI4\n",
  29                                  &iph->saddr,
  30                                  (info->flags & IPRANGE_SRC_INV) ? "(INV) " : "",
  31                                  &info->src_min.ip,
  32                                  &info->src_max.ip);
  33                         return false;
  34                 }
  35         }
  36         if (info->flags & IPRANGE_DST) {
  37                 m  = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
  38                 m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
  39                 m ^= !!(info->flags & IPRANGE_DST_INV);
  40                 if (m) {
  41                         pr_debug("dst IP %pI4 NOT in range %s%pI4-%pI4\n",
  42                                  &iph->daddr,
  43                                  (info->flags & IPRANGE_DST_INV) ? "(INV) " : "",
  44                                  &info->dst_min.ip,
  45                                  &info->dst_max.ip);
  46                         return false;
  47                 }
  48         }
  49         return true;
  50 }
  51 
  52 static inline int
  53 iprange_ipv6_lt(const struct in6_addr *a, const struct in6_addr *b)
  54 {
  55         unsigned int i;
  56 
  57         for (i = 0; i < 4; ++i) {
  58                 if (a->s6_addr32[i] != b->s6_addr32[i])
  59                         return ntohl(a->s6_addr32[i]) < ntohl(b->s6_addr32[i]);
  60         }
  61 
  62         return 0;
  63 }
  64 
  65 static bool
  66 iprange_mt6(const struct sk_buff *skb, struct xt_action_param *par)
  67 {
  68         const struct xt_iprange_mtinfo *info = par->matchinfo;
  69         const struct ipv6hdr *iph = ipv6_hdr(skb);
  70         bool m;
  71 
  72         if (info->flags & IPRANGE_SRC) {
  73                 m  = iprange_ipv6_lt(&iph->saddr, &info->src_min.in6);
  74                 m |= iprange_ipv6_lt(&info->src_max.in6, &iph->saddr);
  75                 m ^= !!(info->flags & IPRANGE_SRC_INV);
  76                 if (m) {
  77                         pr_debug("src IP %pI6 NOT in range %s%pI6-%pI6\n",
  78                                  &iph->saddr,
  79                                  (info->flags & IPRANGE_SRC_INV) ? "(INV) " : "",
  80                                  &info->src_min.in6,
  81                                  &info->src_max.in6);
  82                         return false;
  83                 }
  84         }
  85         if (info->flags & IPRANGE_DST) {
  86                 m  = iprange_ipv6_lt(&iph->daddr, &info->dst_min.in6);
  87                 m |= iprange_ipv6_lt(&info->dst_max.in6, &iph->daddr);
  88                 m ^= !!(info->flags & IPRANGE_DST_INV);
  89                 if (m) {
  90                         pr_debug("dst IP %pI6 NOT in range %s%pI6-%pI6\n",
  91                                  &iph->daddr,
  92                                  (info->flags & IPRANGE_DST_INV) ? "(INV) " : "",
  93                                  &info->dst_min.in6,
  94                                  &info->dst_max.in6);
  95                         return false;
  96                 }
  97         }
  98         return true;
  99 }
 100 
 101 static struct xt_match iprange_mt_reg[] __read_mostly = {
 102         {
 103                 .name      = "iprange",
 104                 .revision  = 1,
 105                 .family    = NFPROTO_IPV4,
 106                 .match     = iprange_mt4,
 107                 .matchsize = sizeof(struct xt_iprange_mtinfo),
 108                 .me        = THIS_MODULE,
 109         },
 110         {
 111                 .name      = "iprange",
 112                 .revision  = 1,
 113                 .family    = NFPROTO_IPV6,
 114                 .match     = iprange_mt6,
 115                 .matchsize = sizeof(struct xt_iprange_mtinfo),
 116                 .me        = THIS_MODULE,
 117         },
 118 };
 119 
 120 static int __init iprange_mt_init(void)
 121 {
 122         return xt_register_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
 123 }
 124 
 125 static void __exit iprange_mt_exit(void)
 126 {
 127         xt_unregister_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
 128 }
 129 
 130 module_init(iprange_mt_init);
 131 module_exit(iprange_mt_exit);
 132 MODULE_LICENSE("GPL");
 133 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
 134 MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 135 MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
 136 MODULE_ALIAS("ipt_iprange");
 137 MODULE_ALIAS("ip6t_iprange");

/* [<][>][^][v][top][bottom][index][help] */