summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-05-16 15:50:08 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2008-05-16 15:50:08 +0200
commit3dedd39ac8c3f4c9b3503e6a9b602fdf0341c7ed (patch)
treeb807d2df276271cda127c3ad9f814c9738630880 /src
parent71006b474001e697a30719d1ae3e66fefa9f181b (diff)
fix __nfct_l4 structure layout (specifically, ICMP)
fix nfct_cmp(): add port comparison, better ICMP support
Diffstat (limited to 'src')
-rw-r--r--src/conntrack/compare.c90
1 files changed, 82 insertions, 8 deletions
diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c
index d1597c3..cd51f9d 100644
--- a/src/conntrack/compare.c
+++ b/src/conntrack/compare.c
@@ -19,10 +19,47 @@ static int cmp_orig(const struct nf_conntrack *ct1,
return 0;
if (test_bit(ATTR_ORIG_L4PROTO, ct1->set) &&
- test_bit(ATTR_ORIG_L4PROTO, ct2->set) &&
- ct1->tuple[__DIR_ORIG].protonum !=
- ct2->tuple[__DIR_ORIG].protonum)
- return 0;
+ test_bit(ATTR_ORIG_L4PROTO, ct2->set)) {
+
+ if (ct1->tuple[__DIR_ORIG].protonum !=
+ ct2->tuple[__DIR_ORIG].protonum)
+ return 0;
+
+ switch(ct1->tuple[__DIR_ORIG].protonum) {
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
+ if (test_bit(ATTR_ICMP_ID, ct1->set) &&
+ test_bit(ATTR_ICMP_ID, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].l4src.icmp.id !=
+ ct2->tuple[__DIR_ORIG].l4src.icmp.id)
+ return 0;
+
+ if (test_bit(ATTR_ICMP_TYPE, ct1->set) &&
+ test_bit(ATTR_ICMP_TYPE, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].l4dst.icmp.type !=
+ ct2->tuple[__DIR_ORIG].l4dst.icmp.type)
+ return 0;
+
+ if (test_bit(ATTR_ICMP_CODE, ct1->set) &&
+ test_bit(ATTR_ICMP_CODE, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].l4dst.icmp.code !=
+ ct2->tuple[__DIR_ORIG].l4dst.icmp.code)
+ return 0;
+ break;
+ default:
+ if (test_bit(ATTR_ORIG_PORT_SRC, ct1->set) &&
+ test_bit(ATTR_ORIG_PORT_SRC, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].l4src.all !=
+ ct2->tuple[__DIR_ORIG].l4src.all)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_PORT_DST, ct1->set) &&
+ test_bit(ATTR_ORIG_PORT_DST, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].l4dst.all !=
+ ct2->tuple[__DIR_ORIG].l4dst.all)
+ return 0;
+ }
+ }
if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
@@ -65,10 +102,47 @@ static int cmp_repl(const struct nf_conntrack *ct1,
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;
+ test_bit(ATTR_REPL_L4PROTO, ct2->set)) {
+
+ if (ct1->tuple[__DIR_REPL].protonum !=
+ ct2->tuple[__DIR_REPL].protonum)
+ return 0;
+
+ switch(ct1->tuple[__DIR_REPL].protonum) {
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
+ if (test_bit(ATTR_ICMP_ID, ct1->set) &&
+ test_bit(ATTR_ICMP_ID, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l4src.icmp.id !=
+ ct2->tuple[__DIR_REPL].l4src.icmp.id)
+ return 0;
+
+ if (test_bit(ATTR_ICMP_TYPE, ct1->set) &&
+ test_bit(ATTR_ICMP_TYPE, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l4dst.icmp.type !=
+ ct2->tuple[__DIR_REPL].l4dst.icmp.type)
+ return 0;
+
+ if (test_bit(ATTR_ICMP_CODE, ct1->set) &&
+ test_bit(ATTR_ICMP_CODE, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l4dst.icmp.code !=
+ ct2->tuple[__DIR_REPL].l4dst.icmp.code)
+ return 0;
+ break;
+ default:
+ if (test_bit(ATTR_REPL_PORT_SRC, ct1->set) &&
+ test_bit(ATTR_REPL_PORT_SRC, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l4src.all !=
+ ct2->tuple[__DIR_REPL].l4src.all)
+ return 0;
+
+ if (test_bit(ATTR_REPL_PORT_DST, ct1->set) &&
+ test_bit(ATTR_REPL_PORT_DST, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l4dst.all !=
+ ct2->tuple[__DIR_REPL].l4dst.all)
+ return 0;
+ }
+ }
if (test_bit(ATTR_REPL_IPV4_SRC, ct1->set) &&
test_bit(ATTR_REPL_IPV4_SRC, ct2->set) &&