* [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-15 14:13 ` Patrick McHardy
@ 2008-01-16 18:02 ` Jan Engelhardt
2008-01-17 13:52 ` Pablo Neira Ayuso
0 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-16 18:02 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Developer Mailing List
On Jan 15 2008 15:13, Patrick McHardy wrote:
> Jan Engelhardt wrote:
>> On Jan 15 2008 07:48, Patrick McHardy wrote:
>> > This reminded me - while we're introducing new revisions, there
>> > are two things that have always been missing from xt_conntrack
>> > and I know of multiple patches adding this. One is port matching
>> > for both directions, the other is matching on the direction
>> > itself. Would you be interested in adding this? Otherwise I'm
>> > going to take care of it myself.
>> >
>>
>> I will take care of that, yes.
>
> Thanks.
>
This patch also removes the ugly #include <linux/in.h>, which is already
found in netfilter.h (which is a better place).
===
commit 17934f6d825d2a6785cd8d7811997a8620cfd528
Author: Jan Engelhardt <jengelh@computergmbh.de>
Date: Wed Jan 16 18:58:49 2008 +0100
[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>
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index d2492a3..9e35ccd 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -6,9 +6,6 @@
#define _XT_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_tuple_common.h>
-#ifdef __KERNEL__
-# include <linux/in.h>
-#endif
#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define XT_CONNTRACK_STATE_INVALID (1 << 0)
@@ -18,14 +15,21 @@
#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
-#define XT_CONNTRACK_STATE 0x01
-#define XT_CONNTRACK_PROTO 0x02
-#define XT_CONNTRACK_ORIGSRC 0x04
-#define XT_CONNTRACK_ORIGDST 0x08
-#define XT_CONNTRACK_REPLSRC 0x10
-#define XT_CONNTRACK_REPLDST 0x20
-#define XT_CONNTRACK_STATUS 0x40
-#define XT_CONNTRACK_EXPIRES 0x80
+enum {
+ XT_CONNTRACK_STATE = 1 << 0,
+ XT_CONNTRACK_PROTO = 1 << 1,
+ XT_CONNTRACK_ORIGSRC = 1 << 2,
+ XT_CONNTRACK_ORIGDST = 1 << 3,
+ XT_CONNTRACK_REPLSRC = 1 << 4,
+ XT_CONNTRACK_REPLDST = 1 << 5,
+ XT_CONNTRACK_STATUS = 1 << 6,
+ XT_CONNTRACK_EXPIRES = 1 << 7,
+ XT_CONNTRACK_ORIGSRC_PORT = 1 << 8,
+ XT_CONNTRACK_ORIGDST_PORT = 1 << 9,
+ XT_CONNTRACK_REPLSRC_PORT = 1 << 10,
+ XT_CONNTRACK_REPLDST_PORT = 1 << 11,
+ XT_CONNTRACK_DIRECTION = 1 << 12,
+};
/* This is exposed to userspace, so remains frozen in time. */
struct ip_conntrack_old_tuple
@@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 {
union nf_inet_addr repldst_addr, repldst_mask;
u_int32_t expires_min, expires_max;
u_int16_t l4proto;
+ u_int16_t origsrc_port, origdst_port;
+ u_int16_t replsrc_port, repldst_port;
+ u_int16_t match_flags, invert_flags;
u_int8_t state_mask, status_mask;
- u_int8_t match_flags, invert_flags;
};
#endif /*_XT_CONNTRACK_H*/
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index e92190e..851cba6 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -166,6 +166,67 @@ conntrack_mt_repldst(const struct nf_conn *ct,
&info->repldst_addr, &info->repldst_mask, family);
}
+static inline bool
+ct_proto_port_check(const struct xt_conntrack_mtinfo1 *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)
+ if ((tuple->dst.protonum == info->l4proto) ^
+ !(info->invert_flags & XT_CONNTRACK_PROTO))
+ return false;
+
+ switch (tuple->dst.protonum) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_SCTP:
+ /*
+ * shortcut by using .u.all rather than
+ * .u.tcp.port + .u.udp.port!
+ */
+ if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
+ (tuple->src.u.all != info->origsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
+ return false;
+ if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
+ (tuple->dst.u.all != info->origdst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
+ return false;
+ break;
+ default:
+ if ((info->match_flags ^ info->invert_flags) &
+ (XT_CONNTRACK_ORIGSRC_PORT | XT_CONNTRACK_ORIGDST_PORT))
+ return false;
+ break;
+ }
+
+ tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ switch (tuple->dst.protonum) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_SCTP:
+ /* shortcut by using ->src.all */
+ if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
+ (tuple->src.u.all != info->replsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
+ return false;
+ if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
+ (tuple->dst.u.all != info->repldst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
+ return false;
+ break;
+ default:
+ if ((info->match_flags ^ info->invert_flags) &
+ (XT_CONNTRACK_REPLSRC_PORT | XT_CONNTRACK_REPLDST_PORT))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
static bool
conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
@@ -200,10 +261,11 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
if (ct == NULL)
return info->match_flags & XT_CONNTRACK_STATE;
-
- if ((info->match_flags & XT_CONNTRACK_PROTO) &&
- ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
- info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+ if (!ct_proto_port_check(info, ct))
+ return false;
+ if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
+ (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
+ !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
return false;
if (info->match_flags & XT_CONNTRACK_ORIGSRC)
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-16 18:02 ` [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt
@ 2008-01-17 13:52 ` Pablo Neira Ayuso
2008-01-17 15:00 ` Jan Engelhardt
0 siblings, 1 reply; 17+ messages in thread
From: Pablo Neira Ayuso @ 2008-01-17 13:52 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List
Jan Engelhardt wrote:
> + switch (tuple->dst.protonum) {
> + case IPPROTO_TCP:
> + case IPPROTO_UDP:
> + case IPPROTO_SCTP:
Minor nitpick. Add IPPROTO_UDPLITE.
--
"Los honestos son inadaptados sociales" -- Les Luthiers
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-17 13:52 ` Pablo Neira Ayuso
@ 2008-01-17 15:00 ` Jan Engelhardt
2008-01-20 13:00 ` Patrick McHardy
0 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-17 15:00 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Patrick McHardy, Netfilter Developer Mailing List
On Jan 17 2008 14:52, Pablo Neira Ayuso wrote:
> Jan Engelhardt wrote:
>> + switch (tuple->dst.protonum) {
>> + case IPPROTO_TCP:
>> + case IPPROTO_UDP:
>> + case IPPROTO_SCTP:
>
> Minor nitpick. Add IPPROTO_UDPLITE.
Yeah that can be easily added. I wonder why Netfilter does not support
DCCP conntracking? (At least there is no dccp field in struct nf_conn
and the tuple things.)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-17 15:00 ` Jan Engelhardt
@ 2008-01-20 13:00 ` Patrick McHardy
2008-01-20 13:12 ` Jan Engelhardt
2008-01-21 1:14 ` Pablo Neira Ayuso
0 siblings, 2 replies; 17+ messages in thread
From: Patrick McHardy @ 2008-01-20 13:00 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List
Jan Engelhardt wrote:
> On Jan 17 2008 14:52, Pablo Neira Ayuso wrote:
>> Jan Engelhardt wrote:
>>> + switch (tuple->dst.protonum) {
>>> + case IPPROTO_TCP:
>>> + case IPPROTO_UDP:
>>> + case IPPROTO_SCTP:
>> Minor nitpick. Add IPPROTO_UDPLITE.
>
> Yeah that can be easily added.
Another nitpick: we support masks for the addresses, ranges of ports
would be nice to have here as well. I also don't think the protocol
check is very useful in this case since all conntrack entries contain
port numbers or something similar.
> I wonder why Netfilter does not support
> DCCP conntracking? (At least there is no dccp field in struct nf_conn
> and the tuple things.)
I have an old patch for this, but it was missing proper protocol state
tracking. Perhaps I should merge it without it for now since thats
still better than no support at all.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-20 13:00 ` Patrick McHardy
@ 2008-01-20 13:12 ` Jan Engelhardt
2008-01-20 13:15 ` Patrick McHardy
2008-01-21 1:14 ` Pablo Neira Ayuso
1 sibling, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-20 13:12 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List
On Jan 20 2008 14:00, Patrick McHardy wrote:
>
> Another nitpick: we support masks for the addresses, ranges of ports
> would be nice to have here as well.
Well well why don't we just add address ranges too then :p
Do we need it so badly?
> I also don't think the protocol
> check is very useful in this case since all conntrack entries contain
> port numbers or something similar.
Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is?
The protocol check is important though, because IPPROTO_GRE is
_not_ included, since, it's not something that has a port.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-20 13:12 ` Jan Engelhardt
@ 2008-01-20 13:15 ` Patrick McHardy
2008-01-20 16:48 ` Jan Engelhardt
0 siblings, 1 reply; 17+ messages in thread
From: Patrick McHardy @ 2008-01-20 13:15 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List
Jan Engelhardt wrote:
> On Jan 20 2008 14:00, Patrick McHardy wrote:
>> Another nitpick: we support masks for the addresses, ranges of ports
>> would be nice to have here as well.
>
> Well well why don't we just add address ranges too then :p
> Do we need it so badly?
We already have masks, which is probably good enough.
>
>> I also don't think the protocol
>> check is very useful in this case since all conntrack entries contain
>> port numbers or something similar.
>
> Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is?
Sure, by proto_generic, which uses 0 for the port numbers.
> The protocol check is important though, because IPPROTO_GRE is
> _not_ included, since, it's not something that has a port.
It has the keys, which are also just a numerical value. Don't
think of it as ports but as "layer 4 protocol keys".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-20 13:15 ` Patrick McHardy
@ 2008-01-20 16:48 ` Jan Engelhardt
2008-01-20 16:55 ` Patrick McHardy
0 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-20 16:48 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List
On Jan 20 2008 14:15, Patrick McHardy wrote:
>>
>> > I also don't think the protocol
>> > check is very useful in this case since all conntrack entries contain
>> > port numbers or something similar.
>>
>> Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is?
>
> Sure, by proto_generic, which uses 0 for the port numbers.
See, that's another case why we have to explicitly list the protocols.
Just consider a stupid invocation of iptables:
-m conntrack --ctorigport 0
I'd rather not let that match IPv4-in-IPv4 or so.
>> The protocol check is important though, because IPPROTO_GRE is
>> _not_ included, since, it's not something that has a port.
>
> It has the keys, which are also just a numerical value. Don't
> think of it as ports but as "layer 4 protocol keys".
>
But do these keys actually get modified in NAT?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-20 16:48 ` Jan Engelhardt
@ 2008-01-20 16:55 ` Patrick McHardy
0 siblings, 0 replies; 17+ messages in thread
From: Patrick McHardy @ 2008-01-20 16:55 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List
Jan Engelhardt wrote:
> On Jan 20 2008 14:15, Patrick McHardy wrote:
>>>> I also don't think the protocol
>>>> check is very useful in this case since all conntrack entries contain
>>>> port numbers or something similar.
>>> Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is?
>> Sure, by proto_generic, which uses 0 for the port numbers.
>
> See, that's another case why we have to explicitly list the protocols.
> Just consider a stupid invocation of iptables:
>
> -m conntrack --ctorigport 0
>
> I'd rather not let that match IPv4-in-IPv4 or so.
I prefer that to listing all the protocols explicitly. I guess
you would not object if it was named "--ctorigprotokey", but
--ctorigport is clearer for most protocols.
>>> The protocol check is important though, because IPPROTO_GRE is
>>> _not_ included, since, it's not something that has a port.
>> It has the keys, which are also just a numerical value. Don't
>> think of it as ports but as "layer 4 protocol keys".
>>
> But do these keys actually get modified in NAT?
If the protocol is known to NAT and it clashes then yes.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-20 13:00 ` Patrick McHardy
2008-01-20 13:12 ` Jan Engelhardt
@ 2008-01-21 1:14 ` Pablo Neira Ayuso
2008-01-21 1:15 ` Jan Engelhardt
2008-01-21 1:19 ` Patrick McHardy
1 sibling, 2 replies; 17+ messages in thread
From: Pablo Neira Ayuso @ 2008-01-21 1:14 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List
Patrick McHardy wrote:
> Jan Engelhardt wrote:
>> On Jan 17 2008 14:52, Pablo Neira Ayuso wrote:
>>> Jan Engelhardt wrote:
>>>> + switch (tuple->dst.protonum) {
>>>> + case IPPROTO_TCP:
>>>> + case IPPROTO_UDP:
>>>> + case IPPROTO_SCTP:
>>> Minor nitpick. Add IPPROTO_UDPLITE.
>>
>> Yeah that can be easily added.
BTW, it would be great if we add support for layer 4 protocol state
matching, e.g. match TCP established. We can use this together with the
target that would mark certain events as volatile, e.g.
iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j
VOLATILE
The idea behind this it that ctnetlink would ignore certain events,
thus, reducing CPU load.
--
"Los honestos son inadaptados sociales" -- Les Luthiers
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-21 1:14 ` Pablo Neira Ayuso
@ 2008-01-21 1:15 ` Jan Engelhardt
2008-01-21 1:18 ` Pablo Neira Ayuso
2008-01-21 1:19 ` Patrick McHardy
1 sibling, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-21 1:15 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Patrick McHardy, Netfilter Developer Mailing List
On Jan 21 2008 02:14, Pablo Neira Ayuso wrote:
>
>BTW, it would be great if we add support for layer 4 protocol state
>matching, e.g. match TCP established. We can use this together with the
>target that would mark certain events as volatile, e.g.
>
>iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j
>VOLATILE
And what's xt_VOLATILE do? (Was it hidden in your recent
xt_CONNTRACK submission?)
>The idea behind this it that ctnetlink would ignore certain events,
>thus, reducing CPU load.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-21 1:15 ` Jan Engelhardt
@ 2008-01-21 1:18 ` Pablo Neira Ayuso
2008-01-21 1:31 ` Jan Engelhardt
0 siblings, 1 reply; 17+ messages in thread
From: Pablo Neira Ayuso @ 2008-01-21 1:18 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List
Jan Engelhardt wrote:
> On Jan 21 2008 02:14, Pablo Neira Ayuso wrote:
>> BTW, it would be great if we add support for layer 4 protocol state
>> matching, e.g. match TCP established. We can use this together with the
>> target that would mark certain events as volatile, e.g.
>>
>> iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j
>> VOLATILE
>
> And what's xt_VOLATILE do? (Was it hidden in your recent
> xt_CONNTRACK submission?)
Indeed. Just set the IPCT_VOLATILE flag to tell ctnetlink to skip that
event. It would be a very simple target. I don't know if VOLATILE would
be a nice name, perhaps CTNETLINK.
--
"Los honestos son inadaptados sociales" -- Les Luthiers
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-21 1:14 ` Pablo Neira Ayuso
2008-01-21 1:15 ` Jan Engelhardt
@ 2008-01-21 1:19 ` Patrick McHardy
1 sibling, 0 replies; 17+ messages in thread
From: Patrick McHardy @ 2008-01-21 1:19 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Jan Engelhardt, Netfilter Developer Mailing List
Pablo Neira Ayuso wrote:
> Patrick McHardy wrote:
>> Jan Engelhardt wrote:
>>> On Jan 17 2008 14:52, Pablo Neira Ayuso wrote:
>>>> Jan Engelhardt wrote:
>>>>> + switch (tuple->dst.protonum) {
>>>>> + case IPPROTO_TCP:
>>>>> + case IPPROTO_UDP:
>>>>> + case IPPROTO_SCTP:
>>>> Minor nitpick. Add IPPROTO_UDPLITE.
>>> Yeah that can be easily added.
>
> BTW, it would be great if we add support for layer 4 protocol state
> matching, e.g. match TCP established. We can use this together with the
> target that would mark certain events as volatile, e.g.
>
> iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j
> VOLATILE
>
> The idea behind this it that ctnetlink would ignore certain events,
> thus, reducing CPU load.
I guess the main question is how to do this properly without running
into compatiblity problems at the next opportunity with our crappy
userspace interface. Can we trust that a u8 is enough for all relevant
states for the forseeable future? For the purpose of avoiding
uninteresting state messages it seems like good enough ...
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-21 1:18 ` Pablo Neira Ayuso
@ 2008-01-21 1:31 ` Jan Engelhardt
0 siblings, 0 replies; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-21 1:31 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Patrick McHardy, Netfilter Developer Mailing List
On Jan 21 2008 02:18, Pablo Neira Ayuso wrote:
>>
>> And what's xt_VOLATILE do? (Was it hidden in your recent
>> xt_CONNTRACK submission?)
>
>Indeed. Just set the IPCT_VOLATILE flag to tell ctnetlink to skip that
>event. It would be a very simple target. I don't know if VOLATILE would
>be a nice name, perhaps CTNETLINK.
Oh I would not mind names all that much.
At the basic level, there is ACCEPT DROP and REJECT.
Then, in the depths of POM-nation there is TARPIT and TEE, (I'm missing COFFEE).
Elsewhere, I wrote CHAOS and DELUDE.
Most recently, I sampled up STEAL.
You see, VOLATILE is not so off after all. :-)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [NETFILTER]: xt_conntrack: add port and direction matching
@ 2008-01-24 22:38 Jan Engelhardt
2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt
2008-01-29 13:08 ` [NETFILTER]: xt_conntrack: add port and direction matching Patrick McHardy
0 siblings, 2 replies; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-24 22:38 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
commit 7f1764fa749032eb8566226bbd1c5a58a8a5efc6
Author: Jan Engelhardt <jengelh@computergmbh.de>
Date: Wed Jan 16 18:58:49 2008 +0100
[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>
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index d2492a3..f3fd83e 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -6,9 +6,6 @@
#define _XT_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_tuple_common.h>
-#ifdef __KERNEL__
-# include <linux/in.h>
-#endif
#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define XT_CONNTRACK_STATE_INVALID (1 << 0)
@@ -18,14 +15,21 @@
#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
-#define XT_CONNTRACK_STATE 0x01
-#define XT_CONNTRACK_PROTO 0x02
-#define XT_CONNTRACK_ORIGSRC 0x04
-#define XT_CONNTRACK_ORIGDST 0x08
-#define XT_CONNTRACK_REPLSRC 0x10
-#define XT_CONNTRACK_REPLDST 0x20
-#define XT_CONNTRACK_STATUS 0x40
-#define XT_CONNTRACK_EXPIRES 0x80
+enum {
+ XT_CONNTRACK_STATE = 1 << 0,
+ XT_CONNTRACK_PROTO = 1 << 1,
+ XT_CONNTRACK_ORIGSRC = 1 << 2,
+ XT_CONNTRACK_ORIGDST = 1 << 3,
+ XT_CONNTRACK_REPLSRC = 1 << 4,
+ XT_CONNTRACK_REPLDST = 1 << 5,
+ XT_CONNTRACK_STATUS = 1 << 6,
+ XT_CONNTRACK_EXPIRES = 1 << 7,
+ XT_CONNTRACK_ORIGSRC_PORT = 1 << 8,
+ XT_CONNTRACK_ORIGDST_PORT = 1 << 9,
+ XT_CONNTRACK_REPLSRC_PORT = 1 << 10,
+ XT_CONNTRACK_REPLDST_PORT = 1 << 11,
+ XT_CONNTRACK_DIRECTION = 1 << 12,
+};
/* This is exposed to userspace, so remains frozen in time. */
struct ip_conntrack_old_tuple
@@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 {
union nf_inet_addr repldst_addr, repldst_mask;
u_int32_t expires_min, expires_max;
u_int16_t l4proto;
+ __be16 origsrc_port, origdst_port;
+ __be16 replsrc_port, repldst_port;
+ u_int16_t match_flags, invert_flags;
u_int8_t state_mask, status_mask;
- u_int8_t match_flags, invert_flags;
};
#endif /*_XT_CONNTRACK_H*/
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index e92190e..8533085 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -4,7 +4,6 @@
*
* (C) 2001 Marc Boucher (marc@mbsi.ca).
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
- * Jan Engelhardt <jengelh@computergmbh.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -20,6 +19,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: connection tracking state match");
MODULE_ALIAS("ipt_conntrack");
MODULE_ALIAS("ip6t_conntrack");
@@ -166,6 +166,44 @@ conntrack_mt_repldst(const struct nf_conn *ct,
&info->repldst_addr, &info->repldst_mask, family);
}
+static inline bool
+ct_proto_port_check(const struct xt_conntrack_mtinfo1 *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) &&
+ (tuple->dst.protonum == 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) &&
+ (tuple->src.u.all == info->origsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
+ (tuple->dst.u.all == info->origdst_port) ^
+ !(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) &&
+ (tuple->src.u.all == info->replsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
+ (tuple->dst.u.all == info->repldst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
+ return false;
+
+ return true;
+}
+
static bool
conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
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,
if (ct == NULL)
return info->match_flags & XT_CONNTRACK_STATE;
-
- if ((info->match_flags & XT_CONNTRACK_PROTO) &&
- ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
- info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+ if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
+ (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
+ !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
return false;
if (info->match_flags & XT_CONNTRACK_ORIGSRC)
@@ -226,6 +263,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
!(info->invert_flags & XT_CONNTRACK_REPLDST))
return false;
+ if (!ct_proto_port_check(info, ct))
+ return false;
+
if ((info->match_flags & XT_CONNTRACK_STATUS) &&
(!!(info->status_mask & ct->status) ^
!(info->invert_flags & XT_CONNTRACK_STATUS)))
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [IPTABLES]: libxt_conntrack revision 1
2008-01-24 22:38 [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt
@ 2008-01-24 22:38 ` Jan Engelhardt
2008-01-29 13:20 ` Patrick McHardy
2008-01-29 13:08 ` [NETFILTER]: xt_conntrack: add port and direction matching Patrick McHardy
1 sibling, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-24 22:38 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
Add support for xt_conntrack match revision 1.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
extensions/libxt_conntrack.c | 575 ++++++++++++++++++++++++++++++++++++++++-
extensions/libxt_conntrack.man | 18 -
2 files changed, 576 insertions(+), 17 deletions(-)
Index: iptables/extensions/libxt_conntrack.c
===================================================================
--- iptables.orig/extensions/libxt_conntrack.c
+++ iptables/extensions/libxt_conntrack.c
@@ -1,10 +1,17 @@
-/* Shared library add-on to iptables for conntrack matching support.
- * GPL (C) 2001 Marc Boucher (marc@mbsi.ca).
+/*
+ * libxt_conntrack
+ * Shared library add-on to iptables for conntrack matching support.
+ *
+ * GPL (C) 2001 Marc Boucher (marc@mbsi.ca).
+ * Copyright © CC Computer Consultants GmbH, 2007 - 2008
+ * Jan Engelhardt <jengelh@computergmbh.de>
*/
-
+#include <sys/socket.h>
+#include <sys/types.h>
#include <ctype.h>
#include <getopt.h>
#include <netdb.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -13,6 +20,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter/xt_conntrack.h>
#include <linux/netfilter/nf_conntrack_common.h>
+#include <arpa/inet.h>
/* Function which prints out usage message. */
static void conntrack_mt_help(void)
@@ -27,14 +35,20 @@ static void conntrack_mt_help(void)
"[!] --ctreplsrc address[/mask]\n"
"[!] --ctrepldst address[/mask]\n"
" Original/Reply source/destination address\n"
+"[!] --ctorigsrcport port\n"
+"[!] --ctorigdstport port\n"
+"[!] --ctreplsrcport port\n"
+"[!] --ctrepldstport port\n"
+" TCP/UDP/SCTP orig./reply source/destination port\n"
"[!] --ctstatus {NONE|EXPECTED|SEEN_REPLY|ASSURED|CONFIRMED}[,...]\n"
" Status(es) to match\n"
"[!] --ctexpire time[:time] Match remaining lifetime in seconds against\n"
" value or range of values (inclusive)\n"
+" --ctdir {ORIGINAL|REPLY} Flow direction of packet\n"
"\n");
}
-static const struct option conntrack_mt_opts[] = {
+static const struct option conntrack_mt_opts_v0[] = {
{.name = "ctstate", .has_arg = true, .val = '1'},
{.name = "ctproto", .has_arg = true, .val = '2'},
{.name = "ctorigsrc", .has_arg = true, .val = '3'},
@@ -46,6 +60,23 @@ static const struct option conntrack_mt_
{},
};
+static const struct option conntrack_mt_opts[] = {
+ {.name = "ctstate", .has_arg = true, .val = '1'},
+ {.name = "ctproto", .has_arg = true, .val = '2'},
+ {.name = "ctorigsrc", .has_arg = true, .val = '3'},
+ {.name = "ctorigdst", .has_arg = true, .val = '4'},
+ {.name = "ctreplsrc", .has_arg = true, .val = '5'},
+ {.name = "ctrepldst", .has_arg = true, .val = '6'},
+ {.name = "ctstatus", .has_arg = true, .val = '7'},
+ {.name = "ctexpire", .has_arg = true, .val = '8'},
+ {.name = "ctorigsrcport", .has_arg = true, .val = 'a'},
+ {.name = "ctorigdstport", .has_arg = true, .val = 'b'},
+ {.name = "ctreplsrcport", .has_arg = true, .val = 'c'},
+ {.name = "ctrepldstport", .has_arg = true, .val = 'd'},
+ {.name = "ctdir", .has_arg = true, .val = 'e'},
+ {},
+};
+
static int
parse_state(const char *state, size_t strlen, struct xt_conntrack_info *sinfo)
{
@@ -83,6 +114,45 @@ parse_states(const char *arg, struct xt_
exit_error(PARAMETER_PROBLEM, "Bad ctstate `%s'", arg);
}
+static bool
+conntrack_ps_state(struct xt_conntrack_mtinfo1 *info, const char *state,
+ size_t z)
+{
+ if (strncasecmp(state, "INVALID", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_INVALID;
+ else if (strncasecmp(state, "NEW", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_NEW);
+ else if (strncasecmp(state, "ESTABLISHED", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED);
+ else if (strncasecmp(state, "RELATED", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_RELATED);
+ else if (strncasecmp(state, "UNTRACKED", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_UNTRACKED;
+ else if (strncasecmp(state, "SNAT", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_SNAT;
+ else if (strncasecmp(state, "DNAT", z) == 0)
+ info->state_mask |= XT_CONNTRACK_STATE_DNAT;
+ else
+ return false;
+ return true;
+}
+
+static void
+conntrack_ps_states(struct xt_conntrack_mtinfo1 *info, const char *arg)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !conntrack_ps_state(info, arg, comma - arg))
+ exit_error(PARAMETER_PROBLEM,
+ "Bad ctstate \"%s\"", arg);
+ arg = comma + 1;
+ }
+
+ if (strlen(arg) == 0 || !conntrack_ps_state(info, arg, strlen(arg)))
+ exit_error(PARAMETER_PROBLEM, "Bad ctstate \"%s\"", arg);
+}
+
static int
parse_status(const char *status, size_t strlen, struct xt_conntrack_info *sinfo)
{
@@ -96,7 +166,7 @@ parse_status(const char *status, size_t
sinfo->statusmask |= IPS_ASSURED;
#ifdef IPS_CONFIRMED
else if (strncasecmp(status, "CONFIRMED", strlen) == 0)
- sinfo->stausmask |= IPS_CONFIRMED;
+ sinfo->statusmask |= IPS_CONFIRMED;
#endif
else
return 0;
@@ -118,6 +188,41 @@ parse_statuses(const char *arg, struct x
exit_error(PARAMETER_PROBLEM, "Bad ctstatus `%s'", arg);
}
+static bool
+conntrack_ps_status(struct xt_conntrack_mtinfo1 *info, const char *status,
+ size_t z)
+{
+ if (strncasecmp(status, "NONE", z) == 0)
+ info->status_mask |= 0;
+ else if (strncasecmp(status, "EXPECTED", z) == 0)
+ info->status_mask |= IPS_EXPECTED;
+ else if (strncasecmp(status, "SEEN_REPLY", z) == 0)
+ info->status_mask |= IPS_SEEN_REPLY;
+ else if (strncasecmp(status, "ASSURED", z) == 0)
+ info->status_mask |= IPS_ASSURED;
+ else if (strncasecmp(status, "CONFIRMED", z) == 0)
+ info->status_mask |= IPS_CONFIRMED;
+ else
+ return false;
+ return true;
+}
+
+static void
+conntrack_ps_statuses(struct xt_conntrack_mtinfo1 *info, const char *arg)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !conntrack_ps_status(info, arg, comma - arg))
+ exit_error(PARAMETER_PROBLEM,
+ "Bad ctstatus \"%s\"", arg);
+ arg = comma + 1;
+ }
+
+ if (strlen(arg) == 0 || !conntrack_ps_status(info, arg, strlen(arg)))
+ exit_error(PARAMETER_PROBLEM, "Bad ctstatus \"%s\"", arg);
+}
+
static unsigned long
parse_expire(const char *s)
{
@@ -138,7 +243,8 @@ parse_expires(const char *s, struct xt_c
buffer = strdup(s);
if ((cp = strchr(buffer, ':')) == NULL)
- sinfo->expires_min = sinfo->expires_max = parse_expire(buffer);
+ sinfo->expires_min = sinfo->expires_max =
+ parse_expire(buffer);
else {
*cp = '\0';
cp++;
@@ -154,6 +260,30 @@ parse_expires(const char *s, struct xt_c
"range value `%lu'", sinfo->expires_min, sinfo->expires_max);
}
+static void
+conntrack_ps_expires(struct xt_conntrack_mtinfo1 *info, const char *s)
+{
+ unsigned int min, max;
+ char *end;
+
+ if (!strtonum(s, &end, &min, 0, ~0))
+ param_act(P_BAD_VALUE, "conntrack", "--expires", s);
+ max = min;
+ if (*end == ':')
+ if (!strtonum(s, &end, &max, 0, ~0U))
+ param_act(P_BAD_VALUE, "conntrack", "--expires", s);
+ if (*end != '\0')
+ param_act(P_BAD_VALUE, "conntrack", "--expires", s);
+
+ if (min > max)
+ exit_error(PARAMETER_PROBLEM,
+ "expire min. range value \"%u\" greater than max. "
+ "range value \"%u\"", min, max);
+
+ info->expires_min = min;
+ info->expires_max = max;
+}
+
/* Function which parses command options; returns true if it
ate an option */
static int conntrack_parse(int c, char **argv, int invert, unsigned int *flags,
@@ -305,10 +435,257 @@ static int conntrack_parse(int c, char *
return 1;
}
+static int
+conntrack_mt_parse(int c, char **argv, int invert, unsigned int *flags,
+ struct xt_entry_match **match)
+{
+ struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data;
+ unsigned int port;
+ char *p;
+
+ switch (c) {
+ case '1': /* --ctstate */
+ conntrack_ps_states(info, optarg);
+ info->match_flags |= XT_CONNTRACK_STATE;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_STATE;
+ break;
+
+ case '2': /* --ctproto */
+ /* Canonicalize into lower case */
+ for (p = optarg; *p != '\0'; ++p)
+ *p = tolower(*p);
+ info->l4proto = parse_protocol(optarg);
+
+ if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO))
+ exit_error(PARAMETER_PROBLEM, "conntrack: rule would "
+ "never match protocol");
+
+ info->match_flags |= XT_CONNTRACK_PROTO;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_PROTO;
+ break;
+
+ case '7': /* --ctstatus */
+ conntrack_ps_statuses(info, optarg);
+ info->match_flags |= XT_CONNTRACK_STATUS;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_STATUS;
+ break;
+
+ case '8': /* --ctexpire */
+ conntrack_ps_expires(info, optarg);
+ info->match_flags |= XT_CONNTRACK_EXPIRES;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_EXPIRES;
+ break;
+
+ case 'a': /* --ctorigsrcport */
+ if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0))
+ param_act(P_BAD_VALUE, "conntrack",
+ "--ctorigsrcport", optarg);
+ info->match_flags |= XT_CONNTRACK_ORIGSRC_PORT;
+ info->origsrc_port = htons(port);
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_ORIGSRC_PORT;
+ break;
+
+ case 'b': /* --ctorigdstport */
+ if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0))
+ param_act(P_BAD_VALUE, "conntrack",
+ "--ctorigdstport", optarg);
+ info->match_flags |= XT_CONNTRACK_ORIGDST_PORT;
+ info->origdst_port = htons(port);
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_ORIGDST_PORT;
+ break;
+
+ case 'c': /* --ctreplsrcport */
+ if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0))
+ param_act(P_BAD_VALUE, "conntrack",
+ "--ctreplsrcport", optarg);
+ info->match_flags |= XT_CONNTRACK_REPLSRC_PORT;
+ info->replsrc_port = htons(port);
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_REPLSRC_PORT;
+ break;
+
+ case 'd': /* --ctrepldstport */
+ if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0))
+ param_act(P_BAD_VALUE, "conntrack",
+ "--ctrepldstport", optarg);
+ info->match_flags |= XT_CONNTRACK_REPLDST_PORT;
+ info->repldst_port = htons(port);
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_REPLDST_PORT;
+ break;
+
+ case 'e': /* --ctdir */
+ param_act(P_NO_INVERT, "conntrack", "--ctdir", invert);
+ if (strcasecmp(optarg, "ORIGINAL") == 0) {
+ info->match_flags |= XT_CONNTRACK_DIRECTION;
+ info->invert_flags &= ~XT_CONNTRACK_DIRECTION;
+ } else if (strcasecmp(optarg, "REPLY") == 0) {
+ info->match_flags |= XT_CONNTRACK_DIRECTION;
+ info->invert_flags |= XT_CONNTRACK_DIRECTION;
+ } else {
+ param_act(P_BAD_VALUE, "conntrack", "--ctdir", optarg);
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ *flags = info->match_flags;
+ return true;
+}
+
+static int
+conntrack_mt4_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data;
+ struct in_addr *addr = NULL;
+ unsigned int naddrs = 0;
+
+ switch (c) {
+ case '3': /* --ctorigsrc */
+ ipparse_hostnetworkmask(optarg, &addr, &info->origsrc_mask.in,
+ &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->origsrc_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_ORIGSRC;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_ORIGSRC;
+ break;
+
+ case '4': /* --ctorigdst */
+ ipparse_hostnetworkmask(optarg, &addr, &info->origdst_mask.in,
+ &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->origdst_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_ORIGDST;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_ORIGDST;
+ break;
+
+ case '5': /* --ctreplsrc */
+ ipparse_hostnetworkmask(optarg, &addr, &info->replsrc_mask.in,
+ &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->replsrc_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_REPLSRC;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_REPLSRC;
+ break;
+
+ case '6': /* --ctrepldst */
+ ipparse_hostnetworkmask(optarg, &addr, &info->repldst_mask.in,
+ &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->repldst_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_REPLDST;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_REPLDST;
+ break;
+
+
+ default:
+ return conntrack_mt_parse(c, argv, invert, flags, match);
+ }
+
+ *flags = info->match_flags;
+ return true;
+}
+
+static int
+conntrack_mt6_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data;
+ struct in6_addr *addr = NULL;
+ unsigned int naddrs = 0;
+
+ switch (c) {
+ case '3': /* --ctorigsrc */
+ ip6parse_hostnetworkmask(optarg, &addr,
+ &info->origsrc_mask.in6, &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->origsrc_addr.in6, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_ORIGSRC;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_ORIGSRC;
+ break;
+
+ case '4': /* --ctorigdst */
+ ip6parse_hostnetworkmask(optarg, &addr,
+ &info->origdst_mask.in6, &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->origdst_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_ORIGDST;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_ORIGDST;
+ break;
+
+ case '5': /* --ctreplsrc */
+ ip6parse_hostnetworkmask(optarg, &addr,
+ &info->replsrc_mask.in6, &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->replsrc_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_REPLSRC;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_REPLSRC;
+ break;
+
+ case '6': /* --ctrepldst */
+ ip6parse_hostnetworkmask(optarg, &addr,
+ &info->repldst_mask.in6, &naddrs);
+ if (naddrs > 1)
+ exit_error(PARAMETER_PROBLEM,
+ "multiple IP addresses not allowed");
+ if (naddrs == 1)
+ memcpy(&info->repldst_addr.in, addr, sizeof(*addr));
+ info->match_flags |= XT_CONNTRACK_REPLDST;
+ if (invert)
+ info->invert_flags |= XT_CONNTRACK_REPLDST;
+ break;
+
+
+ default:
+ return conntrack_mt_parse(c, argv, invert, flags, match);
+ }
+
+ *flags = info->match_flags;
+ return true;
+}
+
static void conntrack_mt_check(unsigned int flags)
{
if (flags == 0)
- exit_error(PARAMETER_PROBLEM, "You must specify one or more options");
+ exit_error(PARAMETER_PROBLEM, "conntrack: At least one option "
+ "is required");
}
static void
@@ -364,20 +741,37 @@ print_status(unsigned int statusmask)
printf("%sASSURED", sep);
sep = ",";
}
-#ifdef IPS_CONFIRMED
if (statusmask & IPS_CONFIRMED) {
printf("%sCONFIRMED", sep);
- sep =",";
- }
-#endif
- if (statusmask == 0) {
- printf("%sNONE", sep);
sep = ",";
}
+ if (statusmask == 0)
+ printf("%sNONE", sep);
printf(" ");
}
static void
+conntrack_dump_addr(const union nf_inet_addr *addr,
+ const union nf_inet_addr *mask,
+ unsigned int family, bool numeric)
+{
+ if (family == AF_INET) {
+ if (!numeric && addr->ip == 0) {
+ printf("anywhere ");
+ return;
+ }
+ printf("%s ", ipaddr_to_anyname(&addr->in));
+ } else if (family == AF_INET6) {
+ if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 &&
+ addr->ip6[2] == 0 && addr->ip6[3] == 0) {
+ printf("anywhere ");
+ return;
+ }
+ printf("%s ", ip6addr_to_anyname(&addr->in6));
+ }
+}
+
+static void
print_addr(struct in_addr *addr, struct in_addr *mask, int inv, int numeric)
{
char buf[BUFSIZ];
@@ -484,6 +878,103 @@ matchinfo_print(const void *ip, const st
}
}
+static void
+conntrack_dump(const struct xt_conntrack_mtinfo1 *info, const char *prefix,
+ unsigned int family, bool numeric)
+{
+ if (info->match_flags & XT_CONNTRACK_STATE) {
+ if (info->invert_flags & XT_CONNTRACK_STATE)
+ printf("! ");
+ printf("%sctstate ", prefix);
+ print_state(info->state_mask);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_PROTO) {
+ if (info->invert_flags & XT_CONNTRACK_PROTO)
+ printf("! ");
+ printf("%sctproto %u ", prefix, info->l4proto);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_ORIGSRC) {
+ if (info->invert_flags & XT_CONNTRACK_PROTO)
+ printf("! ");
+ printf("%sctorigsrc ", prefix);
+ conntrack_dump_addr(&info->origsrc_addr, &info->origsrc_mask,
+ family, numeric);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_ORIGDST) {
+ if (info->invert_flags & XT_CONNTRACK_PROTO)
+ printf("! ");
+ printf("%sctorigdst ", prefix);
+ conntrack_dump_addr(&info->origdst_addr, &info->origdst_mask,
+ family, numeric);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_REPLSRC) {
+ if (info->invert_flags & XT_CONNTRACK_PROTO)
+ printf("! ");
+ printf("%sctreplsrc ", prefix);
+ conntrack_dump_addr(&info->replsrc_addr, &info->replsrc_mask,
+ family, numeric);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_REPLDST) {
+ if (info->invert_flags & XT_CONNTRACK_PROTO)
+ printf("! ");
+ printf("%sctrepldst ", prefix);
+ conntrack_dump_addr(&info->repldst_addr, &info->repldst_mask,
+ family, numeric);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) {
+ if (info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT)
+ printf("! ");
+ printf("%sctorigsrcport %u ", prefix,
+ ntohs(info->origsrc_port));
+ }
+
+ if (info->match_flags & XT_CONNTRACK_ORIGDST_PORT) {
+ if (info->invert_flags & XT_CONNTRACK_ORIGDST_PORT)
+ printf("! ");
+ printf("%sctorigdstport %u ", prefix,
+ ntohs(info->origdst_port));
+ }
+
+ if (info->match_flags & XT_CONNTRACK_REPLSRC_PORT) {
+ if (info->invert_flags & XT_CONNTRACK_REPLSRC_PORT)
+ printf("! ");
+ printf("%sctreplsrcport %u ", prefix,
+ ntohs(info->replsrc_port));
+ }
+
+ if (info->match_flags & XT_CONNTRACK_REPLDST_PORT) {
+ if (info->invert_flags & XT_CONNTRACK_REPLDST_PORT)
+ printf("! ");
+ printf("%sctrepldstport %u ", prefix,
+ ntohs(info->repldst_port));
+ }
+
+ if (info->match_flags & XT_CONNTRACK_STATUS) {
+ if (info->invert_flags & XT_CONNTRACK_STATUS)
+ printf("! ");
+ printf("%sctstatus ", prefix);
+ print_status(info->status_mask);
+ }
+
+ if (info->match_flags & XT_CONNTRACK_EXPIRES) {
+ if (info->invert_flags & XT_CONNTRACK_EXPIRES)
+ printf("! ");
+ printf("%sctexpire ", prefix);
+
+ if (info->expires_max == info->expires_min)
+ printf("%u ", (unsigned int)info->expires_min);
+ else
+ printf("%u:%u ", (unsigned int)info->expires_min,
+ (unsigned int)info->expires_max);
+ }
+}
+
/* Prints out the matchinfo. */
static void conntrack_print(const void *ip, const struct xt_entry_match *match,
int numeric)
@@ -491,12 +982,38 @@ static void conntrack_print(const void *
matchinfo_print(ip, match, numeric, "");
}
+static void
+conntrack_mt_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ conntrack_dump((const void *)match->data, "", AF_INET, numeric);
+}
+
+static void
+conntrack_mt6_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ conntrack_dump((const void *)match->data, "", AF_INET6, numeric);
+}
+
/* Saves the matchinfo in parsable form to stdout. */
static void conntrack_save(const void *ip, const struct xt_entry_match *match)
{
matchinfo_print(ip, match, 1, "--");
}
+static void conntrack_mt_save(const void *ip,
+ const struct xt_entry_match *match)
+{
+ conntrack_dump((const void *)match->data, "--", AF_INET, true);
+}
+
+static void conntrack_mt6_save(const void *ip,
+ const struct xt_entry_match *match)
+{
+ conntrack_dump((const void *)match->data, "--", AF_INET6, true);
+}
+
static struct xtables_match conntrack_match = {
.version = IPTABLES_VERSION,
.name = "conntrack",
@@ -509,10 +1026,42 @@ static struct xtables_match conntrack_ma
.final_check = conntrack_mt_check,
.print = conntrack_print,
.save = conntrack_save,
+ .extra_opts = conntrack_mt_opts_v0,
+};
+
+static struct xtables_match conntrack_mt_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "conntrack",
+ .revision = 1,
+ .family = AF_INET,
+ .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
+ .help = conntrack_mt_help,
+ .parse = conntrack_mt4_parse,
+ .final_check = conntrack_mt_check,
+ .print = conntrack_mt_print,
+ .save = conntrack_mt_save,
+ .extra_opts = conntrack_mt_opts,
+};
+
+static struct xtables_match conntrack_mt6_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "conntrack",
+ .revision = 1,
+ .family = AF_INET6,
+ .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
+ .help = conntrack_mt_help,
+ .parse = conntrack_mt6_parse,
+ .final_check = conntrack_mt_check,
+ .print = conntrack_mt6_print,
+ .save = conntrack_mt6_save,
.extra_opts = conntrack_mt_opts,
};
void _init(void)
{
xtables_register_match(&conntrack_match);
+ xtables_register_match(&conntrack_mt_reg);
+ xtables_register_match(&conntrack_mt6_reg);
}
Index: iptables/extensions/libxt_conntrack.man
===================================================================
--- iptables.orig/extensions/libxt_conntrack.man
+++ iptables/extensions/libxt_conntrack.man
@@ -9,16 +9,22 @@ Possible states are listed below.
Layer-4 protocol to match (by number or name)
.TP
[\fB!\fR] \fB--ctorigsrc\fR \fIaddress\fR[\fB/\fR\fImask\fR]
-Match against original source address
.TP
[\fB!\fR] \fB--ctorigdst\fR \fIaddress\fR[\fB/\fR\fImask\fR]
-Match against original destination address
.TP
[\fB!\fR] \fB--ctreplsrc\fR \fIaddress\fR[\fB/\fR\fImask\fR]
-Match against reply source address
.TP
[\fB!\fR] \fB--ctrepldst\fR \fIaddress\fR[\fB/\fR\fImask\fR]
-Match against reply destination address
+Match against original/reply source/destination address
+.TP
+[\fB!\fR] \fB--ctorigsrcport\fR \fIport\fR
+.TP
+[\fB!\fR] \fB--ctorigdstport\fR \fIport\fR
+.TP
+[\fB!\fR] \fB--ctreplsrcport\fR \fIport\fR
+.TP
+[\fB!\fR] \fB--ctrepldstport\fR \fIport\fR
+Match against original/reply source/destination port (TCP/UDP/etc.) or GRE key.
.TP
[\fB!\fR] \fB--ctstatus\fR \fIstatelist\fR
\fIstatuslist\fR is a comma separated list of the connection statuses to match.
@@ -27,6 +33,10 @@ Possible statuses are listed below.
[\fB!\fR] \fB--ctexpire\fR \fItime\fR[\fB:\fR\fItime\fR]
Match remaining lifetime in seconds against given value or range of values
(inclusive)
+.TP
+\fB--ctdir\fR {\fBORIGINAL\fR|\fBREPLY\fR}
+Match packets that are flowing in the specified direction. If this flag is not
+specified at all, matches packets in both directions.
.PP
States for \fB--ctstate\fR:
.TP
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching
2008-01-24 22:38 [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt
2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt
@ 2008-01-29 13:08 ` Patrick McHardy
1 sibling, 0 replies; 17+ messages in thread
From: Patrick McHardy @ 2008-01-29 13:08 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> commit 7f1764fa749032eb8566226bbd1c5a58a8a5efc6
> Author: Jan Engelhardt <jengelh@computergmbh.de>
> Date: Wed Jan 16 18:58:49 2008 +0100
>
> [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.
Applied, thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [IPTABLES]: libxt_conntrack revision 1
2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt
@ 2008-01-29 13:20 ` Patrick McHardy
0 siblings, 0 replies; 17+ messages in thread
From: Patrick McHardy @ 2008-01-29 13:20 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> Add support for xt_conntrack match revision 1.
>
> Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Applied, thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-01-29 13:36 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-24 22:38 [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt
2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt
2008-01-29 13:20 ` Patrick McHardy
2008-01-29 13:08 ` [NETFILTER]: xt_conntrack: add port and direction matching Patrick McHardy
-- strict thread matches above, loose matches on Subject: below --
2008-01-02 20:18 [PATCH 0/27] Netfilter update Jan Engelhardt
2008-01-02 20:28 ` [PATCH 10/27] xt_conntrack match, revision 1 Jan Engelhardt
2008-01-04 14:53 ` Patrick McHardy
2008-01-15 6:48 ` Patrick McHardy
2008-01-15 12:31 ` Jan Engelhardt
2008-01-15 14:13 ` Patrick McHardy
2008-01-16 18:02 ` [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt
2008-01-17 13:52 ` Pablo Neira Ayuso
2008-01-17 15:00 ` Jan Engelhardt
2008-01-20 13:00 ` Patrick McHardy
2008-01-20 13:12 ` Jan Engelhardt
2008-01-20 13:15 ` Patrick McHardy
2008-01-20 16:48 ` Jan Engelhardt
2008-01-20 16:55 ` Patrick McHardy
2008-01-21 1:14 ` Pablo Neira Ayuso
2008-01-21 1:15 ` Jan Engelhardt
2008-01-21 1:18 ` Pablo Neira Ayuso
2008-01-21 1:31 ` Jan Engelhardt
2008-01-21 1:19 ` Patrick McHardy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).