summaryrefslogtreecommitdiffstats
path: root/src/nfacct.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-02-22 10:12:36 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-02-29 12:44:34 +0100
commit94c7e32bedfd4751d8f9a346cced9a71e5783513 (patch)
treef085e7c8cd2a0acb58baf062804ed77c4a30e151 /src/nfacct.c
parent86d5283161d3b2908229868318d3d2135c46379b (diff)
Add JSON output formatting to nfacct utility
This is based on the JSON support patch of libnetfilter_acct. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/nfacct.c')
-rw-r--r--src/nfacct.c89
1 files changed, 66 insertions, 23 deletions
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;
}