From f1d7d696104e8d52d75ec6ae585d7cc8b8090bde Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 22 Feb 2016 10:12:17 +0100 Subject: add JSON output format the original output format looks a bit like JSON, but isn't. The XML output is useful if you deal with XML, but a lot of applications prefer more lightweight formats like YAML/JSON. This adds the JSON output format to libnetfilter_acct, which will subsequently be used by a similar change in the nfacct utility. Signed-off-by: Pablo Neira Ayuso --- include/libnetfilter_acct/libnetfilter_acct.h | 1 + src/libnetfilter_acct.c | 46 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/libnetfilter_acct/libnetfilter_acct.h b/include/libnetfilter_acct/libnetfilter_acct.h index c6ed858..647490f 100644 --- a/include/libnetfilter_acct/libnetfilter_acct.h +++ b/include/libnetfilter_acct/libnetfilter_acct.h @@ -41,6 +41,7 @@ int nfacct_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfacct *nfacct #define NFACCT_SNPRINTF_T_PLAIN 0 #define NFACCT_SNPRINTF_T_XML 1 +#define NFACCT_SNPRINTF_T_JSON 2 int nfacct_snprintf(char *buf, size_t size, struct nfacct *nfacct, uint16_t type, uint16_t flags); diff --git a/src/libnetfilter_acct.c b/src/libnetfilter_acct.c index bb15c68..b0bcf67 100644 --- a/src/libnetfilter_acct.c +++ b/src/libnetfilter_acct.c @@ -297,6 +297,49 @@ nfacct_snprintf_plain(char *buf, size_t rem, struct nfacct *nfacct, return len; } +static int +nfacct_snprintf_json(char *buf, size_t rem, struct nfacct *nfacct, + uint16_t flags) +{ + int ret = 0, offset = 0, len = 0; + + if (flags & NFACCT_SNPRINTF_F_FULL) { + ret = snprintf(buf, rem, + " { \"pkts\" : %"PRIu64", \"bytes\" : %"PRIu64"", + nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS), + nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES)); + SNPRINTF_CHECK(ret, rem, offset, len); + + if (nfacct->flags) { + uint32_t mode; + char *mode_name; + + mode = nfacct_attr_get_u64(nfacct, NFACCT_ATTR_FLAGS); + if (mode & NFACCT_F_QUOTA_PKTS) + mode_name = "packet"; + else if (mode & NFACCT_F_QUOTA_BYTES) + mode_name = "byte"; + else + mode_name = "unknown"; + + ret = snprintf(buf + offset, rem, + ", \"quota\" : %"PRIu64", \"mode\" = \"%s\""\ + ", \"overquota\" = %u", + nfacct_attr_get_u64(nfacct, NFACCT_ATTR_QUOTA), + mode_name, + mode & NFACCT_F_OVERQUOTA ? 1 : 0); + SNPRINTF_CHECK(ret, rem, offset, len); + } + + ret = snprintf(buf + offset, rem, ", \"name\" : \"%s\" }", + nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME)); + } + /* non-F_FULL doesn't seem to make sense in JSON */ + SNPRINTF_CHECK(ret, rem, offset, len); + + return len; +} + #define BUFFER_SIZE(ret, size, rem, offset) \ size += ret; \ if (ret > rem) \ @@ -393,6 +436,9 @@ int nfacct_snprintf(char *buf, size_t size, struct nfacct *nfacct, case NFACCT_SNPRINTF_T_XML: ret = nfacct_snprintf_xml(buf, size, nfacct, flags); break; + case NFACCT_SNPRINTF_T_JSON: + ret = nfacct_snprintf_json(buf, size, nfacct, flags); + break; default: ret = -1; break; -- cgit v1.2.3