diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/conntrack/snprintf_xml.c | 54 | ||||
-rw-r--r-- | src/expect/Makefile.am | 3 | ||||
-rw-r--r-- | src/expect/snprintf.c | 3 | ||||
-rw-r--r-- | src/expect/snprintf_xml.c | 269 |
4 files changed, 290 insertions, 39 deletions
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; +} |