216 lines
5.6 KiB
Diff
216 lines
5.6 KiB
Diff
From 83745c87b294166ff4dbee4a781e7eb5d4f568b8 Mon Sep 17 00:00:00 2001
|
|
From: Harald Welte <laforge@gnumonks.org>
|
|
Date: Tue, 19 May 2015 22:12:06 +0200
|
|
Subject: [PATCH] Add JSON output formatting to nfacct utility
|
|
|
|
This is based on the JSON support patch of libnetfilter_acct.
|
|
---
|
|
nfacct.8 | 2 ++
|
|
src/nfacct.c | 89 ++++++++++++++++++++++++++++++++++++++++++++----------------
|
|
2 files changed, 68 insertions(+), 23 deletions(-)
|
|
|
|
diff --git a/nfacct.8 b/nfacct.8
|
|
index 0c3249c..bf563ae 100644
|
|
--- a/nfacct.8
|
|
+++ b/nfacct.8
|
|
@@ -47,6 +47,8 @@ That atomically obtains and resets the counters.
|
|
.TP
|
|
.BI "xml "
|
|
That displays the output in XML format.
|
|
+.BI "json "
|
|
+That displays the output in JSON format.
|
|
.PP
|
|
.SH SEE ALSO
|
|
.BR iptables (8)
|
|
diff --git a/src/nfacct.c b/src/nfacct.c
|
|
index 2546a6e..d46ee91 100644
|
|
--- a/src/nfacct.c
|
|
+++ b/src/nfacct.c
|
|
@@ -137,13 +137,13 @@ int main(int argc, char *argv[])
|
|
return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
|
|
-static bool xml_header = false;
|
|
+static bool fmt_header = false;
|
|
|
|
static int nfacct_cb(const struct nlmsghdr *nlh, void *data)
|
|
{
|
|
struct nfacct *nfacct;
|
|
char buf[4096];
|
|
- bool *xml = (bool *)data;
|
|
+ int *fmt = (int *)data;
|
|
|
|
nfacct = nfacct_alloc();
|
|
if (nfacct == NULL) {
|
|
@@ -156,17 +156,38 @@ static int nfacct_cb(const struct nlmsghdr *nlh, void *data)
|
|
goto err_free;
|
|
}
|
|
|
|
- if (*xml && !xml_header) {
|
|
- printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
|
- "<nfacct>\n");
|
|
- xml_header = true;
|
|
+ switch (*fmt) {
|
|
+ case NFACCT_SNPRINTF_T_XML:
|
|
+ if (!fmt_header) {
|
|
+ printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
|
+ "<nfacct>\n");
|
|
+ fmt_header = true;
|
|
+ }
|
|
+ break;
|
|
+ case NFACCT_SNPRINTF_T_JSON:
|
|
+ if (!fmt_header) {
|
|
+ printf("{ \"timestamp\" : %lld, \n"
|
|
+ " \"nfacct_counters\" : [\n",
|
|
+ (long long) time(NULL));
|
|
+ fmt_header = true;
|
|
+ } else
|
|
+ printf(",\n");
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
}
|
|
|
|
- nfacct_snprintf(buf, sizeof(buf), nfacct,
|
|
- *xml ? NFACCT_SNPRINTF_T_XML :
|
|
- NFACCT_SNPRINTF_T_PLAIN,
|
|
+ nfacct_snprintf(buf, sizeof(buf), nfacct, *fmt,
|
|
NFACCT_SNPRINTF_F_FULL);
|
|
- printf("%s\n", buf);
|
|
+ printf("%s", buf);
|
|
+ switch (*fmt) {
|
|
+ case NFACCT_SNPRINTF_T_JSON:
|
|
+ /* no newline in JSON case */
|
|
+ break;
|
|
+ default:
|
|
+ putchar('\n');
|
|
+ break;
|
|
+ }
|
|
|
|
err_free:
|
|
nfacct_free(nfacct);
|
|
@@ -174,9 +195,26 @@ err:
|
|
return MNL_CB_OK;
|
|
}
|
|
|
|
+static void _print_footer(int fmt)
|
|
+{
|
|
+ if (fmt_header) {
|
|
+ switch (fmt) {
|
|
+ case NFACCT_SNPRINTF_T_XML:
|
|
+ printf("</nfacct>\n");
|
|
+ break;
|
|
+ case NFACCT_SNPRINTF_T_JSON:
|
|
+ printf("\n] }\n");
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
static int nfacct_cmd_list(int argc, char *argv[])
|
|
{
|
|
- bool zeroctr = false, xml = false;
|
|
+ bool zeroctr = false;
|
|
+ int fmt = NFACCT_SNPRINTF_T_PLAIN;
|
|
struct mnl_socket *nl;
|
|
char buf[MNL_SOCKET_BUFFER_SIZE];
|
|
struct nlmsghdr *nlh;
|
|
@@ -190,9 +228,13 @@ static int nfacct_cmd_list(int argc, char *argv[])
|
|
duparg(argv[i]);
|
|
zeroctr = true;
|
|
} else if (strncmp(argv[i], "xml", strlen(argv[i])) == 0) {
|
|
- if (xml)
|
|
+ if (fmt)
|
|
+ duparg(argv[i]);
|
|
+ fmt = NFACCT_SNPRINTF_T_XML;
|
|
+ } else if (strncmp(argv[i], "json", strlen(argv[i])) == 0) {
|
|
+ if (fmt)
|
|
duparg(argv[i]);
|
|
- xml = true;
|
|
+ fmt = NFACCT_SNPRINTF_T_JSON;
|
|
} else if (strncmp(argv[i], "counters", strlen(argv[i])) == 0) {
|
|
if (mask || value)
|
|
duparg(argv[i]);
|
|
@@ -251,7 +293,7 @@ static int nfacct_cmd_list(int argc, char *argv[])
|
|
|
|
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
|
while (ret > 0) {
|
|
- ret = mnl_cb_run(buf, ret, seq, portid, nfacct_cb, &xml);
|
|
+ ret = mnl_cb_run(buf, ret, seq, portid, nfacct_cb, &fmt);
|
|
if (ret <= 0)
|
|
break;
|
|
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
|
@@ -262,8 +304,7 @@ static int nfacct_cmd_list(int argc, char *argv[])
|
|
}
|
|
mnl_socket_close(nl);
|
|
|
|
- if (xml_header)
|
|
- printf("</nfacct>\n");
|
|
+ _print_footer(fmt);
|
|
|
|
return 0;
|
|
}
|
|
@@ -444,7 +485,8 @@ static int nfacct_cmd_delete(int argc, char *argv[])
|
|
|
|
static int nfacct_cmd_get(int argc, char *argv[])
|
|
{
|
|
- bool zeroctr = false, xml = false;
|
|
+ bool zeroctr = false;
|
|
+ int fmt = NFACCT_SNPRINTF_T_PLAIN;
|
|
struct mnl_socket *nl;
|
|
char buf[MNL_SOCKET_BUFFER_SIZE];
|
|
struct nlmsghdr *nlh;
|
|
@@ -460,7 +502,9 @@ static int nfacct_cmd_get(int argc, char *argv[])
|
|
if (strncmp(argv[i], "reset", strlen(argv[i])) == 0) {
|
|
zeroctr = true;
|
|
} else if (strncmp(argv[i], "xml", strlen(argv[i])) == 0) {
|
|
- xml = true;
|
|
+ fmt = NFACCT_SNPRINTF_T_XML;
|
|
+ } else if (strncmp(argv[i], "json", strlen(argv[i])) == 0) {
|
|
+ fmt = NFACCT_SNPRINTF_T_JSON;
|
|
} else {
|
|
nfacct_perror("unknown argument");
|
|
return -1;
|
|
@@ -503,7 +547,7 @@ static int nfacct_cmd_get(int argc, char *argv[])
|
|
|
|
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
|
while (ret > 0) {
|
|
- ret = mnl_cb_run(buf, ret, seq, portid, nfacct_cb, &xml);
|
|
+ ret = mnl_cb_run(buf, ret, seq, portid, nfacct_cb, &fmt);
|
|
if (ret <= 0)
|
|
break;
|
|
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
|
@@ -514,8 +558,7 @@ static int nfacct_cmd_get(int argc, char *argv[])
|
|
}
|
|
mnl_socket_close(nl);
|
|
|
|
- if (xml_header)
|
|
- printf("</nfacct>\n");
|
|
+ _print_footer(fmt);
|
|
|
|
return 0;
|
|
}
|
|
@@ -660,7 +703,7 @@ static int nfacct_cmd_restore(int argc, char *argv[])
|
|
static int nfacct_cmd_monitor(int argc, char *argv[])
|
|
{
|
|
struct mnl_socket *nl;
|
|
- bool xml = false;
|
|
+ int fmt = NFACCT_SNPRINTF_T_PLAIN;
|
|
char buf[MNL_SOCKET_BUFFER_SIZE];
|
|
int ret, option = NFNLGRP_ACCT_QUOTA;
|
|
|
|
@@ -685,7 +728,7 @@ static int nfacct_cmd_monitor(int argc, char *argv[])
|
|
break;
|
|
}
|
|
|
|
- ret = mnl_cb_run(buf, ret, 0, 0, nfacct_cb, &xml);
|
|
+ ret = mnl_cb_run(buf, ret, 0, 0, nfacct_cb, &fmt);
|
|
if (ret <= 0)
|
|
break;
|
|
}
|
|
--
|
|
2.1.4
|
|
|