aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@eurodev.net>2005-08-22 02:30:34 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 19:04:07 -0400
commit7567662ba896ee0c33d6215f32e2011488a6d1bf (patch)
treed259de5c48a54b7017ee21b5a141c223f8b082e6
parent24117727b753426d85ba09671c24854834f81b2c (diff)
[NETFILTER]: Add string match
Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter_ipv4/ipt_string.h18
-rw-r--r--net/ipv4/netfilter/Kconfig12
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ipt_string.c91
4 files changed, 122 insertions, 0 deletions
diff --git a/include/linux/netfilter_ipv4/ipt_string.h b/include/linux/netfilter_ipv4/ipt_string.h
new file mode 100644
index 000000000000..a265f6e44eab
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_string.h
@@ -0,0 +1,18 @@
1#ifndef _IPT_STRING_H
2#define _IPT_STRING_H
3
4#define IPT_STRING_MAX_PATTERN_SIZE 128
5#define IPT_STRING_MAX_ALGO_NAME_SIZE 16
6
7struct ipt_string_info
8{
9 u_int16_t from_offset;
10 u_int16_t to_offset;
11 char algo[IPT_STRING_MAX_ALGO_NAME_SIZE];
12 char pattern[IPT_STRING_MAX_PATTERN_SIZE];
13 u_int8_t patlen;
14 u_int8_t invert;
15 struct ts_config __attribute__((aligned(8))) *config;
16};
17
18#endif /*_IPT_STRING_H*/
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
413config 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
414config IP_NF_FILTER 426config 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
65obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 65obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
66obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o 66obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
67obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o 67obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
68obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
68 69
69# targets 70# targets
70obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 71obj-$(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
18MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>");
19MODULE_DESCRIPTION("IP tables string match module");
20MODULE_LICENSE("GPL");
21
22static 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
41static 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
67static void destroy(void *matchinfo, unsigned int matchsize)
68{
69 textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
70}
71
72static struct ipt_match string_match = {
73 .name = "string",
74 .match = match,
75 .checkentry = checkentry,
76 .destroy = destroy,
77 .me = THIS_MODULE
78};
79
80static int __init init(void)
81{
82 return ipt_register_match(&string_match);
83}
84
85static void __exit fini(void)
86{
87 ipt_unregister_match(&string_match);
88}
89
90module_init(init);
91module_exit(fini);