summaryrefslogtreecommitdiffstats
path: root/src/expect/snprintf_xml.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-01-22 19:41:07 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2012-01-22 21:26:12 +0100
commit9064374e7758bc4fa167d1c30ccc751ea588f5db (patch)
tree8fa4252ed572a12b279469fb0038efe4a4445d88 /src/expect/snprintf_xml.c
parent14b50313556eb7ad86de21438ae5837624db381f (diff)
expect: add XML support for nfexp_snprintf()
Example of the XML output: <flow type="new"> <layer3 protonum="2" protoname="IPv4"> <expected> <src>192.168.0.2</src> <dst>192.168.1.2</dst> </expected> <mask> <src>255.255.255.255</src> <dst>255.255.255.255</dst> </mask> <master> <src>192.168.0.2</src> <dst>192.168.1.2</dst> </master> </layer3> <layer4 protonum="6" protoname="tcp"> <expected> <sport>0</sport> <dport>41739</dport> </expected> <mask> <sport>0</sport> <dport>65535</dport> </mask> <master> <sport>36390</sport> <dport>21</dport> </master> </layer4> <meta> <helper-name>ftp</helper-name> <timeout>300</timeout> <zone>0</zone> </meta> </flow> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/expect/snprintf_xml.c')
-rw-r--r--src/expect/snprintf_xml.c269
1 files changed, 269 insertions, 0 deletions
diff --git a/src/expect/snprintf_xml.c b/src/expect/snprintf_xml.c
new file mode 100644
index 0000000..9f11c59
--- /dev/null
+++ b/src/expect/snprintf_xml.c
@@ -0,0 +1,269 @@
+/*
+ * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "internal/internal.h"
+
+/*
+ * XML output sample:
+ *
+ * <flow type="new">
+ * <layer3 protonum="2" protoname="IPv4">
+ * <expected>
+ * <src>192.168.0.2</src>
+ * <dst>192.168.1.2</dst>
+ * </expected>
+ * <mask>
+ * <src>255.255.255.255</src>
+ * <dst>255.255.255.255</dst>
+ * </mask>
+ * <master>
+ * <src>192.168.0.2</src>
+ * <dst>192.168.1.2</dst>
+ * </master>
+ * </layer3>
+ * <layer4 protonum="6" protoname="tcp">
+ * <expected>
+ * <sport>0</sport>
+ * <dport>41739</dport>
+ * </expected>
+ * <mask>
+ * <sport>0</sport>
+ * <dport>65535</dport>
+ * </mask>
+ * <master>
+ * <sport>36390</sport>
+ * <dport>21</dport>
+ * </master>
+ * </layer4>
+ * <meta>
+ * <helper-name>ftp</helper-name>
+ * <timeout>300</timeout>
+ * <zone>0</zone>
+ * </meta>
+ * </flow>
+ */
+
+static int
+snprintf_expect_meta_xml(char *buf, size_t len,
+ const struct nf_expect *exp, unsigned int flags)
+{
+ int ret;
+ unsigned int size = 0, offset = 0;
+
+ ret = snprintf(buf, len, "<meta>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ if (test_bit(ATTR_EXP_HELPER_NAME, exp->set)) {
+ ret = snprintf(buf+offset, len,
+ "<helper-name>%s</helper-name>",
+ exp->helper_name);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+ if (test_bit(ATTR_EXP_TIMEOUT, exp->set)) {
+ ret = snprintf(buf+offset, len, "<timeout>%u</timeout>",
+ exp->timeout);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+ if (test_bit(ATTR_EXP_ZONE, exp->set)) {
+ ret = snprintf(buf+offset, len, "<zone>%u</zone>", exp->zone);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+ if (flags & NFCT_OF_TIME) {
+ time_t t;
+ struct tm tm;
+
+ t = time(NULL);
+ if (localtime_r(&t, &tm) == NULL)
+ goto err_out;
+
+ ret = snprintf(buf+offset, len, "<when>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_localtime_xml(buf+offset, len, &tm);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</when>");
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+err_out:
+ if (exp->flags & NF_CT_EXPECT_PERMANENT) {
+ ret = snprintf(buf+offset, len, "<permanent/>");
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+ if (exp->flags & NF_CT_EXPECT_INACTIVE) {
+ ret = snprintf(buf+offset, len, "<inactive/>");
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+ if (exp->flags & NF_CT_EXPECT_USERSPACE) {
+ ret = snprintf(buf+offset, len, "<userspace/>");
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ ret = snprintf(buf+offset, len, "</meta>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ return size;
+}
+
+static int
+snprintf_expect_layer3_xml(char *buf, size_t len, const struct nf_expect *exp)
+{
+ int ret;
+ unsigned int size = 0, offset = 0;
+
+ ret = snprintf(buf+offset, len,
+ "<layer3 protonum=\"%d\" protoname=\"%s\">",
+ exp->expected.orig.l3protonum,
+ __l3proto2str(exp->expected.orig.l3protonum));
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "<expected>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_addr_xml(buf+offset, len, &exp->expected.orig,
+ __ADDR_SRC);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_addr_xml(buf+offset, len, &exp->expected.orig,
+ __ADDR_DST);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</expected>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "<mask>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_addr_xml(buf+offset, len, &exp->mask.orig,
+ __ADDR_SRC);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_addr_xml(buf+offset, len, &exp->mask.orig,
+ __ADDR_DST);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</mask>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "<master>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_addr_xml(buf+offset, len, &exp->master.orig,
+ __ADDR_SRC);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_addr_xml(buf+offset, len, &exp->master.orig,
+ __ADDR_DST);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</master>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</layer3>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ return size;
+}
+
+static int
+snprintf_expect_layer4_xml(char *buf, size_t len, const struct nf_expect *exp)
+{
+ int ret;
+ unsigned int size = 0, offset = 0;
+
+ ret = snprintf(buf+offset, len,
+ "<layer4 protonum=\"%d\" protoname=\"%s\">",
+ exp->expected.orig.protonum,
+ __proto2str(exp->expected.orig.protonum));
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "<expected>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_proto_xml(buf+offset, len, &exp->expected.orig,
+ __ADDR_SRC);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_proto_xml(buf+offset, len, &exp->expected.orig,
+ __ADDR_DST);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</expected>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "<mask>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_proto_xml(buf+offset, len, &exp->mask.orig,
+ __ADDR_SRC);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_proto_xml(buf+offset, len, &exp->mask.orig,
+ __ADDR_DST);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</mask>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "<master>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_proto_xml(buf+offset, len, &exp->master.orig,
+ __ADDR_SRC);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = __snprintf_proto_xml(buf+offset, len, &exp->master.orig,
+ __ADDR_DST);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</master>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</layer4>");
+ BUFFER_SIZE(ret, size, len, offset)
+
+ return size;
+}
+
+int __snprintf_expect_xml(char *buf, unsigned int len,
+ const struct nf_expect *exp,
+ unsigned int msg_type, unsigned int flags)
+{
+ int ret = 0, size = 0, offset = 0;
+
+ switch(msg_type) {
+ case NFCT_T_NEW:
+ ret = snprintf(buf, len, "<flow type=\"new\">");
+ break;
+ case NFCT_T_UPDATE:
+ ret = snprintf(buf, len, "<flow type=\"update\">");
+ break;
+ case NFCT_T_DESTROY:
+ ret = snprintf(buf, len, "<flow type=\"destroy\">");
+ break;
+ default:
+ ret = snprintf(buf, len, "<flow>");
+ break;
+ }
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf_expect_layer3_xml(buf+offset, len, exp);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf_expect_layer4_xml(buf+offset, len, exp);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf_expect_meta_xml(buf+offset, len, exp, flags);
+ BUFFER_SIZE(ret, size, len, offset);
+
+ ret = snprintf(buf+offset, len, "</flow>");
+ BUFFER_SIZE(ret, size, len, offset);
+
+ return size;
+}