aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@computergmbh.de>2008-01-15 02:43:03 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:02:28 -0500
commit1a50c5a1fe20864f1f902ef76862519a65d14723 (patch)
tree4f3d0151d3b1dfa92754d8ea3d28ce8a98ed1548 /net
parentf72e25a897c7edda03a0e1f767925d98772684da (diff)
[NETFILTER]: xt_iprange match, revision 1
Adds IPv6 support to xt_iprange, making it possible to match on IPv6 address ranges with ip6tables. Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_iprange.c122
1 files changed, 113 insertions, 9 deletions
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index c57a6cf8a081..dbea0e0893f3 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -2,6 +2,7 @@
2 * xt_iprange - Netfilter module to match IP address ranges 2 * xt_iprange - Netfilter module to match IP address ranges
3 * 3 *
4 * (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 * (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5 * (C) CC Computer Consultants GmbH, 2008
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -10,6 +11,7 @@
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/skbuff.h> 12#include <linux/skbuff.h>
12#include <linux/ip.h> 13#include <linux/ip.h>
14#include <linux/ipv6.h>
13#include <linux/netfilter/x_tables.h> 15#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter_ipv4/ipt_iprange.h> 16#include <linux/netfilter_ipv4/ipt_iprange.h>
15 17
@@ -51,26 +53,128 @@ iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in,
51 return true; 53 return true;
52} 54}
53 55
54static struct xt_match iprange_mt_reg __read_mostly = { 56static bool
55 .name = "iprange", 57iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
56 .family = AF_INET, 58 const struct net_device *out, const struct xt_match *match,
57 .match = iprange_mt_v0, 59 const void *matchinfo, int offset, unsigned int protoff,
58 .matchsize = sizeof(struct ipt_iprange_info), 60 bool *hotdrop)
59 .me = THIS_MODULE 61{
62 const struct xt_iprange_mtinfo *info = matchinfo;
63 const struct iphdr *iph = ip_hdr(skb);
64 bool m;
65
66 if (info->flags & IPRANGE_SRC) {
67 m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
68 m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
69 m ^= info->flags & IPRANGE_SRC_INV;
70 if (m) {
71 pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
72 NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
73 NIPQUAD(iph->saddr),
74 (info->flags & IPRANGE_SRC_INV) ? "(INV) " : "",
75 NIPQUAD(info->src_max.ip),
76 NIPQUAD(info->src_max.ip));
77 return false;
78 }
79 }
80 if (info->flags & IPRANGE_DST) {
81 m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
82 m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
83 m ^= info->flags & IPRANGE_DST_INV;
84 if (m) {
85 pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
86 NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
87 NIPQUAD(iph->daddr),
88 (info->flags & IPRANGE_DST_INV) ? "(INV) " : "",
89 NIPQUAD(info->dst_min.ip),
90 NIPQUAD(info->dst_max.ip));
91 return false;
92 }
93 }
94 return true;
95}
96
97static inline int
98iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
99{
100 unsigned int i;
101 int r;
102
103 for (i = 0; i < 4; ++i) {
104 r = a->s6_addr32[i] - b->s6_addr32[i];
105 if (r != 0)
106 return r;
107 }
108
109 return 0;
110}
111
112static bool
113iprange_mt6(const struct sk_buff *skb, const struct net_device *in,
114 const struct net_device *out, const struct xt_match *match,
115 const void *matchinfo, int offset, unsigned int protoff,
116 bool *hotdrop)
117{
118 const struct xt_iprange_mtinfo *info = matchinfo;
119 const struct ipv6hdr *iph = ipv6_hdr(skb);
120 bool m;
121
122 if (info->flags & IPRANGE_SRC) {
123 m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
124 m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
125 m ^= info->flags & IPRANGE_SRC_INV;
126 if (m)
127 return false;
128 }
129 if (info->flags & IPRANGE_DST) {
130 m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
131 m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
132 m ^= info->flags & IPRANGE_DST_INV;
133 if (m)
134 return false;
135 }
136 return true;
137}
138
139static struct xt_match iprange_mt_reg[] __read_mostly = {
140 {
141 .name = "iprange",
142 .revision = 0,
143 .family = AF_INET,
144 .match = iprange_mt_v0,
145 .matchsize = sizeof(struct ipt_iprange_info),
146 .me = THIS_MODULE,
147 },
148 {
149 .name = "iprange",
150 .revision = 1,
151 .family = AF_INET6,
152 .match = iprange_mt4,
153 .matchsize = sizeof(struct xt_iprange_mtinfo),
154 .me = THIS_MODULE,
155 },
156 {
157 .name = "iprange",
158 .revision = 1,
159 .family = AF_INET6,
160 .match = iprange_mt6,
161 .matchsize = sizeof(struct xt_iprange_mtinfo),
162 .me = THIS_MODULE,
163 },
60}; 164};
61 165
62static int __init iprange_mt_init(void) 166static int __init iprange_mt_init(void)
63{ 167{
64 return xt_register_match(&iprange_mt_reg); 168 return xt_register_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
65} 169}
66 170
67static void __exit iprange_mt_exit(void) 171static void __exit iprange_mt_exit(void)
68{ 172{
69 xt_unregister_match(&iprange_mt_reg); 173 xt_unregister_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
70} 174}
71 175
72module_init(iprange_mt_init); 176module_init(iprange_mt_init);
73module_exit(iprange_mt_exit); 177module_exit(iprange_mt_exit);
74MODULE_LICENSE("GPL"); 178MODULE_LICENSE("GPL");
75MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 179MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
76MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching"); 180MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");