summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2010-07-01 14:26:37 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2010-07-01 14:38:30 +0200
commitdfbc66f375e1945e7f65a0478cd25f851efae355 (patch)
tree56af699e061737f49f5170558b34c3df21c8f15b /src
parentdc727615d7fb0f06dbaeb926ed236e75d47f157a (diff)
downloadconntrack-tools-dfbc66f375e1945e7f65a0478cd25f851efae355.tar.gz
conntrack-tools-dfbc66f375e1945e7f65a0478cd25f851efae355.zip
conntrack: re-fix inconsistent display with `--src-nat' and `--dst-nat'
In 142606c60808b3ab0496155ac3d086765e6baef3, I re-introduced the inconsistent behaviour that I described in 85f94171a71880c744f265268f33ad58819caa74. Great. This patch fixes this again. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/conntrack.c76
1 files changed, 30 insertions, 46 deletions
diff --git a/src/conntrack.c b/src/conntrack.c
index b839700..7a06519 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -868,69 +868,53 @@ static unsigned int output_mask;
static int
filter_nat(const struct nf_conntrack *obj, const struct nf_conntrack *ct)
{
+ int check_srcnat = options & CT_OPT_SRC_NAT ? 1 : 0;
+ int check_dstnat = options & CT_OPT_DST_NAT ? 1 : 0;
+ int has_srcnat = 0, has_dstnat = 0;
uint32_t ip;
uint16_t port;
- if (options & CT_OPT_SRC_NAT) {
+ if (options & CT_OPT_ANY_NAT)
+ check_srcnat = check_dstnat = 1;
+
+ if (check_srcnat) {
if (nfct_attr_is_set(obj, ATTR_SNAT_IPV4)) {
ip = nfct_get_attr_u32(obj, ATTR_SNAT_IPV4);
- if (ip != nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST))
- return 1;
+ if (ip == nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST))
+ has_srcnat = 1;
}
if (nfct_attr_is_set(obj, ATTR_SNAT_PORT)) {
port = nfct_get_attr_u16(obj, ATTR_SNAT_PORT);
- if (port != nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST))
- return 1;
+ if (port == nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST))
+ has_srcnat = 1;
}
- if (!nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT) &&
- !nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT))
- return 1;
+ if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT) ||
+ nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT))
+ has_srcnat = 1;
}
- if (options & CT_OPT_DST_NAT) {
+ if (check_dstnat) {
if (nfct_attr_is_set(obj, ATTR_DNAT_IPV4)) {
ip = nfct_get_attr_u32(obj, ATTR_DNAT_IPV4);
- if (ip != nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC))
- return 1;
+ if (ip == nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC))
+ has_dstnat = 1;
}
if (nfct_attr_is_set(obj, ATTR_DNAT_PORT)) {
port = nfct_get_attr_u16(obj, ATTR_DNAT_PORT);
- if (port != nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC))
- return 1;
- }
- if (!nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT) &&
- !nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT))
- return 1;
- }
- if (options & CT_OPT_ANY_NAT) {
- if (nfct_attr_is_set(obj, ATTR_SNAT_IPV4) &&
- nfct_attr_is_set(obj, ATTR_DNAT_IPV4)) {
- uint32_t ip2;
-
- ip = nfct_get_attr_u32(obj, ATTR_SNAT_IPV4);
- ip2 = nfct_get_attr_u32(obj, ATTR_DNAT_IPV4);
- if (ip != nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST) &&
- ip2 != nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC)) {
- return 1;
- }
- }
- if (nfct_attr_is_set(obj, ATTR_SNAT_PORT) &&
- nfct_attr_is_set(obj, ATTR_DNAT_PORT)) {
- uint16_t p1, p2;
-
- p1 = nfct_get_attr_u16(obj, ATTR_SNAT_PORT);
- p2 = nfct_get_attr_u16(obj, ATTR_DNAT_PORT);
- if (p1 != nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST) &&
- p2 != nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC)) {
- return 1;
- }
- }
- if (!nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT) &&
- !nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT) &&
- !nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT) &&
- !nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT)) {
- return 1;
+ if (port == nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC))
+ has_dstnat = 1;
}
+ if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT) ||
+ nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT))
+ has_dstnat = 1;
}
+ if (options & CT_OPT_ANY_NAT)
+ return !(has_srcnat || has_dstnat);
+ else if ((options & CT_OPT_SRC_NAT) && (options & CT_OPT_DST_NAT))
+ return !(has_srcnat && has_dstnat);
+ else if (options & CT_OPT_SRC_NAT)
+ return !has_srcnat;
+ else if (options & CT_OPT_DST_NAT)
+ return !has_dstnat;
return 0;
}