Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 244 lines (209 sloc) 6.674 kb
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
1 /*
2 * iptables module to match inet_addr_type() of an ip.
3 *
4 * Copyright (c) 2004 Patrick McHardy <kaber@trash.net>
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
5 * (C) 2007 Laszlo Attila Toth <panther@balabit.hu>
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
6 *
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.
10 */
ff67e4e4 »
2010-03-19 netfilter: xt extensions: use pr_<level> (2)
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/skbuff.h>
15 #include <linux/netdevice.h>
16 #include <linux/ip.h>
17 #include <net/route.h>
18
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
19 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
20 #include <net/ipv6.h>
21 #include <net/ip6_route.h>
22 #include <net/ip6_fib.h>
23 #endif
24
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
25 #include <linux/netfilter/xt_addrtype.h>
6709dbbb »
2007-02-07 [NETFILTER]: {ip,ip6}_tables: remove x_tables wrapper functions
26 #include <linux/netfilter/x_tables.h>
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
27
28 MODULE_LICENSE("GPL");
29 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
30 MODULE_DESCRIPTION("Xtables: address type match");
31 MODULE_ALIAS("ipt_addrtype");
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
32 MODULE_ALIAS("ip6t_addrtype");
33
34 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
b7225041 »
2011-04-04 netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route
35 static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
36 const struct in6_addr *addr)
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
37 {
b7225041 »
2011-04-04 netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route
38 const struct nf_afinfo *afinfo;
39 struct flowi6 flow;
40 struct rt6_info *rt;
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
41 u32 ret;
b7225041 »
2011-04-04 netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route
42 int route_err;
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
43
b7225041 »
2011-04-04 netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route
44 memset(&flow, 0, sizeof(flow));
45 ipv6_addr_copy(&flow.daddr, addr);
46 if (dev)
47 flow.flowi6_oif = dev->ifindex;
48
49 rcu_read_lock();
50
51 afinfo = nf_get_afinfo(NFPROTO_IPV6);
52 if (afinfo != NULL)
53 route_err = afinfo->route(net, (struct dst_entry **)&rt,
54 flowi6_to_flowi(&flow), !!dev);
55 else
56 route_err = 1;
57
58 rcu_read_unlock();
59
60 if (route_err)
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
61 return XT_ADDRTYPE_UNREACHABLE;
62
63 if (rt->rt6i_flags & RTF_REJECT)
64 ret = XT_ADDRTYPE_UNREACHABLE;
65 else
66 ret = 0;
67
68 if (rt->rt6i_flags & RTF_LOCAL)
69 ret |= XT_ADDRTYPE_LOCAL;
70 if (rt->rt6i_flags & RTF_ANYCAST)
71 ret |= XT_ADDRTYPE_ANYCAST;
b7225041 »
2011-04-04 netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route
72
73
74 dst_release(&rt->dst);
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
75 return ret;
76 }
77
78 static bool match_type6(struct net *net, const struct net_device *dev,
79 const struct in6_addr *addr, u16 mask)
80 {
81 int addr_type = ipv6_addr_type(addr);
82
83 if ((mask & XT_ADDRTYPE_MULTICAST) &&
84 !(addr_type & IPV6_ADDR_MULTICAST))
85 return false;
86 if ((mask & XT_ADDRTYPE_UNICAST) && !(addr_type & IPV6_ADDR_UNICAST))
87 return false;
88 if ((mask & XT_ADDRTYPE_UNSPEC) && addr_type != IPV6_ADDR_ANY)
89 return false;
90
91 if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |
b7225041 »
2011-04-04 netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route
92 XT_ADDRTYPE_UNREACHABLE) & mask)
93 return !!(mask & match_lookup_rt6(net, dev, addr));
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
94 return true;
95 }
96
97 static bool
98 addrtype_mt6(struct net *net, const struct net_device *dev,
99 const struct sk_buff *skb, const struct xt_addrtype_info_v1 *info)
100 {
101 const struct ipv6hdr *iph = ipv6_hdr(skb);
102 bool ret = true;
103
104 if (info->source)
105 ret &= match_type6(net, dev, &iph->saddr, info->source) ^
106 (info->flags & XT_ADDRTYPE_INVERT_SOURCE);
107 if (ret && info->dest)
108 ret &= match_type6(net, dev, &iph->daddr, info->dest) ^
109 !!(info->flags & XT_ADDRTYPE_INVERT_DEST);
110 return ret;
111 }
112 #endif
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
113
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
114 static inline bool match_type(struct net *net, const struct net_device *dev,
115 __be32 addr, u_int16_t mask)
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
116 {
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
117 return !!(mask & (1 << inet_dev_addr_type(net, dev, addr)));
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
118 }
119
d3c5ee6d »
2007-12-04 [NETFILTER]: x_tables: consistent and unique symbol names
120 static bool
62fc8051 »
2009-07-07 netfilter: xtables: deconstify struct xt_action_param for matches
121 addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
122 {
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
123 struct net *net = dev_net(par->in ? par->in : par->out);
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
124 const struct xt_addrtype_info *info = par->matchinfo;
eddc9ec5 »
2007-04-20 [SK_BUFF]: Introduce ip_hdr(), remove skb->nh.iph
125 const struct iphdr *iph = ip_hdr(skb);
1d93a9cb »
2007-07-07 [NETFILTER]: x_tables: switch xt_match->match to bool
126 bool ret = true;
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
127
128 if (info->source)
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
129 ret &= match_type(net, NULL, iph->saddr, info->source) ^
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
130 info->invert_source;
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
131 if (info->dest)
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
132 ret &= match_type(net, NULL, iph->daddr, info->dest) ^
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
133 info->invert_dest;
e905a9ed »
2007-02-09 [NET] IPV4: Fix whitespace errors.
134
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
135 return ret;
136 }
137
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
138 static bool
62fc8051 »
2009-07-07 netfilter: xtables: deconstify struct xt_action_param for matches
139 addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
140 {
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
141 struct net *net = dev_net(par->in ? par->in : par->out);
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
142 const struct xt_addrtype_info_v1 *info = par->matchinfo;
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
143 const struct iphdr *iph;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
144 const struct net_device *dev = NULL;
145 bool ret = true;
146
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
147 if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN)
f7108a20 »
2008-10-08 netfilter: xtables: move extension arguments into compound structure …
148 dev = par->in;
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
149 else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)
f7108a20 »
2008-10-08 netfilter: xtables: move extension arguments into compound structure …
150 dev = par->out;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
151
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
152 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
153 if (par->family == NFPROTO_IPV6)
154 return addrtype_mt6(net, dev, skb, info);
155 #endif
156 iph = ip_hdr(skb);
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
157 if (info->source)
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
158 ret &= match_type(net, dev, iph->saddr, info->source) ^
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
159 (info->flags & XT_ADDRTYPE_INVERT_SOURCE);
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
160 if (ret && info->dest)
d4ec52ba »
2008-11-04 netfilter: netns-aware ipt_addrtype
161 ret &= match_type(net, dev, iph->daddr, info->dest) ^
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
162 !!(info->flags & XT_ADDRTYPE_INVERT_DEST);
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
163 return ret;
164 }
165
b0f38452 »
2010-03-19 netfilter: xtables: change xt_match.checkentry return type
166 static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
167 {
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
168 struct xt_addrtype_info_v1 *info = par->matchinfo;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
169
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
170 if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&
171 info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) {
ff67e4e4 »
2010-03-19 netfilter: xt extensions: use pr_<level> (2)
172 pr_info("both incoming and outgoing "
173 "interface limitation cannot be selected\n");
bd414ee6 »
2010-03-23 netfilter: xtables: change matches to return error code
174 return -EINVAL;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
175 }
176
9b4fce7a »
2008-10-08 netfilter: xtables: move extension arguments into compound structure …
177 if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
178 (1 << NF_INET_LOCAL_IN)) &&
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
179 info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) {
ff67e4e4 »
2010-03-19 netfilter: xt extensions: use pr_<level> (2)
180 pr_info("output interface limitation "
181 "not valid in PREROUTING and INPUT\n");
bd414ee6 »
2010-03-23 netfilter: xtables: change matches to return error code
182 return -EINVAL;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
183 }
184
9b4fce7a »
2008-10-08 netfilter: xtables: move extension arguments into compound structure …
185 if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
186 (1 << NF_INET_LOCAL_OUT)) &&
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
187 info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) {
ff67e4e4 »
2010-03-19 netfilter: xt extensions: use pr_<level> (2)
188 pr_info("input interface limitation "
189 "not valid in POSTROUTING and OUTPUT\n");
bd414ee6 »
2010-03-23 netfilter: xtables: change matches to return error code
190 return -EINVAL;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
191 }
192
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
193 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
194 if (par->family == NFPROTO_IPV6) {
195 if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) {
196 pr_err("ipv6 BLACKHOLE matching not supported\n");
197 return -EINVAL;
198 }
199 if ((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) {
200 pr_err("ipv6 PROHIBT (THROW, NAT ..) matching not supported\n");
201 return -EINVAL;
202 }
203 if ((info->source | info->dest) & XT_ADDRTYPE_BROADCAST) {
204 pr_err("ipv6 does not support BROADCAST matching\n");
205 return -EINVAL;
206 }
207 }
208 #endif
bd414ee6 »
2010-03-23 netfilter: xtables: change matches to return error code
209 return 0;
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
210 }
211
212 static struct xt_match addrtype_mt_reg[] __read_mostly = {
213 {
214 .name = "addrtype",
ee999d8b »
2008-10-08 netfilter: x_tables: use NFPROTO_* in extensions
215 .family = NFPROTO_IPV4,
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
216 .match = addrtype_mt_v0,
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
217 .matchsize = sizeof(struct xt_addrtype_info),
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
218 .me = THIS_MODULE
219 },
220 {
221 .name = "addrtype",
2f5dc631 »
2011-03-15 netfilter: xt_addrtype: ipv6 support
222 .family = NFPROTO_UNSPEC,
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
223 .revision = 1,
224 .match = addrtype_mt_v1,
225 .checkentry = addrtype_mt_checkentry_v1,
de81bbea »
2011-03-15 netfilter: ipt_addrtype: rename to xt_addrtype
226 .matchsize = sizeof(struct xt_addrtype_info_v1),
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
227 .me = THIS_MODULE
228 }
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
229 };
230
d3c5ee6d »
2007-12-04 [NETFILTER]: x_tables: consistent and unique symbol names
231 static int __init addrtype_mt_init(void)
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
232 {
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
233 return xt_register_matches(addrtype_mt_reg,
234 ARRAY_SIZE(addrtype_mt_reg));
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
235 }
236
d3c5ee6d »
2007-12-04 [NETFILTER]: x_tables: consistent and unique symbol names
237 static void __exit addrtype_mt_exit(void)
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
238 {
e2cf5ecb »
2007-12-04 [NETFILTER]: ipt_addrtype: limit address type checking to an interface
239 xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg));
1da177e4 »
2005-04-16 Linux-2.6.12-rc2
240 }
241
d3c5ee6d »
2007-12-04 [NETFILTER]: x_tables: consistent and unique symbol names
242 module_init(addrtype_mt_init);
243 module_exit(addrtype_mt_exit);
Something went wrong with that request. Please try again.