* [PATCH] add nflog_snprintf_xml() to output a log in XML format @ 2010-05-26 12:39 Pablo Neira Ayuso 2010-05-26 13:10 ` Pablo Neira Ayuso 2010-05-26 15:46 ` Jan Engelhardt 0 siblings, 2 replies; 5+ messages in thread From: Pablo Neira Ayuso @ 2010-05-26 12:39 UTC (permalink / raw) To: netfilter-devel; +Cc: eleblond This patch adds a new function to output the packet in XML format. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/libnetfilter_log/libnetfilter_log.h | 12 +++ src/libnetfilter_log.c | 113 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 0 deletions(-) diff --git a/include/libnetfilter_log/libnetfilter_log.h b/include/libnetfilter_log/libnetfilter_log.h index aa0da72..365b19d 100644 --- a/include/libnetfilter_log/libnetfilter_log.h +++ b/include/libnetfilter_log/libnetfilter_log.h @@ -67,4 +67,16 @@ 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_ALL = ~0U, +}; + +extern int nflog_snprintf_xml(char *buf, int 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..6978814 100644 --- a/src/libnetfilter_log.c +++ b/src/libnetfilter_log.c @@ -481,3 +481,116 @@ 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, int 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); + + 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, "x%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; +} ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] add nflog_snprintf_xml() to output a log in XML format 2010-05-26 12:39 [PATCH] add nflog_snprintf_xml() to output a log in XML format Pablo Neira Ayuso @ 2010-05-26 13:10 ` Pablo Neira Ayuso 2010-05-26 15:46 ` Jan Engelhardt 1 sibling, 0 replies; 5+ messages in thread From: Pablo Neira Ayuso @ 2010-05-26 13:10 UTC (permalink / raw) To: netfilter-devel; +Cc: eleblond Pablo Neira Ayuso wrote: > This patch adds a new function to output the packet in XML format. I'm going to extend these to add NFLOG_XML_TIME. This patch will be used by ulogd2's XML output plugin. Consider these patches preliminary work-in-progress. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] add nflog_snprintf_xml() to output a log in XML format 2010-05-26 12:39 [PATCH] add nflog_snprintf_xml() to output a log in XML format Pablo Neira Ayuso 2010-05-26 13:10 ` Pablo Neira Ayuso @ 2010-05-26 15:46 ` Jan Engelhardt 2010-05-27 11:56 ` Pablo Neira Ayuso 1 sibling, 1 reply; 5+ messages in thread From: Jan Engelhardt @ 2010-05-26 15:46 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel, eleblond On Wednesday 2010-05-26 14:39, Pablo Neira Ayuso wrote: >This patch adds a new function to output the packet in XML format. One thing always wondered me.. why is is that logging and queuing are separate? They seem to be both using netlink to transfer a packet in its entirety to userspace. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] add nflog_snprintf_xml() to output a log in XML format 2010-05-26 15:46 ` Jan Engelhardt @ 2010-05-27 11:56 ` Pablo Neira Ayuso 2010-05-27 13:14 ` Pablo Neira Ayuso 0 siblings, 1 reply; 5+ messages in thread From: Pablo Neira Ayuso @ 2010-05-27 11:56 UTC (permalink / raw) To: Jan Engelhardt; +Cc: netfilter-devel, eleblond Jan Engelhardt wrote: > On Wednesday 2010-05-26 14:39, Pablo Neira Ayuso wrote: > >> This patch adds a new function to output the packet in XML format. > > One thing always wondered me.. why is is that logging and queuing are > separate? They seem to be both using netlink to transfer a packet in its > entirety to userspace. Nowadays, the logging infrastructure can be simplified if we use netlink multicast instead. At the time the logging infrastructure was done, netlink only supported 32 multicast groups. Thus, it was not possible to implement it upon multicast. They indeed look quite similar with the minor difference that logging has no verdicts and it contains the string prefix in the messages. Probably Patrick can provide more reasons. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] add nflog_snprintf_xml() to output a log in XML format 2010-05-27 11:56 ` Pablo Neira Ayuso @ 2010-05-27 13:14 ` Pablo Neira Ayuso 0 siblings, 0 replies; 5+ messages in thread From: Pablo Neira Ayuso @ 2010-05-27 13:14 UTC (permalink / raw) To: Jan Engelhardt; +Cc: netfilter-devel, eleblond [-- Attachment #1: Type: text/plain, Size: 38 bytes --] New version including NFLOG_XML_TIME. [-- Attachment #2: xml-log.patch --] [-- Type: text/x-patch, Size: 5869 bytes --] 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> --- include/libnetfilter_log/libnetfilter_log.h | 13 ++ src/libnetfilter_log.c | 155 +++++++++++++++++++++++++++ 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..d4fc0c2 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, "\\x%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; +} ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-05-27 13:14 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-26 12:39 [PATCH] add nflog_snprintf_xml() to output a log in XML format Pablo Neira Ayuso 2010-05-26 13:10 ` Pablo Neira Ayuso 2010-05-26 15:46 ` Jan Engelhardt 2010-05-27 11:56 ` Pablo Neira Ayuso 2010-05-27 13:14 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).