]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
Allow filtering by name for conntrack status flags
authorPhilip Craig <philipc@snapgear.com>
Tue, 18 Sep 2007 01:52:59 +0000 (11:52 +1000)
committerThomas Graf <tgraf@suug.ch>
Tue, 18 Sep 2007 10:37:49 +0000 (12:37 +0200)
include/netlink-types.h
include/netlink/netfilter/ct.h
lib/netfilter/ct_obj.c
src/f_ct.c
src/nf-ct-dump.c

index e1145e1de3eb1c62ee248a5026b7c533bdfa082e..53af6baef27f88c7190f4b852991e70fe9225149 100644 (file)
@@ -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;
index b0bca94a292916dffa9fb90df30b7d1e1c64d2d8..965b869fe7ea1952145c1d8b2cd3342dc25af9d2 100644 (file)
@@ -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);
index 81baade6ab8717315c4b9220bac13ad4e134c3c6..0f5a79e546fca008b8e81cf2862d9e31eba65bd2 100644 (file)
@@ -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)
index e45b39319a52875403219a90d2f19a9b8010326c..fbb04fc08f527d56d4c8a06bc943f44a3c2381c8 100644 (file)
@@ -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);
                }
index 774c91bb2815f965aaaa6008ea427dee532a9a25..54ee4c7e10b28112eaa36bc0be4c9e643fe840da 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "utils.h"
 #include <netlink/netfilter/ct.h>
+#include <linux/netfilter/nf_conntrack_common.h>
 
 #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);
 }