diff options
author | Patrick McHardy <kaber@trash.net> | 2006-03-20 20:59:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-20 20:59:06 -0500 |
commit | 37f9f7334b86ffc3b8a1921842ae33cb9aa22ee3 (patch) | |
tree | d207ae0a0f2eb37072dd4690de95b6cf170e4e04 /net/netfilter | |
parent | 6ea46c9c12da79ec6eead0cf4b3114143dd30bc1 (diff) |
[NETFILTER]: xt_tables: add centralized error checking
Introduce new functions for common match/target checks (private data
size, valid hooks, valid tables and valid protocols) to get more consistent
error reporting and to avoid each module duplicating them.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/x_tables.c | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index d7817afc6b96..750b92829766 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -52,6 +52,12 @@ enum { | |||
52 | MATCH, | 52 | MATCH, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static const char *xt_prefix[NPROTO] = { | ||
56 | [AF_INET] = "ip", | ||
57 | [AF_INET6] = "ip6", | ||
58 | [NF_ARP] = "arp", | ||
59 | }; | ||
60 | |||
55 | /* Registration hooks for targets. */ | 61 | /* Registration hooks for targets. */ |
56 | int | 62 | int |
57 | xt_register_target(int af, struct xt_target *target) | 63 | xt_register_target(int af, struct xt_target *target) |
@@ -158,18 +164,12 @@ struct xt_target *xt_find_target(int af, const char *name, u8 revision) | |||
158 | } | 164 | } |
159 | EXPORT_SYMBOL(xt_find_target); | 165 | EXPORT_SYMBOL(xt_find_target); |
160 | 166 | ||
161 | static const char *xt_prefix[NPROTO] = { | ||
162 | [AF_INET] = "ipt_%s", | ||
163 | [AF_INET6] = "ip6t_%s", | ||
164 | [NF_ARP] = "arpt_%s", | ||
165 | }; | ||
166 | |||
167 | struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) | 167 | struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) |
168 | { | 168 | { |
169 | struct xt_target *target; | 169 | struct xt_target *target; |
170 | 170 | ||
171 | target = try_then_request_module(xt_find_target(af, name, revision), | 171 | target = try_then_request_module(xt_find_target(af, name, revision), |
172 | xt_prefix[af], name); | 172 | "%st_%s", xt_prefix[af], name); |
173 | if (IS_ERR(target) || !target) | 173 | if (IS_ERR(target) || !target) |
174 | return NULL; | 174 | return NULL; |
175 | return target; | 175 | return target; |
@@ -237,6 +237,64 @@ int xt_find_revision(int af, const char *name, u8 revision, int target, | |||
237 | } | 237 | } |
238 | EXPORT_SYMBOL_GPL(xt_find_revision); | 238 | EXPORT_SYMBOL_GPL(xt_find_revision); |
239 | 239 | ||
240 | int xt_check_match(const struct xt_match *match, unsigned short family, | ||
241 | unsigned int size, const char *table, unsigned int hook_mask, | ||
242 | unsigned short proto, int inv_proto) | ||
243 | { | ||
244 | if (XT_ALIGN(match->matchsize) != size) { | ||
245 | printk("%s_tables: %s match: invalid size %Zu != %u\n", | ||
246 | xt_prefix[family], match->name, | ||
247 | XT_ALIGN(match->matchsize), size); | ||
248 | return -EINVAL; | ||
249 | } | ||
250 | if (match->table && strcmp(match->table, table)) { | ||
251 | printk("%s_tables: %s match: only valid in %s table, not %s\n", | ||
252 | xt_prefix[family], match->name, match->table, table); | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | if (match->hooks && (hook_mask & ~match->hooks) != 0) { | ||
256 | printk("%s_tables: %s match: bad hook_mask %u\n", | ||
257 | xt_prefix[family], match->name, hook_mask); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | if (match->proto && (match->proto != proto || inv_proto)) { | ||
261 | printk("%s_tables: %s match: only valid for protocol %u\n", | ||
262 | xt_prefix[family], match->name, match->proto); | ||
263 | return -EINVAL; | ||
264 | } | ||
265 | return 0; | ||
266 | } | ||
267 | EXPORT_SYMBOL_GPL(xt_check_match); | ||
268 | |||
269 | int xt_check_target(const struct xt_target *target, unsigned short family, | ||
270 | unsigned int size, const char *table, unsigned int hook_mask, | ||
271 | unsigned short proto, int inv_proto) | ||
272 | { | ||
273 | if (XT_ALIGN(target->targetsize) != size) { | ||
274 | printk("%s_tables: %s target: invalid size %Zu != %u\n", | ||
275 | xt_prefix[family], target->name, | ||
276 | XT_ALIGN(target->targetsize), size); | ||
277 | return -EINVAL; | ||
278 | } | ||
279 | if (target->table && strcmp(target->table, table)) { | ||
280 | printk("%s_tables: %s target: only valid in %s table, not %s\n", | ||
281 | xt_prefix[family], target->name, target->table, table); | ||
282 | return -EINVAL; | ||
283 | } | ||
284 | if (target->hooks && (hook_mask & ~target->hooks) != 0) { | ||
285 | printk("%s_tables: %s target: bad hook_mask %u\n", | ||
286 | xt_prefix[family], target->name, hook_mask); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | if (target->proto && (target->proto != proto || inv_proto)) { | ||
290 | printk("%s_tables: %s target: only valid for protocol %u\n", | ||
291 | xt_prefix[family], target->name, target->proto); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | return 0; | ||
295 | } | ||
296 | EXPORT_SYMBOL_GPL(xt_check_target); | ||
297 | |||
240 | struct xt_table_info *xt_alloc_table_info(unsigned int size) | 298 | struct xt_table_info *xt_alloc_table_info(unsigned int size) |
241 | { | 299 | { |
242 | struct xt_table_info *newinfo; | 300 | struct xt_table_info *newinfo; |