summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/internal/prototypes.h12
-rw-r--r--src/conntrack/snprintf_xml.c54
-rw-r--r--src/expect/Makefile.am3
-rw-r--r--src/expect/snprintf.c3
-rw-r--r--src/expect/snprintf_xml.c269
-rw-r--r--utils/expect_events.c2
6 files changed, 303 insertions, 40 deletions
diff --git a/include/internal/prototypes.h b/include/internal/prototypes.h
index 7ca8d35..532c60e 100644
--- a/include/internal/prototypes.h
+++ b/include/internal/prototypes.h
@@ -16,6 +16,17 @@ int __snprintf_proto(char *buf, unsigned int len, const struct __nfct_tuple *tup
int __snprintf_conntrack_default(char *buf, unsigned int len, const struct nf_conntrack *ct, const unsigned int msg_type, const unsigned int flags);
int __snprintf_conntrack_xml(char *buf, unsigned int len, const struct nf_conntrack *ct, const unsigned int msg_type, const unsigned int flags);
+enum __nfct_addr {
+ __ADDR_SRC = 0,
+ __ADDR_DST,
+};
+int __snprintf_addr_xml(char *buf, unsigned int len, const struct __nfct_tuple *tuple, enum __nfct_addr type);
+int __snprintf_proto_xml(char *buf, unsigned int len, const struct __nfct_tuple *tuple, enum __nfct_addr type);
+int __snprintf_localtime_xml(char *buf, unsigned int len, const struct tm *tm);
+
+const char *__proto2str(u_int8_t protonum);
+const char *__l3proto2str(u_int8_t protonum);
+
int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data);
int __setobjopt(struct nf_conntrack *ct, unsigned int option);
@@ -36,5 +47,6 @@ int __expect_callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data);
int __cmp_expect(const struct nf_expect *exp1, const struct nf_expect *exp2, unsigned int flags);
int __snprintf_expect(char *buf, unsigned int len, const struct nf_expect *exp, unsigned int type, unsigned int msg_output, unsigned int flags);
int __snprintf_expect_default(char *buf, unsigned int len, const struct nf_expect *exp, unsigned int msg_type, unsigned int flags);
+int __snprintf_expect_xml(char *buf, unsigned int len, const struct nf_expect *exp, unsigned int msg_type, unsigned int flags);
#endif
diff --git a/src/conntrack/snprintf_xml.c b/src/conntrack/snprintf_xml.c
index 63c814a..756d118 100644
--- a/src/conntrack/snprintf_xml.c
+++ b/src/conntrack/snprintf_xml.c
@@ -53,17 +53,12 @@
* </flow>
*/
-enum {
- __ADDR_SRC = 0,
- __ADDR_DST,
-};
-
-static const char *__proto2str(u_int8_t protonum)
+const char *__proto2str(u_int8_t protonum)
{
return proto2str[protonum] ? proto2str[protonum] : "unknown";
}
-static const char *__l3proto2str(u_int8_t protonum)
+const char *__l3proto2str(u_int8_t protonum)
{
return l3proto2str[protonum] ? l3proto2str[protonum] : "unknown";
}
@@ -97,24 +92,16 @@ static int __snprintf_ipv6_xml(char *buf,
return snprintf(buf, len, "%s", tmp);
}
-static int __snprintf_addr_xml(char *buf,
- unsigned int len,
- const struct __nfct_tuple *tuple,
- unsigned int type)
+int __snprintf_addr_xml(char *buf, unsigned int len,
+ const struct __nfct_tuple *tuple,
+ enum __nfct_addr type)
{
int ret;
unsigned int size = 0, offset = 0;
+ const char *tag = (type == __ADDR_SRC) ? "src" : "dst";
- switch(type) {
- case __ADDR_SRC:
- ret = snprintf(buf, len, "<src>");
- BUFFER_SIZE(ret, size, len, offset);
- break;
- case __ADDR_DST:
- ret = snprintf(buf+offset, len, "<dst>");
- BUFFER_SIZE(ret, size, len, offset);
- break;
- }
+ ret = snprintf(buf, len, "<%s>", tag);
+ BUFFER_SIZE(ret, size, len, offset);
switch (tuple->l3protonum) {
case AF_INET:
@@ -127,24 +114,15 @@ static int __snprintf_addr_xml(char *buf,
break;
}
- switch(type) {
- case __ADDR_SRC:
- ret = snprintf(buf+offset, len, "</src>");
- BUFFER_SIZE(ret, size, len, offset);
- break;
- case __ADDR_DST:
- ret = snprintf(buf+offset, len, "</dst>");
- BUFFER_SIZE(ret, size, len, offset);
- break;
- }
+ ret = snprintf(buf+offset, len, "</%s>", tag);
+ BUFFER_SIZE(ret, size, len, offset);
return size;
}
-static int __snprintf_proto_xml(char *buf,
- unsigned int len,
- const struct __nfct_tuple *tuple,
- unsigned int type)
+int __snprintf_proto_xml(char *buf, unsigned int len,
+ const struct __nfct_tuple *tuple,
+ enum __nfct_addr type)
{
int ret = 0;
unsigned int size = 0, offset = 0;
@@ -261,7 +239,7 @@ __snprintf_deltatime(char *buf, unsigned int len, const struct nf_conntrack *ct)
return size;
}
-static int
+int
__snprintf_localtime_xml(char *buf, unsigned int len, const struct tm *tm)
{
int ret = 0;
@@ -317,10 +295,10 @@ static int __snprintf_tuple_xml(char *buf,
tuple->l3protonum, __l3proto2str(tuple->l3protonum));
BUFFER_SIZE(ret, size, len, offset);
- ret = __snprintf_addr_xml(buf+offset, len, tuple, __DIR_ORIG);
+ ret = __snprintf_addr_xml(buf+offset, len, tuple, __ADDR_SRC);
BUFFER_SIZE(ret, size, len, offset);
- ret = __snprintf_addr_xml(buf+offset, len, tuple, __DIR_REPL);
+ ret = __snprintf_addr_xml(buf+offset, len, tuple, __ADDR_DST);
BUFFER_SIZE(ret, size, len, offset);
ret = snprintf(buf+offset, len, "</layer3>");
diff --git a/src/expect/Makefile.am b/src/expect/Makefile.am
index 977a359..e8a874a 100644
--- a/src/expect/Makefile.am
+++ b/src/expect/Makefile.am
@@ -7,4 +7,5 @@ libnfexpect_la_SOURCES = api.c \
getter.c setter.c \
parse.c build.c \
snprintf.c \
- snprintf_default.c
+ snprintf_default.c \
+ snprintf_xml.c
diff --git a/src/expect/snprintf.c b/src/expect/snprintf.c
index 69ec8b6..3a104b5 100644
--- a/src/expect/snprintf.c
+++ b/src/expect/snprintf.c
@@ -22,6 +22,9 @@ int __snprintf_expect(char *buf,
case NFCT_O_DEFAULT:
size = __snprintf_expect_default(buf, len, exp, type, flags);
break;
+ case NFCT_O_XML:
+ size = __snprintf_expect_xml(buf, len, exp, type, flags);
+ break;
default:
errno = ENOENT;
return -1;
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;
+}
diff --git a/utils/expect_events.c b/utils/expect_events.c
index 8adacb6..03161b9 100644
--- a/utils/expect_events.c
+++ b/utils/expect_events.c
@@ -12,7 +12,7 @@ static int event_cb(enum nf_conntrack_msg_type type,
static int n = 0;
char buf[1024];
- nfexp_snprintf(buf, 1024, exp, type, NFCT_O_DEFAULT, 0);
+ nfexp_snprintf(buf, 1024, exp, type, NFCT_O_XML, 0);
printf("%s\n", buf);
if (++n == 10)