From 4cd4e306286b4b255b7a5fb310a5250bb9d099e0 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 22 Jan 2012 18:27:43 +0100 Subject: conntrackd: fix expectation filtering if ExpectationSync On is used If ExpectationSync On is used, we synchronize no expectations at all due to a problem in the event filtering. This is bug, this patch fixes the problem. Reported-by: Gaurav Sinha Signed-off-by: Pablo Neira Ayuso --- src/filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/filter.c b/src/filter.c index e8515d6..afefbfa 100644 --- a/src/filter.c +++ b/src/filter.c @@ -467,8 +467,9 @@ int exp_filter_find(struct exp_filter *f, const struct nf_expect *exp) { struct exp_filter_item *item; + /* if filtering is not active, accept everything. */ if (f == NULL) - return 0; + return 1; list_for_each_entry(item, &f->list, head) { const char *name = nfexp_get_attr(exp, ATTR_EXP_HELPER_NAME); -- cgit v1.2.3 From b5ca4272d185171971872a9a2ee677cd66c8386b Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 22 Jan 2012 21:21:02 +0100 Subject: conntrack: add expectation support for `-o' option Now you can dump expectations in XML format and display the timestamp. conntrack -L exp -o xml,timestamp 192.168.1.135130.89.148.12255.255.255.255255.255.255.255192.168.1.135130.89.148.120328770655354988121ftp29421220912212012 You have to upgrade libnetfilter_conntrack to access this feature. Signed-off-by: Pablo Neira Ayuso --- src/conntrack.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/src/conntrack.c b/src/conntrack.c index 5364eaa..5d6d067 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -340,12 +340,12 @@ static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = /*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,2,2,2,2,2,2,2}, /*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*HELP*/ {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, -/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0}, +/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0}, /*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, /*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, -/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0}, /*CT_COUNT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*EXP_COUNT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*X_STATS*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, @@ -1064,6 +1064,20 @@ event_sighandler(int s) exit(0); } +static void __attribute__((noreturn)) +exp_event_sighandler(int s) +{ + if (dump_xml_header_done == 0) { + printf("\n"); + fflush(stdout); + } + + fprintf(stderr, "%s v%s (conntrack-tools): ", PROGNAME, VERSION); + fprintf(stderr, "%d expectation events have been shown.\n", counter); + nfct_close(cth); + exit(0); +} + static int event_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -1298,8 +1312,27 @@ static int dump_exp_cb(enum nf_conntrack_msg_type type, void *data) { char buf[1024]; + unsigned int op_type = NFCT_O_DEFAULT; + unsigned int op_flags = 0; + + if (output_mask & _O_XML) { + op_type = NFCT_O_XML; + if (dump_xml_header_done) { + dump_xml_header_done = 0; + printf("\n" + "\n"); + } + } + if (output_mask & _O_TMS) { + if (!(output_mask & _O_XML)) { + struct timeval tv; + gettimeofday(&tv, NULL); + printf("[%-8ld.%-6ld]\t", tv.tv_sec, tv.tv_usec); + } else + op_flags |= NFCT_OF_TIME; + } - nfexp_snprintf(buf,sizeof(buf), exp, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0); + nfexp_snprintf(buf,sizeof(buf), exp, NFCT_T_UNKNOWN, op_type, op_flags); printf("%s\n", buf); counter++; @@ -1310,8 +1343,27 @@ static int event_exp_cb(enum nf_conntrack_msg_type type, struct nf_expect *exp, void *data) { char buf[1024]; + unsigned int op_type = NFCT_O_DEFAULT; + unsigned int op_flags = 0; - nfexp_snprintf(buf,sizeof(buf), exp, type, NFCT_O_DEFAULT, 0); + if (output_mask & _O_XML) { + op_type = NFCT_O_XML; + if (dump_xml_header_done) { + dump_xml_header_done = 0; + printf("\n" + "\n"); + } + } + if (output_mask & _O_TMS) { + if (!(output_mask & _O_XML)) { + struct timeval tv; + gettimeofday(&tv, NULL); + printf("[%-8ld.%-6ld]\t", tv.tv_sec, tv.tv_usec); + } else + op_flags |= NFCT_OF_TIME; + } + + nfexp_snprintf(buf,sizeof(buf), exp, type, op_type, op_flags); printf("%s\n", buf); counter++; @@ -1676,8 +1728,13 @@ int main(int argc, char *argv[]) nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL); res = nfexp_query(cth, NFCT_Q_DUMP, &family); nfct_close(cth); + + if (dump_xml_header_done == 0) { + printf("\n"); + fflush(stdout); + } break; - + case CT_CREATE: if ((options & CT_OPT_ORIG) && !(options & CT_OPT_REPL)) nfct_setobjopt(tmpl.ct, NFCT_SOPT_SETUP_REPLY); @@ -1857,8 +1914,8 @@ int main(int argc, char *argv[]) if (!cth) exit_error(OTHER_PROBLEM, "Can't open handler"); - signal(SIGINT, event_sighandler); - signal(SIGTERM, event_sighandler); + signal(SIGINT, exp_event_sighandler); + signal(SIGTERM, exp_event_sighandler); nfexp_callback_register(cth, NFCT_T_ALL, event_exp_cb, NULL); res = nfexp_catch(cth); nfct_close(cth); -- cgit v1.2.3 From 451dafe6f5e1add75793597ba9bd0e3fddf2d7f9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 22 Jan 2012 22:00:54 +0100 Subject: conntrackd: support `-i exp -x' and `-e exp -x' options This patch allows you to dump the internal and external expectation cache in XML. % conntrackd -i exp -x 192.168.1.135130.89.148.12255.255.255.255255.255.255.255192.168.1.135130.89.148.12090820655355051821ftp Signed-off-by: Pablo Neira Ayuso --- include/conntrackd.h | 2 ++ src/main.c | 4 ++++ src/sync-mode.c | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/include/conntrackd.h b/include/conntrackd.h index 8baa088..9359dfa 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -47,6 +47,8 @@ #define ALL_RESYNC_MASTER 44 /* resync w/all kernel tables */ #define ALL_FLUSH_CACHE 45 /* flush all caches */ #define ALL_COMMIT 46 /* commit all tables */ +#define EXP_DUMP_INT_XML 47 /* dump internal cache in XML */ +#define EXP_DUMP_EXT_XML 48 /* dump external cache in XML */ #define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf" #define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock" diff --git a/src/main.c b/src/main.c index 342ed45..0850a29 100644 --- a/src/main.c +++ b/src/main.c @@ -290,6 +290,10 @@ int main(int argc, char *argv[]) action = CT_DUMP_INT_XML; else if (action == CT_DUMP_EXTERNAL) action = CT_DUMP_EXT_XML; + else if (action == EXP_DUMP_INTERNAL) + action = EXP_DUMP_INT_XML; + else if (action == EXP_DUMP_EXTERNAL) + action = EXP_DUMP_EXT_XML; else { show_usage(argv[0]); fprintf(stderr, "Error: Invalid parameters\n"); diff --git a/src/sync-mode.c b/src/sync-mode.c index 2505631..10fdb9e 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -706,6 +706,18 @@ static int local_handler_sync(int fd, int type, void *data) } local_commit(fd); break; + case EXP_DUMP_INT_XML: + if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) { + STATE(mode)->internal->exp.dump(fd, NFCT_O_XML); + exit(EXIT_SUCCESS); + } + break; + case EXP_DUMP_EXT_XML: + if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) { + STATE_SYNC(external)->exp.dump(fd, NFCT_O_XML); + exit(EXIT_SUCCESS); + } + break; default: if (STATE_SYNC(sync)->local) ret = STATE_SYNC(sync)->local(fd, type, data); -- cgit v1.2.3 From 1e70249a665aa611b3547233952f8f9bb51369f8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 23 Jan 2012 01:23:41 +0100 Subject: conntrack: fix setting fixed-timeout status flag % conntrack -U -u FIXED_TIMEOUT conntrack v1.0.1 (conntrack-tools): Operation failed: Device or resource busy With this patch, you can make indeed make it: % conntrack -U -u FIXED_TIMEOUT [...] conntrack v1.0.1 (conntrack-tools): 8 flow entries have been updated. This patch also adds the corresponding simple QA tests. Signed-off-by: Pablo Neira Ayuso --- qa/testsuite/06update | 8 ++++++++ src/conntrack.c | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 qa/testsuite/06update diff --git a/qa/testsuite/06update b/qa/testsuite/06update new file mode 100644 index 0000000..0408303 --- /dev/null +++ b/qa/testsuite/06update @@ -0,0 +1,8 @@ +# create dummy flow +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state SYN_RECV -u SEEN_REPLY,ASSURED -t 50 ; OK +# find it again using mark +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# set fixed timeout +-U -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 -u FIXED_TIMEOUT; OK +# delete it +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20; OK diff --git a/src/conntrack.c b/src/conntrack.c index 5d6d067..31beba5 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -1245,6 +1245,16 @@ static void copy_mark(struct nf_conntrack *tmp, } } +static void copy_status(struct nf_conntrack *tmp, const struct nf_conntrack *ct) +{ + if (options & CT_OPT_STATUS) { + /* copy existing flags, we only allow setting them. */ + uint32_t status = nfct_get_attr_u32(ct, ATTR_STATUS); + status |= nfct_get_attr_u32(tmp, ATTR_STATUS); + nfct_set_attr_u32(tmp, ATTR_STATUS, status); + } +} + static int update_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -1271,6 +1281,7 @@ static int update_cb(enum nf_conntrack_msg_type type, nfct_copy(tmp, ct, NFCT_CP_ORIG); nfct_copy(tmp, obj, NFCT_CP_META); copy_mark(tmp, ct, &tmpl.mark); + copy_status(tmp, ct); /* do not send NFCT_Q_UPDATE if ct appears unchanged */ if (nfct_cmp(tmp, ct, NFCT_CMP_ALL | NFCT_CMP_MASK)) { -- cgit v1.2.3