summaryrefslogtreecommitdiffstats
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
parent71006b474001e697a30719d1ae3e66fefa9f181b (diff)
fix __nfct_l4 structure layout (specifically, ICMP)
fix nfct_cmp(): add port comparison, better ICMP support
-rw-r--r--configure.in2
-rw-r--r--include/internal.h26
-rw-r--r--src/conntrack/compare.c90
3 files changed, 104 insertions, 14 deletions
diff --git a/configure.in b/configure.in
index 0f895d7..a238a3f 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ AC_INIT
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.93)
+AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.94)
AC_PROG_CC
AM_PROG_LIBTOOL
diff --git a/include/internal.h b/include/internal.h
index ae1bd9d..039c64c 100644
--- a/include/internal.h
+++ b/include/internal.h
@@ -62,7 +62,7 @@ struct nfct_handle {
void *data);
};
-union __nfct_l4 {
+union __nfct_l4_src {
/* Add other protocols here. */
u_int16_t all;
struct {
@@ -72,7 +72,6 @@ union __nfct_l4 {
u_int16_t port;
} udp;
struct {
- u_int8_t type, code;
u_int16_t id;
} icmp;
struct {
@@ -80,6 +79,23 @@ union __nfct_l4 {
} sctp;
};
+union __nfct_l4_dst {
+ /* Add other protocols here. */
+ u_int16_t all;
+ struct {
+ u_int16_t port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int8_t type, code;
+ } icmp;
+ struct {
+ u_int16_t port;
+ } sctp;
+};
+
union __nfct_address {
u_int32_t v4;
struct in6_addr v6;
@@ -91,8 +107,8 @@ struct __nfct_tuple {
u_int8_t l3protonum;
u_int8_t protonum;
- union __nfct_l4 l4src;
- union __nfct_l4 l4dst;
+ union __nfct_l4_src l4src;
+ union __nfct_l4_dst l4dst;
struct {
u_int32_t correction_pos;
@@ -123,7 +139,7 @@ struct __nfct_counters {
struct __nfct_nat {
u_int32_t min_ip, max_ip;
- union __nfct_l4 l4min, l4max;
+ union __nfct_l4_src l4min, l4max;
};
struct nf_conntrack {
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) &&