diff options
Diffstat (limited to 'iptables/xtables-monitor.c')
-rw-r--r-- | iptables/xtables-monitor.c | 104 |
1 files changed, 67 insertions, 37 deletions
diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c index eb80bac8..cf2729d8 100644 --- a/iptables/xtables-monitor.c +++ b/iptables/xtables-monitor.c @@ -11,6 +11,7 @@ #define _GNU_SOURCE #include "config.h" +#include <errno.h> #include <stdlib.h> #include <time.h> #include <string.h> @@ -36,11 +37,11 @@ #include "iptables.h" /* for xtables_globals */ #include "xtables-multi.h" #include "nft.h" -#include "nft-arp.h" struct cb_arg { uint32_t nfproto; bool is_event; + struct nft_handle *h; }; static int table_cb(const struct nlmsghdr *nlh, void *data) @@ -91,6 +92,8 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) if (arg->nfproto && arg->nfproto != family) goto err_free; + arg->h->ops = nft_family_ops_lookup(family); + if (arg->is_event) printf(" EVENT: "); switch (family) { @@ -102,11 +105,12 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) printf("-0 "); break; default: + puts(""); goto err_free; } printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE)); - nft_rule_print_save(r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND : + nft_rule_print_save(arg->h, r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND : NFT_RULE_DEL, counters ? 0 : FMT_NOCOUNTS); err_free: @@ -223,12 +227,12 @@ static void trace_print_rule(const struct nftnl_trace *nlt, struct cb_arg *args) exit(EXIT_FAILURE); } - nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, NLM_F_DUMP, 0); + nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, 0, 0); nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family); nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain); nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table); - nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle); + nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, handle); nftnl_rule_nlmsg_build_payload(nlh, r); nftnl_rule_free(r); @@ -244,24 +248,21 @@ static void trace_print_rule(const struct nftnl_trace *nlt, struct cb_arg *args) } portid = mnl_socket_get_portid(nl); - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_send"); - exit(EXIT_FAILURE); - } + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + perror("mnl_socket_send"); + exit(EXIT_FAILURE); + } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - while (ret > 0) { + if (ret > 0) { args->is_event = false; - ret = mnl_cb_run(buf, ret, 0, portid, rule_cb, args); - if (ret <= 0) - break; - ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - } - if (ret == -1) { - perror("error"); - exit(EXIT_FAILURE); - } - mnl_socket_close(nl); + ret = mnl_cb_run(buf, ret, 0, portid, rule_cb, args); + } + if (ret == -1) { + perror("error"); + exit(EXIT_FAILURE); + } + mnl_socket_close(nl); } static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *args) @@ -272,14 +273,14 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg uint32_t mark; char name[IFNAMSIZ]; - printf("PACKET: %d %08x ", args->nfproto, nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID)); + family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY); + printf("PACKET: %d %08x ", family, nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID)); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF)) printf("IN=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_IIF), name)); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF)) printf("OUT=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_OIF), name)); - family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY); nfproto = family; if (nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) { nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO); @@ -304,6 +305,9 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg printf("MACDST=%s ", ether_ntoa((const void *)eh->h_dest)); printf("MACPROTO=%04x ", ntohs(eh->h_proto)); break; + case ARPHRD_LOOPBACK: + printf("LOOPBACK "); + break; default: printf("LL=0x%x ", type); for (i = 0 ; i < len; i++) @@ -335,7 +339,7 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg inet_ntop(AF_INET, &iph->daddr, addrbuf, sizeof(addrbuf)); printf("DST=%s ", addrbuf); - printf("LEN=%d TOS=0x%x TTL=%d ID=%d", ntohs(iph->tot_len), iph->tos, iph->ttl, ntohs(iph->id)); + printf("LEN=%d TOS=0x%x TTL=%d ID=%d ", ntohs(iph->tot_len), iph->tos, iph->ttl, ntohs(iph->id)); if (iph->frag_off & htons(0x8000)) printf("CE "); if (iph->frag_off & htons(IP_DF)) @@ -358,7 +362,7 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg printf("OPT ("); for (i = 0; i < optsize; i++) printf("%02X", op[i]); - printf(")"); + printf(") "); } break; } @@ -432,9 +436,18 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg mark = nftnl_trace_get_u32(nlt, NFTNL_TRACE_MARK); if (mark) printf("MARK=0x%x ", mark); + puts(""); +} + +static void trace_print_hdr(const struct nftnl_trace *nlt) +{ + printf(" TRACE: %d %08x %s:%s", nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY), + nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID), + nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE), + nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN)); } -static void print_verdict(struct nftnl_trace *nlt, uint32_t verdict) +static void print_verdict(const struct nftnl_trace *nlt, uint32_t verdict) { const char *chain; @@ -495,38 +508,41 @@ static int trace_cb(const struct nlmsghdr *nlh, struct cb_arg *arg) arg->nfproto != nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY)) goto err_free; - printf(" TRACE: %d %08x %s:%s", nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY), - nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID), - nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE), - nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN)); - switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) { case NFT_TRACETYPE_RULE: verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT); - printf(":rule:0x%llx:", (unsigned long long)nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE)); - print_verdict(nlt, verdict); - if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) - trace_print_rule(nlt, arg); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) || nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER)) trace_print_packet(nlt, arg); + + if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) { + trace_print_hdr(nlt); + printf(":rule:0x%" PRIx64":", nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE)); + print_verdict(nlt, verdict); + printf(" "); + trace_print_rule(nlt, arg); + } break; case NFT_TRACETYPE_POLICY: + trace_print_hdr(nlt); printf(":policy:"); verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY); print_verdict(nlt, verdict); + puts(""); break; case NFT_TRACETYPE_RETURN: + trace_print_hdr(nlt); printf(":return:"); trace_print_return(nlt); + puts(""); break; } - puts(""); err_free: nftnl_trace_free(nlt); err: + fflush(stdout); return MNL_CB_OK; } @@ -593,7 +609,10 @@ int xtables_monitor_main(int argc, char *argv[]) struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; uint32_t nfgroup = 0; - struct cb_arg cb_arg = {}; + struct nft_handle h = {}; + struct cb_arg cb_arg = { + .h = &h, + }; int ret, c; xtables_globals.program_name = "xtables-monitor"; @@ -605,10 +624,19 @@ int xtables_monitor_main(int argc, char *argv[]) xtables_globals.program_version); exit(1); } -#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) init_extensions(); init_extensions4(); -#endif + init_extensions6(); + init_extensionsa(); + init_extensionsb(); + + if (nft_init(&h, AF_INET)) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, + strerror(errno)); + exit(EXIT_FAILURE); + } opterr = 0; while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) { @@ -675,6 +703,8 @@ int xtables_monitor_main(int argc, char *argv[]) } mnl_socket_close(nl); + xtables_fini(); + return EXIT_SUCCESS; } |