diff options
author | Jan Engelhardt <jengelh@computergmbh.de> | 2008-01-31 06:58:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:27:31 -0500 |
commit | b41649989c9640e54e47001994b7ecb927ea1822 (patch) | |
tree | 4c733dd12a1d8f95ac05c431fb64a1eb7cd7e59e | |
parent | 41d0cdedd5d0a067069a1559315aa9bfdf00794a (diff) |
[NETFILTER]: xt_conntrack: add port and direction matching
Extend the xt_conntrack match revision 1 by port matching (all four
{orig,repl}{src,dst}) and by packet direction matching.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter/xt_conntrack.h | 30 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 50 |
2 files changed, 63 insertions, 17 deletions
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h index d2492a3329be..f3fd83e46bab 100644 --- a/include/linux/netfilter/xt_conntrack.h +++ b/include/linux/netfilter/xt_conntrack.h | |||
@@ -6,9 +6,6 @@ | |||
6 | #define _XT_CONNTRACK_H | 6 | #define _XT_CONNTRACK_H |
7 | 7 | ||
8 | #include <linux/netfilter/nf_conntrack_tuple_common.h> | 8 | #include <linux/netfilter/nf_conntrack_tuple_common.h> |
9 | #ifdef __KERNEL__ | ||
10 | # include <linux/in.h> | ||
11 | #endif | ||
12 | 9 | ||
13 | #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) | 10 | #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) |
14 | #define XT_CONNTRACK_STATE_INVALID (1 << 0) | 11 | #define XT_CONNTRACK_STATE_INVALID (1 << 0) |
@@ -18,14 +15,21 @@ | |||
18 | #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) | 15 | #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) |
19 | 16 | ||
20 | /* flags, invflags: */ | 17 | /* flags, invflags: */ |
21 | #define XT_CONNTRACK_STATE 0x01 | 18 | enum { |
22 | #define XT_CONNTRACK_PROTO 0x02 | 19 | XT_CONNTRACK_STATE = 1 << 0, |
23 | #define XT_CONNTRACK_ORIGSRC 0x04 | 20 | XT_CONNTRACK_PROTO = 1 << 1, |
24 | #define XT_CONNTRACK_ORIGDST 0x08 | 21 | XT_CONNTRACK_ORIGSRC = 1 << 2, |
25 | #define XT_CONNTRACK_REPLSRC 0x10 | 22 | XT_CONNTRACK_ORIGDST = 1 << 3, |
26 | #define XT_CONNTRACK_REPLDST 0x20 | 23 | XT_CONNTRACK_REPLSRC = 1 << 4, |
27 | #define XT_CONNTRACK_STATUS 0x40 | 24 | XT_CONNTRACK_REPLDST = 1 << 5, |
28 | #define XT_CONNTRACK_EXPIRES 0x80 | 25 | XT_CONNTRACK_STATUS = 1 << 6, |
26 | XT_CONNTRACK_EXPIRES = 1 << 7, | ||
27 | XT_CONNTRACK_ORIGSRC_PORT = 1 << 8, | ||
28 | XT_CONNTRACK_ORIGDST_PORT = 1 << 9, | ||
29 | XT_CONNTRACK_REPLSRC_PORT = 1 << 10, | ||
30 | XT_CONNTRACK_REPLDST_PORT = 1 << 11, | ||
31 | XT_CONNTRACK_DIRECTION = 1 << 12, | ||
32 | }; | ||
29 | 33 | ||
30 | /* This is exposed to userspace, so remains frozen in time. */ | 34 | /* This is exposed to userspace, so remains frozen in time. */ |
31 | struct ip_conntrack_old_tuple | 35 | struct ip_conntrack_old_tuple |
@@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 { | |||
70 | union nf_inet_addr repldst_addr, repldst_mask; | 74 | union nf_inet_addr repldst_addr, repldst_mask; |
71 | u_int32_t expires_min, expires_max; | 75 | u_int32_t expires_min, expires_max; |
72 | u_int16_t l4proto; | 76 | u_int16_t l4proto; |
77 | __be16 origsrc_port, origdst_port; | ||
78 | __be16 replsrc_port, repldst_port; | ||
79 | u_int16_t match_flags, invert_flags; | ||
73 | u_int8_t state_mask, status_mask; | 80 | u_int8_t state_mask, status_mask; |
74 | u_int8_t match_flags, invert_flags; | ||
75 | }; | 81 | }; |
76 | 82 | ||
77 | #endif /*_XT_CONNTRACK_H*/ | 83 | #endif /*_XT_CONNTRACK_H*/ |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index e92190eafcc5..85330856a29c 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -4,7 +4,6 @@ | |||
4 | * | 4 | * |
5 | * (C) 2001 Marc Boucher (marc@mbsi.ca). | 5 | * (C) 2001 Marc Boucher (marc@mbsi.ca). |
6 | * Copyright © CC Computer Consultants GmbH, 2007 - 2008 | 6 | * Copyright © CC Computer Consultants GmbH, 2007 - 2008 |
7 | * Jan Engelhardt <jengelh@computergmbh.de> | ||
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,6 +19,7 @@ | |||
20 | 19 | ||
21 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
22 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | 21 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); |
22 | MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); | ||
23 | MODULE_DESCRIPTION("Xtables: connection tracking state match"); | 23 | MODULE_DESCRIPTION("Xtables: connection tracking state match"); |
24 | MODULE_ALIAS("ipt_conntrack"); | 24 | MODULE_ALIAS("ipt_conntrack"); |
25 | MODULE_ALIAS("ip6t_conntrack"); | 25 | MODULE_ALIAS("ip6t_conntrack"); |
@@ -166,6 +166,44 @@ conntrack_mt_repldst(const struct nf_conn *ct, | |||
166 | &info->repldst_addr, &info->repldst_mask, family); | 166 | &info->repldst_addr, &info->repldst_mask, family); |
167 | } | 167 | } |
168 | 168 | ||
169 | static inline bool | ||
170 | ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, | ||
171 | const struct nf_conn *ct) | ||
172 | { | ||
173 | const struct nf_conntrack_tuple *tuple; | ||
174 | |||
175 | tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; | ||
176 | if ((info->match_flags & XT_CONNTRACK_PROTO) && | ||
177 | (tuple->dst.protonum == info->l4proto) ^ | ||
178 | !(info->invert_flags & XT_CONNTRACK_PROTO)) | ||
179 | return false; | ||
180 | |||
181 | /* Shortcut to match all recognized protocols by using ->src.all. */ | ||
182 | if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) && | ||
183 | (tuple->src.u.all == info->origsrc_port) ^ | ||
184 | !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT)) | ||
185 | return false; | ||
186 | |||
187 | if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) && | ||
188 | (tuple->dst.u.all == info->origdst_port) ^ | ||
189 | !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT)) | ||
190 | return false; | ||
191 | |||
192 | tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; | ||
193 | |||
194 | if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) && | ||
195 | (tuple->src.u.all == info->replsrc_port) ^ | ||
196 | !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT)) | ||
197 | return false; | ||
198 | |||
199 | if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) && | ||
200 | (tuple->dst.u.all == info->repldst_port) ^ | ||
201 | !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT)) | ||
202 | return false; | ||
203 | |||
204 | return true; | ||
205 | } | ||
206 | |||
169 | static bool | 207 | static bool |
170 | conntrack_mt(const struct sk_buff *skb, const struct net_device *in, | 208 | conntrack_mt(const struct sk_buff *skb, const struct net_device *in, |
171 | const struct net_device *out, const struct xt_match *match, | 209 | const struct net_device *out, const struct xt_match *match, |
@@ -200,10 +238,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in, | |||
200 | 238 | ||
201 | if (ct == NULL) | 239 | if (ct == NULL) |
202 | return info->match_flags & XT_CONNTRACK_STATE; | 240 | return info->match_flags & XT_CONNTRACK_STATE; |
203 | 241 | if ((info->match_flags & XT_CONNTRACK_DIRECTION) && | |
204 | if ((info->match_flags & XT_CONNTRACK_PROTO) && | 242 | (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^ |
205 | ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == | 243 | !!(info->invert_flags & XT_CONNTRACK_DIRECTION)) |
206 | info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO))) | ||
207 | return false; | 244 | return false; |
208 | 245 | ||
209 | if (info->match_flags & XT_CONNTRACK_ORIGSRC) | 246 | if (info->match_flags & XT_CONNTRACK_ORIGSRC) |
@@ -226,6 +263,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in, | |||
226 | !(info->invert_flags & XT_CONNTRACK_REPLDST)) | 263 | !(info->invert_flags & XT_CONNTRACK_REPLDST)) |
227 | return false; | 264 | return false; |
228 | 265 | ||
266 | if (!ct_proto_port_check(info, ct)) | ||
267 | return false; | ||
268 | |||
229 | if ((info->match_flags & XT_CONNTRACK_STATUS) && | 269 | if ((info->match_flags & XT_CONNTRACK_STATUS) && |
230 | (!!(info->status_mask & ct->status) ^ | 270 | (!!(info->status_mask & ct->status) ^ |
231 | !(info->invert_flags & XT_CONNTRACK_STATUS))) | 271 | !(info->invert_flags & XT_CONNTRACK_STATUS))) |