summaryrefslogtreecommitdiffstats
path: root/src/conntrack/compare.c
diff options
context:
space:
mode:
author/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org>2008-04-13 00:38:09 +0000
committer/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org>2008-04-13 00:38:09 +0000
commitc3704c0e73d0dda9d9d5919af22831a439fbc611 (patch)
tree85dd4d2f6e0308a196b097273d6e28cfe038d792 /src/conntrack/compare.c
parent721a93769a15c0f579a389ad58d82d14d13f7f93 (diff)
- add nfct_cmp (replacement for nfct_compare a bit more flexible)
- add nfct_copy - conditional build of original and reply tuples - fix secmark parsing
Diffstat (limited to 'src/conntrack/compare.c')
-rw-r--r--src/conntrack/compare.c146
1 files changed, 88 insertions, 58 deletions
diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c
index a5c66e2..0280638 100644
--- a/src/conntrack/compare.c
+++ b/src/conntrack/compare.c
@@ -7,28 +7,34 @@
#include "internal.h"
-int __compare(const struct nf_conntrack *ct1,
- const struct nf_conntrack *ct2)
+static int cmp_orig(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2)
{
- if (test_bit(ATTR_MARK, ct1->set) &&
- test_bit(ATTR_MARK, ct2->set) &&
- ct1->mark != ct2->mark)
- return 0;
+ if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].src.v4 !=
+ ct2->tuple[__DIR_ORIG].src.v4)
+ return 0;
- if (test_bit(ATTR_TIMEOUT, ct1->set) &&
- test_bit(ATTR_TIMEOUT, ct2->set) &&
- ct1->timeout != ct2->timeout)
- return 0;
+ if (test_bit(ATTR_ORIG_IPV4_DST, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV4_DST, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].dst.v4 !=
+ ct2->tuple[__DIR_ORIG].dst.v4)
+ return 0;
- if (test_bit(ATTR_STATUS, ct1->set) &&
- test_bit(ATTR_STATUS, ct2->set) &&
- ct1->status == ct2->status)
- return 0;
+ if (test_bit(ATTR_ORIG_IPV6_SRC, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV6_SRC, ct2->set) &&
+ memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
+ &ct2->tuple[__DIR_ORIG].src.v6,
+ sizeof(u_int32_t)*4) == 0)
+ return 0;
- if (test_bit(ATTR_TCP_STATE, ct1->set) &&
- test_bit(ATTR_TCP_STATE, ct2->set) &&
- ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
- return 0;
+ if (test_bit(ATTR_ORIG_IPV6_DST, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV6_DST, ct2->set) &&
+ memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
+ &ct2->tuple[__DIR_ORIG].dst.v6,
+ sizeof(u_int32_t)*4) == 0)
+ return 0;
if (test_bit(ATTR_ORIG_L3PROTO, ct1->set) &&
test_bit(ATTR_ORIG_L3PROTO, ct2->set) &&
@@ -36,15 +42,7 @@ int __compare(const struct nf_conntrack *ct1,
ct2->tuple[__DIR_ORIG].l3protonum != AF_UNSPEC &&
ct1->tuple[__DIR_ORIG].l3protonum !=
ct2->tuple[__DIR_ORIG].l3protonum)
- return 0;
-
- if (test_bit(ATTR_REPL_L3PROTO, ct1->set) &&
- test_bit(ATTR_REPL_L3PROTO, ct2->set) &&
- ct1->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
- ct2->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
- ct1->tuple[__DIR_REPL].l3protonum !=
- ct2->tuple[__DIR_REPL].l3protonum)
- return 0;
+ return 0;
if (test_bit(ATTR_ORIG_L4PROTO, ct1->set) &&
test_bit(ATTR_ORIG_L4PROTO, ct2->set) &&
@@ -52,24 +50,12 @@ int __compare(const struct nf_conntrack *ct1,
ct2->tuple[__DIR_ORIG].protonum)
return 0;
- if (test_bit(ATTR_REPL_L4PROTO, ct1->set) &&
- test_bit(ATTR_REPL_L4PROTO, ct2->set) &&
- ct1->tuple[__DIR_REPL].protonum !=
- ct2->tuple[__DIR_REPL].protonum)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
- test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
- ct1->tuple[__DIR_ORIG].src.v4 !=
- ct2->tuple[__DIR_ORIG].src.v4)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV4_DST, ct1->set) &&
- test_bit(ATTR_ORIG_IPV4_DST, ct2->set) &&
- ct1->tuple[__DIR_ORIG].dst.v4 !=
- ct2->tuple[__DIR_ORIG].dst.v4)
- return 0;
+ return 1;
+}
+static int cmp_repl(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2)
+{
if (test_bit(ATTR_REPL_IPV4_SRC, ct1->set) &&
test_bit(ATTR_REPL_IPV4_SRC, ct2->set) &&
ct1->tuple[__DIR_REPL].src.v4 !=
@@ -82,20 +68,6 @@ int __compare(const struct nf_conntrack *ct1,
ct2->tuple[__DIR_REPL].dst.v4)
return 0;
- if (test_bit(ATTR_ORIG_IPV6_SRC, ct1->set) &&
- test_bit(ATTR_ORIG_IPV6_SRC, ct2->set) &&
- memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
- &ct2->tuple[__DIR_ORIG].src.v6,
- sizeof(u_int32_t)*4) == 0)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV6_DST, ct1->set) &&
- test_bit(ATTR_ORIG_IPV6_DST, ct2->set) &&
- memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
- &ct2->tuple[__DIR_ORIG].dst.v6,
- sizeof(u_int32_t)*4) == 0)
- return 0;
-
if (test_bit(ATTR_REPL_IPV6_SRC, ct1->set) &&
test_bit(ATTR_REPL_IPV6_SRC, ct2->set) &&
memcmp(&ct1->tuple[__DIR_REPL].src.v6,
@@ -110,5 +82,63 @@ int __compare(const struct nf_conntrack *ct1,
sizeof(u_int32_t)*4) == 0)
return 0;
+ if (test_bit(ATTR_REPL_L3PROTO, ct1->set) &&
+ test_bit(ATTR_REPL_L3PROTO, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
+ ct2->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
+ ct1->tuple[__DIR_REPL].l3protonum !=
+ ct2->tuple[__DIR_REPL].l3protonum)
+ return 0;
+
+ if (test_bit(ATTR_REPL_L4PROTO, ct1->set) &&
+ test_bit(ATTR_REPL_L4PROTO, ct2->set) &&
+ ct1->tuple[__DIR_REPL].protonum !=
+ ct2->tuple[__DIR_REPL].protonum)
+ return 0;
+
+ return 1;
+}
+
+static int cmp_meta(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2)
+{
+ if (test_bit(ATTR_MARK, ct1->set) &&
+ test_bit(ATTR_MARK, ct2->set) &&
+ ct1->mark != ct2->mark)
+ return 0;
+
+ if (test_bit(ATTR_TIMEOUT, ct1->set) &&
+ test_bit(ATTR_TIMEOUT, ct2->set) &&
+ ct1->timeout != ct2->timeout)
+ return 0;
+
+ if (test_bit(ATTR_STATUS, ct1->set) &&
+ test_bit(ATTR_STATUS, ct2->set) &&
+ ct1->status == ct2->status)
+ return 0;
+
+ if (test_bit(ATTR_TCP_STATE, ct1->set) &&
+ test_bit(ATTR_TCP_STATE, ct2->set) &&
+ ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
+ return 0;
+
+ return 1;
+}
+
+int __compare(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2,
+ unsigned int flags)
+{
+ if (flags == NFCT_CMP_ALL)
+ return cmp_orig(ct1, ct2) &&
+ cmp_repl(ct1, ct2) &&
+ cmp_meta(ct1, ct2);
+
+ if (flags & NFCT_CMP_ORIG && !cmp_orig(ct1, ct2))
+ return 0;
+
+ if (flags & NFCT_CMP_REPL && !cmp_repl(ct1, ct2))
+ return 0;
+
return 1;
}