diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 12 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_string.c | 91 |
3 files changed, 104 insertions, 0 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 3f7e6e49cbdd..f2bea6ecb226 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -410,6 +410,18 @@ config IP_NF_MATCH_HASHLIMIT | |||
410 | destination IP' or `500pps from any given source IP' with a single | 410 | destination IP' or `500pps from any given source IP' with a single |
411 | IPtables rule. | 411 | IPtables rule. |
412 | 412 | ||
413 | config IP_NF_MATCH_STRING | ||
414 | tristate 'string match support' | ||
415 | depends on IP_NF_IPTABLES | ||
416 | select TEXTSEARCH | ||
417 | select TEXTSEARCH_KMP | ||
418 | select TEXTSEARCH_FSM | ||
419 | help | ||
420 | This option adds a `string' match, which allows you to look for | ||
421 | pattern matchings in packets. | ||
422 | |||
423 | To compile it as a module, choose M here. If unsure, say N. | ||
424 | |||
413 | # `filter', generic and specific targets | 425 | # `filter', generic and specific targets |
414 | config IP_NF_FILTER | 426 | config IP_NF_FILTER |
415 | tristate "Packet filtering" | 427 | tristate "Packet filtering" |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 7c8ae858aa43..89cae69ee208 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -65,6 +65,7 @@ obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o | |||
65 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 65 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
66 | obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o | 66 | obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o |
67 | obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o | 67 | obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o |
68 | obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o | ||
68 | 69 | ||
69 | # targets | 70 | # targets |
70 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o | 71 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
diff --git a/net/ipv4/netfilter/ipt_string.c b/net/ipv4/netfilter/ipt_string.c new file mode 100644 index 000000000000..b5def204d798 --- /dev/null +++ b/net/ipv4/netfilter/ipt_string.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* String matching match for iptables | ||
2 | * | ||
3 | * (C) 2005 Pablo Neira Ayuso <pablo@eurodev.net> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
15 | #include <linux/netfilter_ipv4/ipt_string.h> | ||
16 | #include <linux/textsearch.h> | ||
17 | |||
18 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); | ||
19 | MODULE_DESCRIPTION("IP tables string match module"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static int match(const struct sk_buff *skb, | ||
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | const void *matchinfo, | ||
26 | int offset, | ||
27 | int *hotdrop) | ||
28 | { | ||
29 | struct ts_state state; | ||
30 | struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo; | ||
31 | |||
32 | memset(&state, 0, sizeof(struct ts_state)); | ||
33 | |||
34 | return (skb_find_text((struct sk_buff *)skb, conf->from_offset, | ||
35 | conf->to_offset, conf->config, &state) | ||
36 | != UINT_MAX) && !conf->invert; | ||
37 | } | ||
38 | |||
39 | #define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m) | ||
40 | |||
41 | static int checkentry(const char *tablename, | ||
42 | const struct ipt_ip *ip, | ||
43 | void *matchinfo, | ||
44 | unsigned int matchsize, | ||
45 | unsigned int hook_mask) | ||
46 | { | ||
47 | struct ipt_string_info *conf = matchinfo; | ||
48 | struct ts_config *ts_conf; | ||
49 | |||
50 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) | ||
51 | return 0; | ||
52 | |||
53 | /* Damn, can't handle this case properly with iptables... */ | ||
54 | if (conf->from_offset > conf->to_offset) | ||
55 | return 0; | ||
56 | |||
57 | ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, | ||
58 | GFP_KERNEL, TS_AUTOLOAD); | ||
59 | if (IS_ERR(ts_conf)) | ||
60 | return 0; | ||
61 | |||
62 | conf->config = ts_conf; | ||
63 | |||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | static void destroy(void *matchinfo, unsigned int matchsize) | ||
68 | { | ||
69 | textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); | ||
70 | } | ||
71 | |||
72 | static struct ipt_match string_match = { | ||
73 | .name = "string", | ||
74 | .match = match, | ||
75 | .checkentry = checkentry, | ||
76 | .destroy = destroy, | ||
77 | .me = THIS_MODULE | ||
78 | }; | ||
79 | |||
80 | static int __init init(void) | ||
81 | { | ||
82 | return ipt_register_match(&string_match); | ||
83 | } | ||
84 | |||
85 | static void __exit fini(void) | ||
86 | { | ||
87 | ipt_unregister_match(&string_match); | ||
88 | } | ||
89 | |||
90 | module_init(init); | ||
91 | module_exit(fini); | ||