2 * xt_iprange - Netfilter module to match IP address ranges
4 * (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5 * (C) CC Computer Consultants GmbH, 2008
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 #include <linux/module.h>
12 #include <linux/skbuff.h>
14 #include <linux/ipv6.h>
15 #include <linux/netfilter/x_tables.h>
16 #include <linux/netfilter/xt_iprange.h>
17 #include <linux/netfilter_ipv4/ipt_iprange.h>
20 iprange_mt_v0(const struct sk_buff
*skb
, const struct xt_match_param
*par
)
22 const struct ipt_iprange_info
*info
= par
->matchinfo
;
23 const struct iphdr
*iph
= ip_hdr(skb
);
25 if (info
->flags
& IPRANGE_SRC
) {
26 if ((ntohl(iph
->saddr
) < ntohl(info
->src
.min_ip
)
27 || ntohl(iph
->saddr
) > ntohl(info
->src
.max_ip
))
28 ^ !!(info
->flags
& IPRANGE_SRC_INV
)) {
29 pr_debug("src IP %u.%u.%u.%u NOT in range %s"
30 "%u.%u.%u.%u-%u.%u.%u.%u\n",
32 info
->flags
& IPRANGE_SRC_INV
? "(INV) " : "",
33 NIPQUAD(info
->src
.min_ip
),
34 NIPQUAD(info
->src
.max_ip
));
38 if (info
->flags
& IPRANGE_DST
) {
39 if ((ntohl(iph
->daddr
) < ntohl(info
->dst
.min_ip
)
40 || ntohl(iph
->daddr
) > ntohl(info
->dst
.max_ip
))
41 ^ !!(info
->flags
& IPRANGE_DST_INV
)) {
42 pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
43 "%u.%u.%u.%u-%u.%u.%u.%u\n",
45 info
->flags
& IPRANGE_DST_INV
? "(INV) " : "",
46 NIPQUAD(info
->dst
.min_ip
),
47 NIPQUAD(info
->dst
.max_ip
));
55 iprange_mt4(const struct sk_buff
*skb
, const struct xt_match_param
*par
)
57 const struct xt_iprange_mtinfo
*info
= par
->matchinfo
;
58 const struct iphdr
*iph
= ip_hdr(skb
);
61 if (info
->flags
& IPRANGE_SRC
) {
62 m
= ntohl(iph
->saddr
) < ntohl(info
->src_min
.ip
);
63 m
|= ntohl(iph
->saddr
) > ntohl(info
->src_max
.ip
);
64 m
^= info
->flags
& IPRANGE_SRC_INV
;
66 pr_debug("src IP " NIPQUAD_FMT
" NOT in range %s"
67 NIPQUAD_FMT
"-" NIPQUAD_FMT
"\n",
69 (info
->flags
& IPRANGE_SRC_INV
) ? "(INV) " : "",
70 NIPQUAD(info
->src_max
.ip
),
71 NIPQUAD(info
->src_max
.ip
));
75 if (info
->flags
& IPRANGE_DST
) {
76 m
= ntohl(iph
->daddr
) < ntohl(info
->dst_min
.ip
);
77 m
|= ntohl(iph
->daddr
) > ntohl(info
->dst_max
.ip
);
78 m
^= info
->flags
& IPRANGE_DST_INV
;
80 pr_debug("dst IP " NIPQUAD_FMT
" NOT in range %s"
81 NIPQUAD_FMT
"-" NIPQUAD_FMT
"\n",
83 (info
->flags
& IPRANGE_DST_INV
) ? "(INV) " : "",
84 NIPQUAD(info
->dst_min
.ip
),
85 NIPQUAD(info
->dst_max
.ip
));
93 iprange_ipv6_sub(const struct in6_addr
*a
, const struct in6_addr
*b
)
98 for (i
= 0; i
< 4; ++i
) {
99 r
= ntohl(a
->s6_addr32
[i
]) - ntohl(b
->s6_addr32
[i
]);
108 iprange_mt6(const struct sk_buff
*skb
, const struct xt_match_param
*par
)
110 const struct xt_iprange_mtinfo
*info
= par
->matchinfo
;
111 const struct ipv6hdr
*iph
= ipv6_hdr(skb
);
114 if (info
->flags
& IPRANGE_SRC
) {
115 m
= iprange_ipv6_sub(&iph
->saddr
, &info
->src_min
.in6
) < 0;
116 m
|= iprange_ipv6_sub(&iph
->saddr
, &info
->src_max
.in6
) > 0;
117 m
^= info
->flags
& IPRANGE_SRC_INV
;
121 if (info
->flags
& IPRANGE_DST
) {
122 m
= iprange_ipv6_sub(&iph
->daddr
, &info
->dst_min
.in6
) < 0;
123 m
|= iprange_ipv6_sub(&iph
->daddr
, &info
->dst_max
.in6
) > 0;
124 m
^= info
->flags
& IPRANGE_DST_INV
;
131 static struct xt_match iprange_mt_reg
[] __read_mostly
= {
135 .family
= NFPROTO_IPV4
,
136 .match
= iprange_mt_v0
,
137 .matchsize
= sizeof(struct ipt_iprange_info
),
143 .family
= NFPROTO_IPV4
,
144 .match
= iprange_mt4
,
145 .matchsize
= sizeof(struct xt_iprange_mtinfo
),
151 .family
= NFPROTO_IPV6
,
152 .match
= iprange_mt6
,
153 .matchsize
= sizeof(struct xt_iprange_mtinfo
),
158 static int __init
iprange_mt_init(void)
160 return xt_register_matches(iprange_mt_reg
, ARRAY_SIZE(iprange_mt_reg
));
163 static void __exit
iprange_mt_exit(void)
165 xt_unregister_matches(iprange_mt_reg
, ARRAY_SIZE(iprange_mt_reg
));
168 module_init(iprange_mt_init
);
169 module_exit(iprange_mt_exit
);
170 MODULE_LICENSE("GPL");
171 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
172 MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
173 MODULE_ALIAS("ipt_iprange");
174 MODULE_ALIAS("ip6t_iprange");