From 2217eb4c53a54eabbc09e043209181c483e2eace Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 23 Oct 2010 17:35:57 +0200 Subject: conntrack: add timestamp support This patch adds the connection tracking extension that allows conntrack timestamping. This requires a Linux kernel >= 2.6.38. We have now 65 attributes, we need 96 bits to store what attributes are set in the objects. Signed-off-by: Pablo Neira Ayuso --- src/conntrack/snprintf_xml.c | 151 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 127 insertions(+), 24 deletions(-) (limited to 'src/conntrack/snprintf_xml.c') diff --git a/src/conntrack/snprintf_xml.c b/src/conntrack/snprintf_xml.c index 97f6650..12dd686 100644 --- a/src/conntrack/snprintf_xml.c +++ b/src/conntrack/snprintf_xml.c @@ -198,6 +198,97 @@ static int __snprintf_counters_xml(char *buf, return size; } +static int +__snprintf_timestamp_start(char *buf, unsigned int len, + const struct nf_conntrack *ct) +{ + int ret; + unsigned int size = 0, offset = 0; + + ret = snprintf(buf, len, "%llu", + (unsigned long long)ct->timestamp.start); + BUFFER_SIZE(ret, size, len, offset); + + return size; +} + +static int +__snprintf_timestamp_stop(char *buf, unsigned int len, + const struct nf_conntrack *ct) +{ + int ret; + unsigned int size = 0, offset = 0; + + ret = snprintf(buf, len, "%llu", + (unsigned long long)ct->timestamp.stop); + BUFFER_SIZE(ret, size, len, offset); + + return size; +} + +static int +__snprintf_deltatime_now(char *buf, unsigned int len, + const struct nf_conntrack *ct) +{ + int ret; + unsigned int size = 0, offset = 0; + time_t now, delta_time; + + time(&now); + delta_time = now - (time_t)(ct->timestamp.start / NSEC_PER_SEC); + + ret = snprintf(buf+offset, len, "%llu", + (unsigned long long)delta_time); + BUFFER_SIZE(ret, size, len, offset); + + return size; +} + +static int +__snprintf_deltatime(char *buf, unsigned int len, const struct nf_conntrack *ct) +{ + int ret; + unsigned int size = 0, offset = 0; + time_t delta_time = (time_t)((ct->timestamp.stop - + ct->timestamp.start) / NSEC_PER_SEC); + + ret = snprintf(buf+offset, len, "%llu", + (unsigned long long)delta_time); + BUFFER_SIZE(ret, size, len, offset); + + return size; +} + +static int +__snprintf_localtime_xml(char *buf, unsigned int len, const struct tm *tm) +{ + int ret = 0; + unsigned int size = 0, offset = 0; + + ret = snprintf(buf+offset, len, "%d", tm->tm_hour); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%02d", tm->tm_min); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%02d", tm->tm_sec); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%d", tm->tm_wday + 1); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%d", tm->tm_mday); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%d", tm->tm_mon + 1); + BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%d", 1900 + tm->tm_year); + BUFFER_SIZE(ret, size, len, offset); + + return size; +} + static int __snprintf_tuple_xml(char *buf, unsigned int len, const struct nf_conntrack *ct, @@ -298,7 +389,9 @@ int __snprintf_conntrack_xml(char *buf, test_bit(ATTR_ZONE, ct->set) || test_bit(ATTR_USE, ct->set) || test_bit(ATTR_STATUS, ct->set) || - test_bit(ATTR_ID, ct->set)) { + test_bit(ATTR_ID, ct->set) || + test_bit(ATTR_TIMESTAMP_START, ct->set) || + test_bit(ATTR_TIMESTAMP_STOP, ct->set)) { ret = snprintf(buf+offset, len, ""); BUFFER_SIZE(ret, size, len, offset); @@ -378,6 +471,35 @@ int __snprintf_conntrack_xml(char *buf, BUFFER_SIZE(ret, size, len, offset); } + if (flags & NFCT_OF_TIMESTAMP) { + if (test_bit(ATTR_TIMESTAMP_START, ct->set) || + test_bit(ATTR_TIMESTAMP_STOP, ct->set)) { + ret = snprintf(buf+offset, len, ""); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_TIMESTAMP_START, ct->set)) { + ret = __snprintf_timestamp_start(buf+offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_TIMESTAMP_STOP, ct->set)) { + ret = __snprintf_timestamp_stop(buf+offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_TIMESTAMP_START, ct->set) || + test_bit(ATTR_TIMESTAMP_STOP, ct->set)) { + ret = snprintf(buf+offset, len, ""); + BUFFER_SIZE(ret, size, len, offset); + } + } + if (test_bit(ATTR_TIMESTAMP_START, ct->set) && + test_bit(ATTR_TIMESTAMP_STOP, ct->set)) { + ret = __snprintf_deltatime(buf+offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + } else if (test_bit(ATTR_TIMESTAMP_START, ct->set)) { + ret = __snprintf_deltatime_now(buf+offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_TCP_STATE, ct->set) || test_bit(ATTR_SCTP_STATE, ct->set) || test_bit(ATTR_DCCP_STATE, ct->set) || @@ -387,7 +509,9 @@ int __snprintf_conntrack_xml(char *buf, test_bit(ATTR_ZONE, ct->set) || test_bit(ATTR_USE, ct->set) || test_bit(ATTR_STATUS, ct->set) || - test_bit(ATTR_ID, ct->set)) { + test_bit(ATTR_ID, ct->set) || + test_bit(ATTR_TIMESTAMP_START, ct->set) || + test_bit(ATTR_TIMESTAMP_STOP, ct->set)) { ret = snprintf(buf+offset, len, ""); BUFFER_SIZE(ret, size, len, offset); } @@ -403,28 +527,7 @@ int __snprintf_conntrack_xml(char *buf, ret = snprintf(buf+offset, len, ""); BUFFER_SIZE(ret, size, len, offset); - ret = snprintf(buf+offset, len, "%d", tm.tm_hour); - BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "%02d", tm.tm_min); - BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "%02d", tm.tm_sec); - BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "%d", - tm.tm_wday + 1); - BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "%d", tm.tm_mday); - BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "%d", - tm.tm_mon + 1); - BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "%d", - 1900 + tm.tm_year); + ret = __snprintf_localtime_xml(buf+offset, len, &tm); BUFFER_SIZE(ret, size, len, offset); ret = snprintf(buf+offset, len, ""); -- cgit v1.2.3