From cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Tue, 18 Sep 2007 11:52:59 +1000 Subject: Allow filtering by name for conntrack status flags --- include/netlink-types.h | 1 + include/netlink/netfilter/ct.h | 2 +- lib/netfilter/ct_obj.c | 16 ++++++++++++---- src/f_ct.c | 23 ++++++++++++++++++++--- src/nf-ct-dump.c | 5 ++++- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/include/netlink-types.h b/include/netlink-types.h index e1145e1..53af6ba 100644 --- a/include/netlink-types.h +++ b/include/netlink-types.h @@ -717,6 +717,7 @@ struct nfnl_ct { union nfnl_ct_protoinfo ct_protoinfo; uint32_t ct_status; + uint32_t ct_status_mask; uint32_t ct_timeout; uint32_t ct_mark; uint32_t ct_use; diff --git a/include/netlink/netfilter/ct.h b/include/netlink/netfilter/ct.h index b0bca94..965b869 100644 --- a/include/netlink/netfilter/ct.h +++ b/include/netlink/netfilter/ct.h @@ -53,7 +53,7 @@ extern char * nfnl_ct_tcp_state2str(uint8_t, char *, size_t); extern int nfnl_ct_str2tcp_state(const char *name); extern void nfnl_ct_set_status(struct nfnl_ct *, uint32_t); -extern int nfnl_ct_test_status(const struct nfnl_ct *); +extern void nfnl_ct_unset_status(struct nfnl_ct *, uint32_t); extern uint32_t nfnl_ct_get_status(const struct nfnl_ct *); extern void nfnl_ct_set_timeout(struct nfnl_ct *, uint32_t); diff --git a/lib/netfilter/ct_obj.c b/lib/netfilter/ct_obj.c index 81baade..0f5a79e 100644 --- a/lib/netfilter/ct_obj.c +++ b/lib/netfilter/ct_obj.c @@ -204,7 +204,6 @@ static int ct_compare(struct nl_object *_a, struct nl_object *_b, diff |= CT_DIFF_VAL(FAMILY, ct_family); diff |= CT_DIFF_VAL(PROTO, ct_proto); diff |= CT_DIFF_VAL(TCP_STATE, ct_protoinfo.tcp.state); - diff |= CT_DIFF_VAL(STATUS, ct_status); diff |= CT_DIFF_VAL(TIMEOUT, ct_timeout); diff |= CT_DIFF_VAL(MARK, ct_mark); diff |= CT_DIFF_VAL(USE, ct_use); @@ -228,6 +227,12 @@ static int ct_compare(struct nl_object *_a, struct nl_object *_b, diff |= CT_DIFF_VAL(REPL_PACKETS, ct_repl.packets); diff |= CT_DIFF_VAL(REPL_BYTES, ct_repl.bytes); + if (flags & LOOSE_FLAG_COMPARISON) + diff |= CT_DIFF(STATUS, (a->ct_status ^ b->ct_status) & + b->ct_status_mask); + else + diff |= CT_DIFF(STATUS, a->ct_status != b->ct_status); + #undef CT_DIFF #undef CT_DIFF_VAL #undef CT_DIFF_ADDR @@ -367,13 +372,16 @@ int nfnl_ct_str2tcp_state(const char *name) void nfnl_ct_set_status(struct nfnl_ct *ct, uint32_t status) { - ct->ct_status = status; + ct->ct_status_mask |= status; + ct->ct_status |= status; ct->ce_mask |= CT_ATTR_STATUS; } -int nfnl_ct_test_status(const struct nfnl_ct *ct) +void nfnl_ct_unset_status(struct nfnl_ct *ct, uint32_t status) { - return !!(ct->ce_mask & CT_ATTR_STATUS); + ct->ct_status_mask |= status; + ct->ct_status &= ~status; + ct->ce_mask |= CT_ATTR_STATUS; } uint32_t nfnl_ct_get_status(const struct nfnl_ct *ct) diff --git a/src/f_ct.c b/src/f_ct.c index e45b393..fbb04fc 100644 --- a/src/f_ct.c +++ b/src/f_ct.c @@ -38,8 +38,11 @@ static void get_filter(struct nfnl_ct *ct, int argc, char **argv, int idx) nfnl_ct_set_tcp_state(ct, state); } } else if (arg_match("status")) { - if (argc > ++idx) - nfnl_ct_set_status(ct, strtoul(argv[idx++], NULL, 0)); + if (argc > ++idx) { + int status = strtoul(argv[idx++], NULL, 0); + nfnl_ct_set_status(ct, status); + nfnl_ct_unset_status(ct, ~status); + } } else if (arg_match("timeout")) { if (argc > ++idx) nfnl_ct_set_timeout(ct, strtoul(argv[idx++], NULL, 0)); @@ -130,7 +133,21 @@ static void get_filter(struct nfnl_ct *ct, int argc, char **argv, int idx) } else if (arg_match("replybytes")) { if (argc > ++idx) nfnl_ct_set_bytes(ct, 1, strtoul(argv[idx++], NULL, 0)); - } else { + } +#define MSTATUS(STR, STATUS) \ + else if (!strcasecmp(argv[idx], STR)) { \ + nfnl_ct_set_status(ct, STATUS); idx++; } +#define MNOSTATUS(STR, STATUS) \ + else if (!strcasecmp(argv[idx], STR)) { \ + nfnl_ct_unset_status(ct, STATUS); idx++; } + + MSTATUS("replied", IPS_SEEN_REPLY) + MNOSTATUS("unreplied", IPS_SEEN_REPLY) + MSTATUS("assured", IPS_ASSURED) + MNOSTATUS("unassured", IPS_ASSURED) +#undef MSTATUS +#undef MNOSTATUS + else { fprintf(stderr, "What is '%s'?\n", argv[idx]); exit(1); } diff --git a/src/nf-ct-dump.c b/src/nf-ct-dump.c index 774c91b..54ee4c7 100644 --- a/src/nf-ct-dump.c +++ b/src/nf-ct-dump.c @@ -13,6 +13,7 @@ #include "utils.h" #include +#include #include "f_ct.c" @@ -28,7 +29,9 @@ static void print_usage(void) " [origpackets PACKETS] [origbytes BYTES]\n" " [replysrc ADDR] [replydst ADDR] [replysrcport PORT] [replydstport PORT]\n" " [replyicmpid ID] [replyicmptype TYPE] [replyicmpcode CODE]\n" - " [replypackets PACKETS] [replybytes BYTES]\n"); + " [replypackets PACKETS] [replybytes BYTES]\n" + " [{ replied | unreplied }] [{ assured | unassured }]\n" + ); exit(1); } -- cgit v0.12