diff options
author | Harald Welte <laforge@netfilter.org> | 2006-01-12 16:30:04 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-12 17:06:43 -0500 |
commit | 2e4e6a17af35be359cc8f1c924f8f198fbd478cc (patch) | |
tree | cb4b5438dcf9ff9d57518a26124308bcbfffd214 /net/netfilter/xt_helper.c | |
parent | 880b005f294454d989783d0984dc554dfe3c8214 (diff) |
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/xt_helper.c')
-rw-r--r-- | net/netfilter/xt_helper.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c new file mode 100644 index 00000000000..38b6715e1db --- /dev/null +++ b/net/netfilter/xt_helper.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* iptables module to match on related connections */ | ||
2 | /* | ||
3 | * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se> | ||
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 | * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: | ||
10 | * - Port to newnat infrastructure | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | #include <linux/netfilter.h> | ||
16 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | ||
17 | #include <linux/netfilter_ipv4/ip_conntrack.h> | ||
18 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | ||
19 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | ||
20 | #else | ||
21 | #include <net/netfilter/nf_conntrack.h> | ||
22 | #include <net/netfilter/nf_conntrack_core.h> | ||
23 | #include <net/netfilter/nf_conntrack_helper.h> | ||
24 | #endif | ||
25 | #include <linux/netfilter/x_tables.h> | ||
26 | #include <linux/netfilter/xt_helper.h> | ||
27 | |||
28 | MODULE_LICENSE("GPL"); | ||
29 | MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); | ||
30 | MODULE_DESCRIPTION("iptables helper match module"); | ||
31 | MODULE_ALIAS("ipt_helper"); | ||
32 | MODULE_ALIAS("ip6t_helper"); | ||
33 | |||
34 | #if 0 | ||
35 | #define DEBUGP printk | ||
36 | #else | ||
37 | #define DEBUGP(format, args...) | ||
38 | #endif | ||
39 | |||
40 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | ||
41 | static int | ||
42 | match(const struct sk_buff *skb, | ||
43 | const struct net_device *in, | ||
44 | const struct net_device *out, | ||
45 | const void *matchinfo, | ||
46 | int offset, | ||
47 | unsigned int protoff, | ||
48 | int *hotdrop) | ||
49 | { | ||
50 | const struct xt_helper_info *info = matchinfo; | ||
51 | struct ip_conntrack *ct; | ||
52 | enum ip_conntrack_info ctinfo; | ||
53 | int ret = info->invert; | ||
54 | |||
55 | ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); | ||
56 | if (!ct) { | ||
57 | DEBUGP("xt_helper: Eek! invalid conntrack?\n"); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | if (!ct->master) { | ||
62 | DEBUGP("xt_helper: conntrack %p has no master\n", ct); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | read_lock_bh(&ip_conntrack_lock); | ||
67 | if (!ct->master->helper) { | ||
68 | DEBUGP("xt_helper: master ct %p has no helper\n", | ||
69 | exp->expectant); | ||
70 | goto out_unlock; | ||
71 | } | ||
72 | |||
73 | DEBUGP("master's name = %s , info->name = %s\n", | ||
74 | ct->master->helper->name, info->name); | ||
75 | |||
76 | if (info->name[0] == '\0') | ||
77 | ret ^= 1; | ||
78 | else | ||
79 | ret ^= !strncmp(ct->master->helper->name, info->name, | ||
80 | strlen(ct->master->helper->name)); | ||
81 | out_unlock: | ||
82 | read_unlock_bh(&ip_conntrack_lock); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | #else /* CONFIG_IP_NF_CONNTRACK */ | ||
87 | |||
88 | static int | ||
89 | match(const struct sk_buff *skb, | ||
90 | const struct net_device *in, | ||
91 | const struct net_device *out, | ||
92 | const void *matchinfo, | ||
93 | int offset, | ||
94 | unsigned int protoff, | ||
95 | int *hotdrop) | ||
96 | { | ||
97 | const struct xt_helper_info *info = matchinfo; | ||
98 | struct nf_conn *ct; | ||
99 | enum ip_conntrack_info ctinfo; | ||
100 | int ret = info->invert; | ||
101 | |||
102 | ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); | ||
103 | if (!ct) { | ||
104 | DEBUGP("xt_helper: Eek! invalid conntrack?\n"); | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | if (!ct->master) { | ||
109 | DEBUGP("xt_helper: conntrack %p has no master\n", ct); | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | read_lock_bh(&nf_conntrack_lock); | ||
114 | if (!ct->master->helper) { | ||
115 | DEBUGP("xt_helper: master ct %p has no helper\n", | ||
116 | exp->expectant); | ||
117 | goto out_unlock; | ||
118 | } | ||
119 | |||
120 | DEBUGP("master's name = %s , info->name = %s\n", | ||
121 | ct->master->helper->name, info->name); | ||
122 | |||
123 | if (info->name[0] == '\0') | ||
124 | ret ^= 1; | ||
125 | else | ||
126 | ret ^= !strncmp(ct->master->helper->name, info->name, | ||
127 | strlen(ct->master->helper->name)); | ||
128 | out_unlock: | ||
129 | read_unlock_bh(&nf_conntrack_lock); | ||
130 | return ret; | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | static int check(const char *tablename, | ||
135 | const void *inf, | ||
136 | void *matchinfo, | ||
137 | unsigned int matchsize, | ||
138 | unsigned int hook_mask) | ||
139 | { | ||
140 | struct xt_helper_info *info = matchinfo; | ||
141 | |||
142 | info->name[29] = '\0'; | ||
143 | |||
144 | /* verify size */ | ||
145 | if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info))) | ||
146 | return 0; | ||
147 | |||
148 | return 1; | ||
149 | } | ||
150 | |||
151 | static struct xt_match helper_match = { | ||
152 | .name = "helper", | ||
153 | .match = &match, | ||
154 | .checkentry = &check, | ||
155 | .me = THIS_MODULE, | ||
156 | }; | ||
157 | static struct xt_match helper6_match = { | ||
158 | .name = "helper", | ||
159 | .match = &match, | ||
160 | .checkentry = &check, | ||
161 | .me = THIS_MODULE, | ||
162 | }; | ||
163 | |||
164 | static int __init init(void) | ||
165 | { | ||
166 | int ret; | ||
167 | need_conntrack(); | ||
168 | |||
169 | ret = xt_register_match(AF_INET, &helper_match); | ||
170 | if (ret < 0) | ||
171 | return ret; | ||
172 | |||
173 | ret = xt_register_match(AF_INET6, &helper6_match); | ||
174 | if (ret < 0) | ||
175 | xt_unregister_match(AF_INET, &helper_match); | ||
176 | |||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | static void __exit fini(void) | ||
181 | { | ||
182 | xt_unregister_match(AF_INET, &helper_match); | ||
183 | xt_unregister_match(AF_INET6, &helper6_match); | ||
184 | } | ||
185 | |||
186 | module_init(init); | ||
187 | module_exit(fini); | ||
188 | |||