diff options
author | Patrick McHardy <kaber@trash.net> | 2010-12-15 03:46:26 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2011-01-13 06:05:12 -0500 |
commit | b017900aac4a158b9bf7ffdcb8a369a91115b3e4 (patch) | |
tree | 8516ac2dae8db038e7e45d76a1c8ecfb75faf7a9 | |
parent | 5df15196a2bbf16ca4c6a797ec00ff36d0d5c179 (diff) |
netfilter: xt_conntrack: support matching on port ranges
Add a new revision 3 that contains port ranges for all of origsrc,
origdst, replsrc and repldst. The high ports are appended to the
original v2 data structure to allow sharing most of the code with
v1 and v2. Use of the revision specific port matching function is
made dependant on par->match->revision.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/linux/netfilter/xt_conntrack.h | 15 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 75 |
2 files changed, 88 insertions, 2 deletions
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h index 54f47a2f6152..74b904d8f99c 100644 --- a/include/linux/netfilter/xt_conntrack.h +++ b/include/linux/netfilter/xt_conntrack.h | |||
@@ -58,4 +58,19 @@ struct xt_conntrack_mtinfo2 { | |||
58 | __u16 state_mask, status_mask; | 58 | __u16 state_mask, status_mask; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct xt_conntrack_mtinfo3 { | ||
62 | union nf_inet_addr origsrc_addr, origsrc_mask; | ||
63 | union nf_inet_addr origdst_addr, origdst_mask; | ||
64 | union nf_inet_addr replsrc_addr, replsrc_mask; | ||
65 | union nf_inet_addr repldst_addr, repldst_mask; | ||
66 | __u32 expires_min, expires_max; | ||
67 | __u16 l4proto; | ||
68 | __u16 origsrc_port, origdst_port; | ||
69 | __u16 replsrc_port, repldst_port; | ||
70 | __u16 match_flags, invert_flags; | ||
71 | __u16 state_mask, status_mask; | ||
72 | __u16 origsrc_port_high, origdst_port_high; | ||
73 | __u16 replsrc_port_high, repldst_port_high; | ||
74 | }; | ||
75 | |||
61 | #endif /*_XT_CONNTRACK_H*/ | 76 | #endif /*_XT_CONNTRACK_H*/ |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index e536710ad916..4ef1b63ad73f 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -112,6 +112,54 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info, | |||
112 | return true; | 112 | return true; |
113 | } | 113 | } |
114 | 114 | ||
115 | static inline bool | ||
116 | port_match(u16 min, u16 max, u16 port, bool invert) | ||
117 | { | ||
118 | return (port >= min && port <= max) ^ invert; | ||
119 | } | ||
120 | |||
121 | static inline bool | ||
122 | ct_proto_port_check_v3(const struct xt_conntrack_mtinfo3 *info, | ||
123 | const struct nf_conn *ct) | ||
124 | { | ||
125 | const struct nf_conntrack_tuple *tuple; | ||
126 | |||
127 | tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; | ||
128 | if ((info->match_flags & XT_CONNTRACK_PROTO) && | ||
129 | (nf_ct_protonum(ct) == info->l4proto) ^ | ||
130 | !(info->invert_flags & XT_CONNTRACK_PROTO)) | ||
131 | return false; | ||
132 | |||
133 | /* Shortcut to match all recognized protocols by using ->src.all. */ | ||
134 | if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) && | ||
135 | !port_match(info->origsrc_port, info->origsrc_port_high, | ||
136 | ntohs(tuple->src.u.all), | ||
137 | info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT)) | ||
138 | return false; | ||
139 | |||
140 | if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) && | ||
141 | !port_match(info->origdst_port, info->origdst_port_high, | ||
142 | ntohs(tuple->dst.u.all), | ||
143 | info->invert_flags & XT_CONNTRACK_ORIGDST_PORT)) | ||
144 | return false; | ||
145 | |||
146 | tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; | ||
147 | |||
148 | if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) && | ||
149 | !port_match(info->replsrc_port, info->replsrc_port_high, | ||
150 | ntohs(tuple->src.u.all), | ||
151 | info->invert_flags & XT_CONNTRACK_REPLSRC_PORT)) | ||
152 | return false; | ||
153 | |||
154 | if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) && | ||
155 | !port_match(info->repldst_port, info->repldst_port_high, | ||
156 | ntohs(tuple->dst.u.all), | ||
157 | info->invert_flags & XT_CONNTRACK_REPLDST_PORT)) | ||
158 | return false; | ||
159 | |||
160 | return true; | ||
161 | } | ||
162 | |||
115 | static bool | 163 | static bool |
116 | conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, | 164 | conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, |
117 | u16 state_mask, u16 status_mask) | 165 | u16 state_mask, u16 status_mask) |
@@ -170,8 +218,13 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, | |||
170 | !(info->invert_flags & XT_CONNTRACK_REPLDST)) | 218 | !(info->invert_flags & XT_CONNTRACK_REPLDST)) |
171 | return false; | 219 | return false; |
172 | 220 | ||
173 | if (!ct_proto_port_check(info, ct)) | 221 | if (par->match->revision != 3) { |
174 | return false; | 222 | if (!ct_proto_port_check(info, ct)) |
223 | return false; | ||
224 | } else { | ||
225 | if (!ct_proto_port_check_v3(par->matchinfo, ct)) | ||
226 | return false; | ||
227 | } | ||
175 | 228 | ||
176 | if ((info->match_flags & XT_CONNTRACK_STATUS) && | 229 | if ((info->match_flags & XT_CONNTRACK_STATUS) && |
177 | (!!(status_mask & ct->status) ^ | 230 | (!!(status_mask & ct->status) ^ |
@@ -207,6 +260,14 @@ conntrack_mt_v2(const struct sk_buff *skb, struct xt_action_param *par) | |||
207 | return conntrack_mt(skb, par, info->state_mask, info->status_mask); | 260 | return conntrack_mt(skb, par, info->state_mask, info->status_mask); |
208 | } | 261 | } |
209 | 262 | ||
263 | static bool | ||
264 | conntrack_mt_v3(const struct sk_buff *skb, struct xt_action_param *par) | ||
265 | { | ||
266 | const struct xt_conntrack_mtinfo3 *info = par->matchinfo; | ||
267 | |||
268 | return conntrack_mt(skb, par, info->state_mask, info->status_mask); | ||
269 | } | ||
270 | |||
210 | static int conntrack_mt_check(const struct xt_mtchk_param *par) | 271 | static int conntrack_mt_check(const struct xt_mtchk_param *par) |
211 | { | 272 | { |
212 | int ret; | 273 | int ret; |
@@ -244,6 +305,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { | |||
244 | .destroy = conntrack_mt_destroy, | 305 | .destroy = conntrack_mt_destroy, |
245 | .me = THIS_MODULE, | 306 | .me = THIS_MODULE, |
246 | }, | 307 | }, |
308 | { | ||
309 | .name = "conntrack", | ||
310 | .revision = 3, | ||
311 | .family = NFPROTO_UNSPEC, | ||
312 | .matchsize = sizeof(struct xt_conntrack_mtinfo3), | ||
313 | .match = conntrack_mt_v3, | ||
314 | .checkentry = conntrack_mt_check, | ||
315 | .destroy = conntrack_mt_destroy, | ||
316 | .me = THIS_MODULE, | ||
317 | }, | ||
247 | }; | 318 | }; |
248 | 319 | ||
249 | static int __init conntrack_mt_init(void) | 320 | static int __init conntrack_mt_init(void) |