diff options
author | Florian Westphal <fwestphal@astaro.com> | 2011-03-15 15:16:20 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-03-15 15:16:20 -0400 |
commit | de81bbea17650769882bc625d6b5df11ee7c4b24 (patch) | |
tree | 2e1250b7309977fc48b4f5b88f83959795f04591 /net/netfilter/xt_addrtype.c | |
parent | 6a8ab060779779de8aea92ce3337ca348f973f54 (diff) |
netfilter: ipt_addrtype: rename to xt_addrtype
Followup patch will add ipv6 support.
ipt_addrtype.h is retained for compatibility reasons, but no longer used
by the kernel.
Signed-off-by: Florian Westphal <fwestphal@astaro.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter/xt_addrtype.c')
-rw-r--r-- | net/netfilter/xt_addrtype.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c new file mode 100644 index 00000000000..e89c0b84583 --- /dev/null +++ b/net/netfilter/xt_addrtype.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * iptables module to match inet_addr_type() of an ip. | ||
3 | * | ||
4 | * Copyright (c) 2004 Patrick McHardy <kaber@trash.net> | ||
5 | * (C) 2007 Laszlo Attila Toth <panther@balabit.hu> | ||
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 | */ | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
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 | |||
19 | #include <linux/netfilter/xt_addrtype.h> | ||
20 | #include <linux/netfilter/x_tables.h> | ||
21 | |||
22 | MODULE_LICENSE("GPL"); | ||
23 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
24 | MODULE_DESCRIPTION("Xtables: address type match"); | ||
25 | MODULE_ALIAS("ipt_addrtype"); | ||
26 | |||
27 | static inline bool match_type(struct net *net, const struct net_device *dev, | ||
28 | __be32 addr, u_int16_t mask) | ||
29 | { | ||
30 | return !!(mask & (1 << inet_dev_addr_type(net, dev, addr))); | ||
31 | } | ||
32 | |||
33 | static bool | ||
34 | addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) | ||
35 | { | ||
36 | struct net *net = dev_net(par->in ? par->in : par->out); | ||
37 | const struct xt_addrtype_info *info = par->matchinfo; | ||
38 | const struct iphdr *iph = ip_hdr(skb); | ||
39 | bool ret = true; | ||
40 | |||
41 | if (info->source) | ||
42 | ret &= match_type(net, NULL, iph->saddr, info->source) ^ | ||
43 | info->invert_source; | ||
44 | if (info->dest) | ||
45 | ret &= match_type(net, NULL, iph->daddr, info->dest) ^ | ||
46 | info->invert_dest; | ||
47 | |||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | static bool | ||
52 | addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) | ||
53 | { | ||
54 | struct net *net = dev_net(par->in ? par->in : par->out); | ||
55 | const struct xt_addrtype_info_v1 *info = par->matchinfo; | ||
56 | const struct iphdr *iph = ip_hdr(skb); | ||
57 | const struct net_device *dev = NULL; | ||
58 | bool ret = true; | ||
59 | |||
60 | if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) | ||
61 | dev = par->in; | ||
62 | else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) | ||
63 | dev = par->out; | ||
64 | |||
65 | if (info->source) | ||
66 | ret &= match_type(net, dev, iph->saddr, info->source) ^ | ||
67 | (info->flags & XT_ADDRTYPE_INVERT_SOURCE); | ||
68 | if (ret && info->dest) | ||
69 | ret &= match_type(net, dev, iph->daddr, info->dest) ^ | ||
70 | !!(info->flags & XT_ADDRTYPE_INVERT_DEST); | ||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) | ||
75 | { | ||
76 | struct xt_addrtype_info_v1 *info = par->matchinfo; | ||
77 | |||
78 | if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN && | ||
79 | info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { | ||
80 | pr_info("both incoming and outgoing " | ||
81 | "interface limitation cannot be selected\n"); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | | ||
86 | (1 << NF_INET_LOCAL_IN)) && | ||
87 | info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { | ||
88 | pr_info("output interface limitation " | ||
89 | "not valid in PREROUTING and INPUT\n"); | ||
90 | return -EINVAL; | ||
91 | } | ||
92 | |||
93 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | | ||
94 | (1 << NF_INET_LOCAL_OUT)) && | ||
95 | info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) { | ||
96 | pr_info("input interface limitation " | ||
97 | "not valid in POSTROUTING and OUTPUT\n"); | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static struct xt_match addrtype_mt_reg[] __read_mostly = { | ||
105 | { | ||
106 | .name = "addrtype", | ||
107 | .family = NFPROTO_IPV4, | ||
108 | .match = addrtype_mt_v0, | ||
109 | .matchsize = sizeof(struct xt_addrtype_info), | ||
110 | .me = THIS_MODULE | ||
111 | }, | ||
112 | { | ||
113 | .name = "addrtype", | ||
114 | .family = NFPROTO_IPV4, | ||
115 | .revision = 1, | ||
116 | .match = addrtype_mt_v1, | ||
117 | .checkentry = addrtype_mt_checkentry_v1, | ||
118 | .matchsize = sizeof(struct xt_addrtype_info_v1), | ||
119 | .me = THIS_MODULE | ||
120 | } | ||
121 | }; | ||
122 | |||
123 | static int __init addrtype_mt_init(void) | ||
124 | { | ||
125 | return xt_register_matches(addrtype_mt_reg, | ||
126 | ARRAY_SIZE(addrtype_mt_reg)); | ||
127 | } | ||
128 | |||
129 | static void __exit addrtype_mt_exit(void) | ||
130 | { | ||
131 | xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); | ||
132 | } | ||
133 | |||
134 | module_init(addrtype_mt_init); | ||
135 | module_exit(addrtype_mt_exit); | ||