]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
add xtables-events
authorPablo Neira Ayuso <pablo@netfilter.org>
Sat, 9 Feb 2013 17:22:13 +0000 (18:22 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 30 Dec 2013 22:50:25 +0000 (23:50 +0100)
Add new program to listen to rule updates:

shell$ xtables-events
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-D INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-D INPUT -m state --state ESTABLISHED -j ACCEPT

You can use `-c' option to display counters.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/Makefile.am
iptables/nft.c
iptables/nft.h
iptables/xtables-events.c [new file with mode: 0644]
iptables/xtables-multi.c
iptables/xtables-multi.h

index 2b1f3fa4cc53f56eda69191ba80942e71b69dbbb..2ed169600a2f6ea0220e8237a3a069a975f3419d 100644 (file)
@@ -31,7 +31,7 @@ if HAVE_LIBNFTABLES
 xtables_multi_SOURCES += xtables-save.c xtables-restore.c \
                         xtables-standalone.c xtables.c nft.c \
                         xtables-config-parser.y xtables-config-syntax.l \
-                        xtables-config.c
+                        xtables-config.c xtables-events.c
 xtables_multi_LDADD   += -lmnl -lnftables
 xtables_multi_CFLAGS  += -DENABLE_NFTABLES
 # yacc and lex generate dirty code
@@ -55,7 +55,8 @@ if ENABLE_IPV6
 v6_sbin_links  = ip6tables ip6tables-restore ip6tables-save
 endif
 if ENABLE_NFTABLES
-x_sbin_links  = xtables xtables-restore xtables-save xtables-config
+x_sbin_links  = xtables xtables-restore xtables-save xtables-config \
+               xtables-events
 endif
 
 iptables-extensions.8: iptables-extensions.8.tmpl ../extensions/matches.man ../extensions/targets.man
index cef1f32e5fe9f124b0fc5760b8312246aaefcb98..097c28b9062748fb37e4e6e562a6e2bfd08c375b 100644 (file)
@@ -1385,13 +1385,22 @@ nft_print_counters(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
        }
 }
 
-static void nft_rule_print_save(struct nft_rule *r, bool counters)
+void
+nft_rule_print_save(struct nft_rule *r, enum nft_rule_print type, bool counters)
 {
        struct nft_rule_expr_iter *iter;
        struct nft_rule_expr *expr;
+       const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);
 
        /* print chain name */
-       printf("-A %s ", nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN));
+       switch(type) {
+       case NFT_RULE_APPEND:
+               printf("-A %s ", chain);
+               break;
+       case NFT_RULE_DEL:
+               printf("-D %s ", chain);
+               break;
+       }
 
        iter = nft_rule_expr_iter_create(r);
        if (iter == NULL)
@@ -1614,7 +1623,7 @@ int nft_rule_save(struct nft_handle *h, const char *table, bool counters)
                if (strcmp(table, rule_table) != 0)
                        goto next;
 
-               nft_rule_print_save(r, counters);
+               nft_rule_print_save(r, NFT_RULE_APPEND, counters);
 
 next:
                r = nft_rule_list_iter_next(iter);
@@ -2714,7 +2723,7 @@ nft_rule_find(struct nft_rule_list *list, const char *chain, const char *table,
                        /* Delete by matching rule case */
                        DEBUGP("comparing with... ");
 #ifdef DEBUG_DEL
-                       nft_rule_print_save(r, 0);
+                       nft_rule_print_save(r, NFT_RULE_APPEND, 0);
 #endif
 
                        nft_rule_to_iptables_command_state(r, &this);
@@ -3378,7 +3387,7 @@ static void
 list_save(const struct iptables_command_state *cs, struct nft_rule *r,
          unsigned int num, unsigned int format)
 {
-       nft_rule_print_save(r, !(format & FMT_NOCOUNTS));
+       nft_rule_print_save(r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS));
 }
 
 static int
index 834fff0d93d4158ac83a76d23f8aa2c59bde6d11..3cffb7771a48a7fdfc9df3bd096137f0b1c64979 100644 (file)
@@ -56,6 +56,13 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *tabl
 int nft_rule_save(struct nft_handle *h, const char *table, bool counters);
 int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table);
 
+enum nft_rule_print {
+       NFT_RULE_APPEND,
+       NFT_RULE_DEL,
+};
+
+void nft_rule_print_save(struct nft_rule *r, enum nft_rule_print type, bool counters);
+
 /*
  * global commit and abort
  */
diff --git a/iptables/xtables-events.c b/iptables/xtables-events.c
new file mode 100644 (file)
index 0000000..2600a25
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <getopt.h>
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nf_tables.h>
+
+#include <libmnl/libmnl.h>
+#include <libnftables/table.h>
+#include <libnftables/chain.h>
+#include <libnftables/rule.h>
+
+#include <include/xtables.h>
+#include "iptables.h" /* for xtables_globals */
+#include "xtables-multi.h"
+#include "nft.h"
+
+static int table_cb(const struct nlmsghdr *nlh, int type)
+{
+       struct nft_table *t;
+       char buf[4096];
+
+       t = nft_table_alloc();
+       if (t == NULL) {
+               perror("OOM");
+               goto err;
+       }
+
+       if (nft_table_nlmsg_parse(nlh, t) < 0) {
+               perror("nft_table_nlmsg_parse");
+               goto err_free;
+       }
+
+       nft_table_snprintf(buf, sizeof(buf), t, NFT_TABLE_O_DEFAULT, 0);
+       /* FIXME: define syntax to represent table events */
+       printf("# [table: %s]\t%s", type == NFT_MSG_NEWTABLE ? "NEW" : "DEL", buf);
+
+err_free:
+       nft_table_free(t);
+err:
+       return MNL_CB_OK;
+}
+
+static bool counters;
+
+static int rule_cb(const struct nlmsghdr *nlh, int type)
+{
+       struct nft_rule *r;
+
+       r = nft_rule_alloc();
+       if (r == NULL) {
+               perror("OOM");
+               goto err;
+       }
+
+       if (nft_rule_nlmsg_parse(nlh, r) < 0) {
+               perror("nft_rule_nlmsg_parse");
+               goto err_free;
+       }
+
+       switch(nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY)) {
+       case AF_INET:
+               printf("-4 ");
+               break;
+       case AF_INET6:
+               printf("-6 ");
+               break;
+       default:
+               break;
+       }
+
+       nft_rule_print_save(r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
+                                                        NFT_RULE_DEL,
+                           counters);
+err_free:
+       nft_rule_free(r);
+err:
+       return MNL_CB_OK;
+}
+
+static int chain_cb(const struct nlmsghdr *nlh, int type)
+{
+       struct nft_chain *t;
+       char buf[4096];
+
+       t = nft_chain_alloc();
+       if (t == NULL) {
+               perror("OOM");
+               goto err;
+       }
+
+       if (nft_chain_nlmsg_parse(nlh, t) < 0) {
+               perror("nft_chain_nlmsg_parse");
+               goto err_free;
+       }
+
+       nft_chain_snprintf(buf, sizeof(buf), t, NFT_CHAIN_O_DEFAULT, 0);
+       /* FIXME: define syntax to represent chain events */
+       printf("# [chain: %s]\t%s", type == NFT_MSG_NEWCHAIN ? "NEW" : "DEL", buf);
+
+err_free:
+       nft_chain_free(t);
+err:
+       return MNL_CB_OK;
+}
+
+static int events_cb(const struct nlmsghdr *nlh, void *data)
+{
+       int ret = MNL_CB_OK;
+       int type = nlh->nlmsg_type & 0xFF;
+
+       switch(type) {
+       case NFT_MSG_NEWTABLE:
+       case NFT_MSG_DELTABLE:
+               ret = table_cb(nlh, type);
+               break;
+       case NFT_MSG_NEWCHAIN:
+       case NFT_MSG_DELCHAIN:
+               ret = chain_cb(nlh, type);
+               break;
+       case NFT_MSG_NEWRULE:
+       case NFT_MSG_DELRULE:
+               ret = rule_cb(nlh, type);
+               break;
+       }
+
+       return ret;
+}
+
+static const struct option options[] = {
+       {.name = "counters", .has_arg = false, .val = 'c'},
+       {NULL},
+};
+
+static void print_usage(const char *name, const char *version)
+{
+       fprintf(stderr, "Usage: %s [-c]\n"
+                       "          [ --counters ]\n", name);
+       exit(EXIT_FAILURE);
+}
+
+int xtables_events_main(int argc, char *argv[])
+{
+       struct mnl_socket *nl;
+       char buf[MNL_SOCKET_BUFFER_SIZE];
+       int ret, c;
+
+       xtables_globals.program_name = "xtables-events";
+       /* XXX xtables_init_all does several things we don't want */
+       c = xtables_init_all(&xtables_globals, NFPROTO_IPV4);
+       if (c < 0) {
+               fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+                               xtables_globals.program_name,
+                               xtables_globals.program_version);
+               exit(1);
+       }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+       init_extensions();
+       init_extensions4();
+#endif
+
+       while ((c = getopt_long(argc, argv, "c", options, NULL)) != -1) {
+               switch (c) {
+               case 'c':
+                       counters = true;
+                       break;
+               }
+       }
+
+       nl = mnl_socket_open(NETLINK_NETFILTER);
+       if (nl == NULL) {
+               perror("mnl_socket_open");
+               exit(EXIT_FAILURE);
+       }
+
+       if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
+               perror("mnl_socket_bind");
+               exit(EXIT_FAILURE);
+       }
+
+       ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+       while (ret > 0) {
+               ret = mnl_cb_run(buf, ret, 0, 0, events_cb, NULL);
+               if (ret <= 0)
+                       break;
+               ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+       }
+       if (ret == -1) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+       mnl_socket_close(nl);
+
+       return EXIT_SUCCESS;
+}
index c17464349b6f424a2c475499d8932635ea790e58..5732ba386d1e4583ea49973c4b2c4ba126440133 100644 (file)
@@ -41,6 +41,7 @@ static const struct subcommand multi_subcommands[] = {
        {"xtables-save",        xtables_save_main},
        {"xtables-restore",     xtables_restore_main},
        {"xtables-config",      xtables_config_main},
+       {"xtables-events",      xtables_events_main},
 #endif
        {NULL},
 };
index be2b3ad86d1ee0ea0677c867f2ab575789af1706..c609ea5b35cd0d6e62f1b28218cd30b4fd38258b 100644 (file)
@@ -6,5 +6,6 @@ extern int xtables_main(int, char **);
 extern int xtables_save_main(int, char **);
 extern int xtables_restore_main(int, char **);
 extern int xtables_config_main(int, char **);
+extern int xtables_events_main(int, char **);
 
 #endif /* _XTABLES_MULTI_H */