From 9ab22d56d0ae15e10904c52417d2417e4400ea30 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 26 Jan 2010 14:06:35 +0100 Subject: add nfq_snprintf_xml() to output a packet in XML format This patch adds a new function to output the packet in XML format. Signed-off-by: Pablo Neira Ayuso --- include/libnetfilter_queue/libnetfilter_queue.h | 12 ++ src/libnetfilter_queue.c | 151 ++++++++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/include/libnetfilter_queue/libnetfilter_queue.h b/include/libnetfilter_queue/libnetfilter_queue.h index 53bda74..295de66 100644 --- a/include/libnetfilter_queue/libnetfilter_queue.h +++ b/include/libnetfilter_queue/libnetfilter_queue.h @@ -106,6 +106,18 @@ extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad); /* return -1 if problem, length otherwise */ extern int nfq_get_payload(struct nfq_data *nfad, unsigned char **data); +enum { + NFQ_XML_HW = (1 << 0), + NFQ_XML_MARK = (1 << 1), + NFQ_XML_DEV = (1 << 2), + NFQ_XML_PHYSDEV = (1 << 3), + NFQ_XML_PAYLOAD = (1 << 4), + NFQ_XML_TIME = (1 << 5), + NFQ_XML_ALL = ~0U, +}; + +extern int nfq_snprintf_xml(char *buf, size_t len, struct nfq_data *tb, int flags); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/libnetfilter_queue.c b/src/libnetfilter_queue.c index c543055..16a5291 100644 --- a/src/libnetfilter_queue.c +++ b/src/libnetfilter_queue.c @@ -1012,6 +1012,157 @@ int nfq_get_payload(struct nfq_data *nfad, unsigned char **data) return -1; } +#define SNPRINTF_FAILURE(size, len, offset) \ +do { \ + if (size < 0 || (unsigned int) size >= len) \ + return size; \ + offset += size; \ + len -= size; \ +} while (0) + +int nfq_snprintf_xml(char *buf, size_t len, struct nfq_data *tb, int flags) +{ + struct nfqnl_msg_packet_hdr *ph; + struct nfqnl_msg_packet_hw *hwph; + u_int32_t mark, ifi; + int size, offset = 0, ret; + char *data; + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + + if (flags & NFQ_XML_TIME) { + time_t t; + struct tm tm; + + t = time(NULL); + if (localtime_r(&t, &tm) == NULL) + return -1; + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, + "%d", tm.tm_hour); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, + len, "%02d", tm.tm_min); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, + len, "%02d", tm.tm_sec); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, "%d", + tm.tm_wday + 1); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, "%d", tm.tm_mday); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, "%d", + tm.tm_mon + 1); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, "%d", + 1900 + tm.tm_year); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + } + + ph = nfq_get_msg_packet_hdr(tb); + if (ph) { + size = snprintf(buf + offset, len, + "%u%u", + ph->hook, ntohl(ph->packet_id)); + SNPRINTF_FAILURE(size, len, offset); + + hwph = nfq_get_packet_hw(tb); + if (hwph && (flags & NFQ_XML_HW)) { + int i, hlen = ntohs(hwph->hw_addrlen); + + size = snprintf(buf + offset, len, "0x%04x" + "", + ntohs(ph->hw_protocol)); + SNPRINTF_FAILURE(size, len, offset); + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + + for (i=0; ihw_protocol)); + SNPRINTF_FAILURE(size, len, offset); + } + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + } else if (flags & NFQ_XML_HW) { + size = snprintf(buf + offset, len, "0x%04x" + "", + ntohs(ph->hw_protocol)); + SNPRINTF_FAILURE(size, len, offset); + } + } + + mark = nfq_get_nfmark(tb); + if (mark && (flags & NFQ_XML_MARK)) { + size = snprintf(buf + offset, len, "%u", mark); + SNPRINTF_FAILURE(size, len, offset); + } + + ifi = nfq_get_indev(tb); + if (ifi && (flags & NFQ_XML_DEV)) { + size = snprintf(buf + offset, len, "%u", ifi); + SNPRINTF_FAILURE(size, len, offset); + } + + ifi = nfq_get_outdev(tb); + if (ifi && (flags & NFQ_XML_DEV)) { + size = snprintf(buf + offset, len, "%u", ifi); + SNPRINTF_FAILURE(size, len, offset); + } + + ifi = nfq_get_physindev(tb); + if (ifi && (flags & NFQ_XML_PHYSDEV)) { + size = snprintf(buf + offset, len, + "%u", ifi); + SNPRINTF_FAILURE(size, len, offset); + } + + ifi = nfq_get_physoutdev(tb); + if (ifi && (flags & NFQ_XML_PHYSDEV)) { + size = snprintf(buf + offset, len, + "%u", ifi); + SNPRINTF_FAILURE(size, len, offset); + } + + ret = nfq_get_payload(tb, &data); + if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) { + int i; + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + + for (i=0; i"); + SNPRINTF_FAILURE(size, len, offset); + } + + size = snprintf(buf + offset, len, ""); + SNPRINTF_FAILURE(size, len, offset); + + return size; +} + /** * @} */ -- cgit v1.2.3