summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}