From c3704c0e73d0dda9d9d5919af22831a439fbc611 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sun, 13 Apr 2008 00:38:09 +0000 Subject: - add nfct_cmp (replacement for nfct_compare a bit more flexible) - add nfct_copy - conditional build of original and reply tuples - fix secmark parsing --- src/conntrack/compare.c | 146 +++++++++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 58 deletions(-) (limited to 'src/conntrack/compare.c') 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; } -- cgit v1.2.3