add nfq_snprintf_xml() to output a packet in XML format
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 26 Jan 2010 13:06:35 +0000 (14:06 +0100)
committerr.kubiak <r.kubiak@samsung.com>
Mon, 16 Nov 2015 13:12:05 +0000 (14:12 +0100)
This patch adds a new function to output the packet in XML format.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/libnetfilter_queue/libnetfilter_queue.h
src/libnetfilter_queue.c

index 53bda74..295de66 100644 (file)
@@ -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
index c543055..16a5291 100644 (file)
@@ -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, "<pkt>");
+       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, "<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);
+       }
+
+       ph = nfq_get_msg_packet_hdr(tb);
+       if (ph) {
+               size = snprintf(buf + offset, len,
+                               "<hook>%u</hook><id>%u</id>",
+                               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, "<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 & NFQ_XML_HW) {
+                       size = snprintf(buf + offset, len, "<hw><proto>0x%04x"
+                                                   "</proto></hw>",
+                                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, "<mark>%u</mark>", mark);
+               SNPRINTF_FAILURE(size, len, offset);
+       }
+
+       ifi = nfq_get_indev(tb);
+       if (ifi && (flags & NFQ_XML_DEV)) {
+               size = snprintf(buf + offset, len, "<indev>%u</indev>", ifi);
+               SNPRINTF_FAILURE(size, len, offset);
+       }
+
+       ifi = nfq_get_outdev(tb);
+       if (ifi && (flags & NFQ_XML_DEV)) {
+               size = snprintf(buf + offset, len, "<outdev>%u</outdev>", ifi);
+               SNPRINTF_FAILURE(size, len, offset);
+       }
+
+       ifi = nfq_get_physindev(tb);
+       if (ifi && (flags & NFQ_XML_PHYSDEV)) {
+               size = snprintf(buf + offset, len,
+                               "<physindev>%u</physindev>", ifi);
+               SNPRINTF_FAILURE(size, len, offset);
+       }
+
+       ifi = nfq_get_physoutdev(tb);
+       if (ifi && (flags & NFQ_XML_PHYSDEV)) {
+               size = snprintf(buf + offset, len,
+                               "<physoutdev>%u</physoutdev>", 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, "<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, "</pkt>");
+       SNPRINTF_FAILURE(size, len, offset);
+
+       return size;
+}
+
 /**
  * @}
  */