Commit b017900a authored by Patrick McHardy's avatar Patrick McHardy Committed by Pablo Neira Ayuso

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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 5df15196
...@@ -58,4 +58,19 @@ struct xt_conntrack_mtinfo2 { ...@@ -58,4 +58,19 @@ struct xt_conntrack_mtinfo2 {
__u16 state_mask, status_mask; __u16 state_mask, status_mask;
}; };
struct xt_conntrack_mtinfo3 {
union nf_inet_addr origsrc_addr, origsrc_mask;
union nf_inet_addr origdst_addr, origdst_mask;
union nf_inet_addr replsrc_addr, replsrc_mask;
union nf_inet_addr repldst_addr, repldst_mask;
__u32 expires_min, expires_max;
__u16 l4proto;
__u16 origsrc_port, origdst_port;
__u16 replsrc_port, repldst_port;
__u16 match_flags, invert_flags;
__u16 state_mask, status_mask;
__u16 origsrc_port_high, origdst_port_high;
__u16 replsrc_port_high, repldst_port_high;
};
#endif /*_XT_CONNTRACK_H*/ #endif /*_XT_CONNTRACK_H*/
...@@ -112,6 +112,54 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info, ...@@ -112,6 +112,54 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
return true; return true;
} }
static inline bool
port_match(u16 min, u16 max, u16 port, bool invert)
{
return (port >= min && port <= max) ^ invert;
}
static inline bool
ct_proto_port_check_v3(const struct xt_conntrack_mtinfo3 *info,
const struct nf_conn *ct)
{
const struct nf_conntrack_tuple *tuple;
tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
if ((info->match_flags & XT_CONNTRACK_PROTO) &&
(nf_ct_protonum(ct) == info->l4proto) ^
!(info->invert_flags & XT_CONNTRACK_PROTO))
return false;
/* Shortcut to match all recognized protocols by using ->src.all. */
if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
!port_match(info->origsrc_port, info->origsrc_port_high,
ntohs(tuple->src.u.all),
info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
return false;
if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
!port_match(info->origdst_port, info->origdst_port_high,
ntohs(tuple->dst.u.all),
info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
return false;
tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
!port_match(info->replsrc_port, info->replsrc_port_high,
ntohs(tuple->src.u.all),
info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
return false;
if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
!port_match(info->repldst_port, info->repldst_port_high,
ntohs(tuple->dst.u.all),
info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
return false;
return true;
}
static bool static bool
conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
u16 state_mask, u16 status_mask) u16 state_mask, u16 status_mask)
...@@ -170,8 +218,13 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, ...@@ -170,8 +218,13 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
!(info->invert_flags & XT_CONNTRACK_REPLDST)) !(info->invert_flags & XT_CONNTRACK_REPLDST))
return false; return false;
if (!ct_proto_port_check(info, ct)) if (par->match->revision != 3) {
return false; if (!ct_proto_port_check(info, ct))
return false;
} else {
if (!ct_proto_port_check_v3(par->matchinfo, ct))
return false;
}
if ((info->match_flags & XT_CONNTRACK_STATUS) && if ((info->match_flags & XT_CONNTRACK_STATUS) &&
(!!(status_mask & ct->status) ^ (!!(status_mask & ct->status) ^
...@@ -207,6 +260,14 @@ conntrack_mt_v2(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -207,6 +260,14 @@ conntrack_mt_v2(const struct sk_buff *skb, struct xt_action_param *par)
return conntrack_mt(skb, par, info->state_mask, info->status_mask); return conntrack_mt(skb, par, info->state_mask, info->status_mask);
} }
static bool
conntrack_mt_v3(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_conntrack_mtinfo3 *info = par->matchinfo;
return conntrack_mt(skb, par, info->state_mask, info->status_mask);
}
static int conntrack_mt_check(const struct xt_mtchk_param *par) static int conntrack_mt_check(const struct xt_mtchk_param *par)
{ {
int ret; int ret;
...@@ -244,6 +305,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { ...@@ -244,6 +305,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
.destroy = conntrack_mt_destroy, .destroy = conntrack_mt_destroy,
.me = THIS_MODULE, .me = THIS_MODULE,
}, },
{
.name = "conntrack",
.revision = 3,
.family = NFPROTO_UNSPEC,
.matchsize = sizeof(struct xt_conntrack_mtinfo3),
.match = conntrack_mt_v3,
.checkentry = conntrack_mt_check,
.destroy = conntrack_mt_destroy,
.me = THIS_MODULE,
},
}; };
static int __init conntrack_mt_init(void) static int __init conntrack_mt_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment