summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2010-05-25 10:44:43 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2010-05-25 11:02:49 +0200
commit4eb7c493dabf47fc559b7a41e583fa656d616e05 (patch)
tree9bf2c7ba3043040c0e5c955c4fac8e1be2526439
parent3b95a2af27bfe87706205f9c4ea7f0f07257a9aa (diff)
add nflog_snprintf_xml() to output a log in XML format
This patch adds a new function to output the packet in XML format. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/libnetfilter_log/libnetfilter_log.h13
-rw-r--r--src/libnetfilter_log.c155
2 files changed, 168 insertions, 0 deletions
diff --git a/include/libnetfilter_log/libnetfilter_log.h b/include/libnetfilter_log/libnetfilter_log.h
index aa0da72..6b0d3b0 100644
--- a/include/libnetfilter_log/libnetfilter_log.h
+++ b/include/libnetfilter_log/libnetfilter_log.h
@@ -67,4 +67,17 @@ extern int nflog_get_gid(struct nflog_data *nfad, u_int32_t *gid);
extern int nflog_get_seq(struct nflog_data *nfad, u_int32_t *seq);
extern int nflog_get_seq_global(struct nflog_data *nfad, u_int32_t *seq);
+enum {
+ NFLOG_XML_PREFIX = (1 << 0),
+ NFLOG_XML_HW = (1 << 1),
+ NFLOG_XML_MARK = (1 << 2),
+ NFLOG_XML_DEV = (1 << 3),
+ NFLOG_XML_PHYSDEV = (1 << 4),
+ NFLOG_XML_PAYLOAD = (1 << 5),
+ NFLOG_XML_TIME = (1 << 6),
+ NFLOG_XML_ALL = ~0U,
+};
+
+extern int nflog_snprintf_xml(char *buf, size_t len, struct nflog_data *tb, int flags);
+
#endif /* __LIBNETFILTER_LOG_H */
diff --git a/src/libnetfilter_log.c b/src/libnetfilter_log.c
index ebb8a19..acc1edf 100644
--- a/src/libnetfilter_log.c
+++ b/src/libnetfilter_log.c
@@ -481,3 +481,158 @@ int nflog_get_seq_global(struct nflog_data *nfad, u_int32_t *seq)
*seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ_GLOBAL, u_int32_t));
return 0;
}
+
+#define SNPRINTF_FAILURE(size, len, offset) \
+do { \
+ if (size < 0 || (unsigned int) size >= len) \
+ return size; \
+ offset += size; \
+ len -= size; \
+} while (0)
+
+int nflog_snprintf_xml(char *buf, size_t len, struct nflog_data *tb, int flags)
+{
+ struct nfulnl_msg_packet_hdr *ph;
+ struct nfulnl_msg_packet_hw *hwph;
+ u_int32_t mark, ifi;
+ int size, offset = 0, ret;
+ char *data;
+
+ size = snprintf(buf + offset, len, "<log>");
+ SNPRINTF_FAILURE(size, len, offset);
+
+ if (flags & NFLOG_XML_TIME) {
+ time_t t;
+ struct tm tm;
+
+ t = time(NULL);
+ if (localtime_r(&t, &tm) == NULL)
+ return -1;
+
+ size = snprintf(buf + offset, len, "<when>");
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len,
+ "<hour>%d</hour>", tm.tm_hour);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset,
+ len, "<min>%02d</min>", tm.tm_min);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset,
+ len, "<sec>%02d</sec>", tm.tm_sec);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len, "<wday>%d</wday>",
+ tm.tm_wday + 1);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len, "<day>%d</day>", tm.tm_mday);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len, "<month>%d</month>",
+ tm.tm_mon + 1);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len, "<year>%d</year>",
+ 1900 + tm.tm_year);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len, "</when>");
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ data = nflog_get_prefix(tb);
+ if (data && (flags & NFLOG_XML_PREFIX)) {
+ size = snprintf(buf + offset, len, "<prefix>%s</prefix>", data);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ ph = nflog_get_msg_packet_hdr(tb);
+ if (ph) {
+ size = snprintf(buf + offset, len, "<hook>%u</hook>", ph->hook);
+ SNPRINTF_FAILURE(size, len, offset);
+
+ hwph = nflog_get_packet_hw(tb);
+ if (hwph && (flags & NFLOG_XML_HW)) {
+ int i, hlen = ntohs(hwph->hw_addrlen);
+
+ size = snprintf(buf + offset, len, "<hw><proto>0x%04x"
+ "</proto>",
+ ntohs(ph->hw_protocol));
+ SNPRINTF_FAILURE(size, len, offset);
+
+ size = snprintf(buf + offset, len, "<src>");
+ SNPRINTF_FAILURE(size, len, offset);
+
+ for (i=0; i<hlen-1; i++) {
+ size = snprintf(buf + offset, len, "%02x:",
+ ntohs(ph->hw_protocol));
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ size = snprintf(buf + offset, len, "</src></hw>");
+ SNPRINTF_FAILURE(size, len, offset);
+ } else if (flags & NFLOG_XML_HW) {
+ size = snprintf(buf + offset, len, "<hw><proto>0x%04x"
+ "</proto></hw>",
+ ntohs(ph->hw_protocol));
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+ }
+
+ mark = nflog_get_nfmark(tb);
+ if (mark && (flags & NFLOG_XML_MARK)) {
+ size = snprintf(buf + offset, len, "<mark>%u</mark>", mark);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ ifi = nflog_get_indev(tb);
+ if (ifi && (flags & NFLOG_XML_DEV)) {
+ size = snprintf(buf + offset, len, "<indev>%u</indev>", ifi);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ ifi = nflog_get_outdev(tb);
+ if (ifi && (flags & NFLOG_XML_DEV)) {
+ size = snprintf(buf + offset, len, "<outdev>%u</outdev>", ifi);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ ifi = nflog_get_physindev(tb);
+ if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
+ size = snprintf(buf + offset, len,
+ "<physindev>%u</physindev>", ifi);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ ifi = nflog_get_physoutdev(tb);
+ if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
+ size = snprintf(buf + offset, len,
+ "<physoutdev>%u</physoutdev>", ifi);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ ret = nflog_get_payload(tb, &data);
+ if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) {
+ int i;
+
+ size = snprintf(buf + offset, len, "<payload>");
+ SNPRINTF_FAILURE(size, len, offset);
+
+ for (i=0; i<ret; i++) {
+ size = snprintf(buf + offset, len, "%02x",
+ data[i] & 0xff);
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ size = snprintf(buf + offset, len, "</payload>");
+ SNPRINTF_FAILURE(size, len, offset);
+ }
+
+ size = snprintf(buf + offset, len, "</log>");
+ SNPRINTF_FAILURE(size, len, offset);
+
+ return size;
+}