From 9064374e7758bc4fa167d1c30ccc751ea588f5db Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 22 Jan 2012 19:41:07 +0100 Subject: expect: add XML support for nfexp_snprintf() Example of the XML output: 192.168.0.2 192.168.1.2 255.255.255.255 255.255.255.255 192.168.0.2 192.168.1.2 0 41739 0 65535 36390 21 ftp 300 0 Signed-off-by: Pablo Neira Ayuso --- include/internal/prototypes.h | 12 ++ src/conntrack/snprintf_xml.c | 54 +++------ src/expect/Makefile.am | 3 +- src/expect/snprintf.c | 3 + src/expect/snprintf_xml.c | 269 ++++++++++++++++++++++++++++++++++++++++++ utils/expect_events.c | 2 +- 6 files changed, 303 insertions(+), 40 deletions(-) create mode 100644 src/expect/snprintf_xml.c 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 @@ * */ -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, ""); - BUFFER_SIZE(ret, size, len, offset); - break; - case __ADDR_DST: - ret = snprintf(buf+offset, len, ""); - 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, ""); - BUFFER_SIZE(ret, size, len, offset); - break; - case __ADDR_DST: - ret = snprintf(buf+offset, len, ""); - BUFFER_SIZE(ret, size, len, offset); - break; - } + ret = snprintf(buf+offset, len, "", 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, ""); 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 + * + * 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: + * + * + * + * + * 192.168.0.2 + * 192.168.1.2 + * + * + * 255.255.255.255 + * 255.255.255.255 + * + * + * 192.168.0.2 + * 192.168.1.2 + * + * + * + * + * 0 + * 41739 + * + * + * 0 + * 65535 + * + * + * 36390 + * 21 + * + * + * + * ftp + * 300 + * 0 + * + * + */ + +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, ""); + BUFFER_SIZE(ret, size, len, offset); + + if (test_bit(ATTR_EXP_HELPER_NAME, exp->set)) { + ret = snprintf(buf+offset, len, + "%s", + exp->helper_name); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_EXP_TIMEOUT, exp->set)) { + ret = snprintf(buf+offset, len, "%u", + exp->timeout); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_EXP_ZONE, exp->set)) { + ret = snprintf(buf+offset, len, "%u", 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, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + } +err_out: + if (exp->flags & NF_CT_EXPECT_PERMANENT) { + ret = snprintf(buf+offset, len, ""); + BUFFER_SIZE(ret, size, len, offset); + } + if (exp->flags & NF_CT_EXPECT_INACTIVE) { + ret = snprintf(buf+offset, len, ""); + BUFFER_SIZE(ret, size, len, offset); + } + if (exp->flags & NF_CT_EXPECT_USERSPACE) { + ret = snprintf(buf+offset, len, ""); + BUFFER_SIZE(ret, size, len, offset); + } + + ret = snprintf(buf+offset, len, ""); + 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, + "", + exp->expected.orig.l3protonum, + __l3proto2str(exp->expected.orig.l3protonum)); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, + "", + exp->expected.orig.protonum, + __proto2str(exp->expected.orig.protonum)); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, ""); + 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, ""); + break; + case NFCT_T_UPDATE: + ret = snprintf(buf, len, ""); + break; + case NFCT_T_DESTROY: + ret = snprintf(buf, len, ""); + break; + default: + ret = snprintf(buf, len, ""); + 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, ""); + 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) -- cgit v1.2.3