From c2f6ad83b0087a246447726a121d1694d95fc627 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sun, 13 Apr 2008 01:52:48 +0000 Subject: add initial automated qa testing for the conntrack cli --- qa/testsuite/00create | 16 ++++++++++++++++ qa/testsuite/01delete | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 qa/testsuite/00create create mode 100644 qa/testsuite/01delete (limited to 'qa/testsuite') diff --git a/qa/testsuite/00create b/qa/testsuite/00create new file mode 100644 index 0000000..7af7d37 --- /dev/null +++ b/qa/testsuite/00create @@ -0,0 +1,16 @@ +#missing destination +-I -s 1.1.1.1 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing source +-I -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing protocol +-I -s 1.1.1.1 -d 2.2.2.2 --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing source port +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing timeout +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY ; BAD +# create a conntrack +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# create again +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +# create from reply +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK diff --git a/qa/testsuite/01delete b/qa/testsuite/01delete new file mode 100644 index 0000000..dd3ca8b --- /dev/null +++ b/qa/testsuite/01delete @@ -0,0 +1,2 @@ +# delete +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK -- cgit v1.2.3 From 953bcf62fbd110f63c946905f9642d17b63c50cf Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Wed, 16 Apr 2008 14:54:24 +0000 Subject: o fix NAT filtering via --src-nat and --dst-nat (reported by K.Oledzki) o recover the ID support o show display counters to stderr o enable filtering by status and ID --- ChangeLog | 3 ++ configure.in | 2 +- conntrack.8 | 27 +++++++++------ include/conntrack.h | 12 +++---- qa/test-conntrack.c | 18 +++++++--- qa/testsuite/00create | 4 +++ qa/testsuite/01delete | 8 +++-- qa/testsuite/02filter | 20 +++++++++++ src/conntrack.c | 92 +++++++++++++++++++++++++++++---------------------- 9 files changed, 120 insertions(+), 66 deletions(-) create mode 100644 qa/testsuite/02filter (limited to 'qa/testsuite') diff --git a/ChangeLog b/ChangeLog index f15849b..d6fbe30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,7 +14,10 @@ o simplify parameter-handling code o check for missing source/address IP/ports in creation and get operations o way more flexible conntrack updates and deletions o fix NAT filtering via --src-nat and --dst-nat (reported by K.Oledzki) +o recover the ID support o show display counters to stderr +o enable filtering by status and ID +o update manpage o minor cleanups = conntrackd = diff --git a/configure.in b/configure.in index 46dd7b8..17101e9 100644 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ esac dnl Dependencies LIBNFNETLINK_REQUIRED=0.0.32 -LIBNETFILTER_CONNTRACK_REQUIRED=0.0.91 +LIBNETFILTER_CONNTRACK_REQUIRED=0.0.92 AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes) if test "x$HAVE_PKG_CONFIG" = "x" diff --git a/conntrack.8 b/conntrack.8 index 670770a..9fb9508 100644 --- a/conntrack.8 +++ b/conntrack.8 @@ -73,9 +73,8 @@ Flush the whole given table Atomically zero counters after reading them. This option is only valid in combination with the "-L, --dump" command options. .TP -.BI "-o, --output [extended,xml,timestamp] " -Display output in a certain format. This option is only valid in combination -with the "-L, --dump", "-E, --event" and "-G, --get" command options. +.BI "-o, --output [extended,xml,timestamp,id] " +Display output in a certain format. .TP .BI "-e, --event-mask " "[ALL|NEW|UPDATES|DESTROY][,...]" Set the bitmask of events that are to be generated by the in-kernel ctnetlink @@ -136,10 +135,10 @@ Specify the destination address mask of an expectation. .TP TCP-specific fields: .TP -.BI "--orig-port-src " "PORT" +.BI "--sport, --orig-port-src " "PORT" Source port in original direction .TP -.BI "--orig-port-dst " "PORT" +.BI "--dport, --orig-port-dst " "PORT" Destination port in original direction .TP .BI "--reply-port-src " "PORT" @@ -153,10 +152,10 @@ TCP state .TP UDP-specific fields: .TP -.BI "--orig-port-src " "PORT" +.BI "--sport, --orig-port-src " "PORT" Source port in original direction .TP -.BI "--orig-port-dst " "PORT" +.BI "--dport, --orig-port-dst " "PORT" Destination port in original direction .TP .BI "--reply-port-src " "PORT" @@ -182,22 +181,28 @@ cause an exit code of 1. .SH EXAMPLES .TP .B conntrack \-L -Dump the connection tracking table in /proc/net/ip_conntrack format +Show the connection tracking table in /proc/net/ip_conntrack format .TP .B conntrack \-L -o extended -Dump the connection tracking table in /proc/net/nf_conntrack format +Show the connection tracking table in /proc/net/nf_conntrack format .TP .B conntrack \-L \-o xml -Dump the connection tracking table in XML +Show the connection tracking table in XML .TP .B conntrack \-L -f ipv6 -o extended Only dump IPv6 connections in /proc/net/nf_conntrack format .TP .B conntrack \-L --src-nat -Dump source NAT connections +Show source NAT connections .TP .B conntrack \-E \-o timestamp Show connection events together with the timestamp +.TP +.B conntrack \-D \-s 1.2.3.4 +Delete all flow whose source address is 1.2.3.4 +.TP +.B conntrack \-U \-s 1.2.3.4 \-m 1 +Set connmark to 1 of all the flows whose source address is 1.2.3.4 .SH BUGS Bugs? What's this ;-) .SH SEE ALSO diff --git a/include/conntrack.h b/include/conntrack.h index 9e005d9..2e17475 100644 --- a/include/conntrack.h +++ b/include/conntrack.h @@ -138,14 +138,10 @@ enum options { #define NUMBER_OF_OPT CT_OPT_MAX+1 enum { - _O_XML_BIT = 0, - _O_XML = (1 << _O_XML_BIT), - - _O_EXT_BIT = 1, - _O_EXT = (1 << _O_EXT_BIT), - - _O_TMS_BIT = 2, - _O_TMS = (1 << _O_TMS_BIT), + _O_XML = (1 << 0), + _O_EXT = (1 << 1), + _O_TMS = (1 << 2), + _O_ID = (1 << 3), }; struct ctproto_handler { diff --git a/qa/test-conntrack.c b/qa/test-conntrack.c index c58aa8d..c9097b6 100644 --- a/qa/test-conntrack.c +++ b/qa/test-conntrack.c @@ -21,7 +21,7 @@ int main() { - int ret, ok = 0, bad = 0; + int ret, ok = 0, bad = 0, line; FILE *fp; DIR *d; char buf[1024]; @@ -34,6 +34,8 @@ int main() sprintf(file, "testsuite/%s", dent->d_name); + line = 0; + fp = fopen(file, "r"); if (fp == NULL) { perror("cannot find testsuite file"); @@ -44,15 +46,22 @@ int main() char tmp[1024] = CT_PROG, *res; tmp[strlen(CT_PROG)] = ' '; + line++; + if (buf[0] == '#' || buf[0] == ' ') continue; res = strchr(buf, ';'); + if (!res) { + printf("malformed file %s at line %d\n", + dent->d_name, line); + exit(EXIT_FAILURE); + } *res = '\0'; res+=2; strcpy(tmp + strlen(CT_PROG) + 1, buf); - printf("Executing: %s\n", tmp); + printf("(%d) Executing: %s\n", line, tmp); ret = system(tmp); @@ -75,10 +84,11 @@ int main() printf("^----- BAD\n"); } } + printf("=====\n"); } + fclose(fp); } + closedir(d); fprintf(stdout, "OK: %d BAD: %d\n", ok, bad); - - fclose(fp); } diff --git a/qa/testsuite/00create b/qa/testsuite/00create index 7af7d37..40e2c19 100644 --- a/qa/testsuite/00create +++ b/qa/testsuite/00create @@ -12,5 +12,9 @@ -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK # create again -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +# delete +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK # create from reply -I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# delete reverse +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK diff --git a/qa/testsuite/01delete b/qa/testsuite/01delete index dd3ca8b..3c38ac5 100644 --- a/qa/testsuite/01delete +++ b/qa/testsuite/01delete @@ -1,2 +1,6 @@ -# delete --D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# create dummy +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# delete bad source +-D -s 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# delete by source +-D -s 1.1.1.1 ; OK diff --git a/qa/testsuite/02filter b/qa/testsuite/02filter new file mode 100644 index 0000000..1ae9abd --- /dev/null +++ b/qa/testsuite/02filter @@ -0,0 +1,20 @@ +# create dummy +conntrack -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# filter by source +conntrack -L -s 1.1.1.1 ; OK +# filter by destination +conntrack -L -d 2.2.2.2 ; OK +# filter by protocol +conntrack -L -p tcp ; OK +# filter by status +conntrack -L -u SEEN_REPLY ; OK +# filter by TCP protocol state +conntrack -L -p tcp --state LISTEN ; OK +# update mark of dummy conntrack +conntrack -U -s 1.1.1.1 -m 1 ; OK +# filter by mark +conntrack -L -m 1 ; OK +# filter by layer 3 protocol +conntrack -L -f ipv4 ; OK +# delete dummy +conntrack -D -d 2.2.2.2 ; OK diff --git a/src/conntrack.c b/src/conntrack.c index 2dfb601..9ab4558 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -121,7 +121,7 @@ static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = /* Well, it's better than "Re: Linux vs FreeBSD" */ { /* s d r q p t u z e [ ] { } a m i f n g o c */ -/*CT_LIST*/ {2,2,2,2,2,0,0,2,0,0,0,0,0,0,2,2,2,2,2,2,2}, +/*CT_LIST*/ {2,2,2,2,2,0,2,2,0,0,0,0,0,0,2,0,2,2,2,2,2}, /*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0,2,2,0,2}, /*CT_UPDATE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2}, /*CT_DELETE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2}, @@ -130,7 +130,7 @@ 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}, /*VERSION*/ {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}, -/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,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}, /*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,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}, /*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, @@ -143,7 +143,7 @@ static LIST_HEAD(proto_list); static unsigned int options; #define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | CT_OPT_MARK |\ - CT_OPT_SECMARK) + CT_OPT_SECMARK | CT_OPT_STATUS | CT_OPT_ID) void register_proto(struct ctproto_handler *h) { @@ -328,8 +328,8 @@ static struct parse_parameter { { {"ALL", "NEW", "UPDATES", "DESTROY"}, 4, {~0U, NF_NETLINK_CONNTRACK_NEW, NF_NETLINK_CONNTRACK_UPDATE, NF_NETLINK_CONNTRACK_DESTROY} }, - { {"xml", "extended", "timestamp" }, 3, - { _O_XML, _O_EXT, _O_TMS }, + { {"xml", "extended", "timestamp", "id" }, 4, + { _O_XML, _O_EXT, _O_TMS, _O_ID }, }, }; @@ -603,13 +603,13 @@ static int ignore_nat(const struct nf_conntrack *obj, return 0; } -static int events_counter; +static int counter; static void __attribute__((noreturn)) event_sighandler(int s) { fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); - fprintf(stderr, "%d flow events has been shown.\n", events_counter); + fprintf(stderr, "%d flow events has been shown.\n", counter); nfct_close(cth); exit(0); } @@ -640,19 +640,19 @@ static int event_cb(enum nf_conntrack_msg_type type, printf("[%-8ld.%-6ld]\t", tv.tv_sec, tv.tv_usec); } else op_flags |= NFCT_OF_TIME; - } + } + if (output_mask & _O_ID) + op_flags |= NFCT_OF_ID; nfct_snprintf(buf, 1024, ct, type, op_type, op_flags); printf("%s\n", buf); fflush(stdout); - events_counter++; + counter++; return NFCT_CB_CONTINUE; } -static int list_counter; - static int dump_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -672,17 +672,17 @@ static int dump_cb(enum nf_conntrack_msg_type type, op_type = NFCT_O_XML; if (output_mask & _O_EXT) op_flags = NFCT_OF_SHOW_LAYER3; + if (output_mask & _O_ID) + op_flags |= NFCT_OF_ID; nfct_snprintf(buf, 1024, ct, NFCT_T_UNKNOWN, op_type, op_flags); printf("%s\n", buf); - list_counter++; + counter++; return NFCT_CB_CONTINUE; } -static int delete_counter; - static int delete_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -709,17 +709,17 @@ static int delete_cb(enum nf_conntrack_msg_type type, op_type = NFCT_O_XML; if (output_mask & _O_EXT) op_flags = NFCT_OF_SHOW_LAYER3; + if (output_mask & _O_ID) + op_flags |= NFCT_OF_ID; nfct_snprintf(buf, 1024, ct, NFCT_T_UNKNOWN, op_type, op_flags); printf("%s\n", buf); - delete_counter++; + counter++; return NFCT_CB_CONTINUE; } -static int update_counter; - static int update_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -737,6 +737,10 @@ static int update_cb(enum nf_conntrack_msg_type type, if (ignore_nat(tmp, ct)) return NFCT_CB_CONTINUE; + if (nfct_attr_is_set(obj, ATTR_ID) && nfct_attr_is_set(ct, ATTR_ID) && + nfct_get_attr_u32(obj, ATTR_ID) != nfct_get_attr_u32(ct, ATTR_ID)) + return NFCT_CB_CONTINUE; + if (options & CT_OPT_TUPLE_ORIG && !nfct_cmp(tmp, ct, NFCT_CMP_ORIG)) return NFCT_CB_CONTINUE; if (options & CT_OPT_TUPLE_REPL && !nfct_cmp(tmp, ct, NFCT_CMP_REPL)) @@ -754,11 +758,13 @@ static int update_cb(enum nf_conntrack_msg_type type, op_type = NFCT_O_XML; if (output_mask & _O_EXT) op_flags = NFCT_OF_SHOW_LAYER3; + if (output_mask & _O_ID) + op_flags |= NFCT_OF_ID; nfct_snprintf(buf, 1024, ct, NFCT_T_UNKNOWN, op_type, op_flags); printf("%s\n", buf); - update_counter++; + counter++; return NFCT_CB_CONTINUE; } @@ -801,6 +807,7 @@ static const int opt2type[] = { ['g'] = CT_OPT_DST_NAT, ['m'] = CT_OPT_MARK, ['c'] = CT_OPT_SECMARK, + ['i'] = CT_OPT_ID, }; static const int opt2family_attr[][2] = { @@ -821,6 +828,18 @@ static const int opt2attr[] = { ['q'] = ATTR_REPL_L3PROTO, ['m'] = ATTR_MARK, ['c'] = ATTR_SECMARK, + ['i'] = ATTR_ID, +}; + +static char exit_msg[][64] = { + [CT_LIST_BIT] = "%d flow entries has been shown.\n", + [CT_CREATE_BIT] = "%d flow entries has been created.\n", + [CT_UPDATE_BIT] = "%d flow entries has been updated.\n", + [CT_DELETE_BIT] = "%d flow entries has been deleted.\n", + [CT_GET_BIT] = "%d flow entries has been shown.\n", + [CT_EVENT_BIT] = "%d flow events has been shown.\n", + [EXP_LIST_BIT] = "%d expectations has been shown.\n", + [EXP_DELETE_BIT] = "%d expectations has been shown.\n", }; int main(int argc, char *argv[]) @@ -853,7 +872,7 @@ int main(int argc, char *argv[]) register_icmpv6(); while ((c = getopt_long(argc, argv, "L::I::U::D::G::E::F::hVs:d:r:q:" - "p:t:u:e:a:z[:]:{:}:m:i::f:o:n::" + "p:t:u:e:a:z[:]:{:}:m:i:f:o:n::" "g::c:", opts, NULL)) != -1) { switch(c) { @@ -999,6 +1018,7 @@ int main(int argc, char *argv[]) nat_parse(tmp, 1, obj, opt2type[c]); break; } + case 'i': case 'm': case 'c': options |= opt2type[c]; @@ -1006,9 +1026,10 @@ int main(int argc, char *argv[]) exit_error(PARAMETER_PROBLEM, "-%c requires value", c); - nfct_set_attr_u32(obj, opt2attr[c], atol(optarg)); + nfct_set_attr_u32(obj, + opt2attr[c], + strtoul(optarg, NULL, 0)); break; - case 'i': case 'a': fprintf(stderr, "WARNING: ignoring -%c, " "deprecated option.\n", c); @@ -1084,10 +1105,6 @@ int main(int argc, char *argv[]) res = nfct_query(cth, NFCT_Q_DUMP, &family); nfct_close(cth); - - fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); - fprintf(stderr, "%d flow entries has been shown.\n", - list_counter); break; case EXP_LIST: @@ -1111,10 +1128,9 @@ int main(int argc, char *argv[]) exit_error(OTHER_PROBLEM, "Can't open handler"); res = nfct_query(cth, NFCT_Q_CREATE, obj); + if (res != -1) + counter++; nfct_close(cth); - fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); - fprintf(stderr, "%d flow entry has been created.\n", - res == -1 ? 0 : 1); break; case EXP_CREATE: @@ -1142,10 +1158,6 @@ int main(int argc, char *argv[]) res = nfct_query(cth, NFCT_Q_DUMP, &family); nfct_close(ith); nfct_close(cth); - - fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); - fprintf(stderr, "%d flow entries has been updated.\n", - update_counter); break; case CT_DELETE: @@ -1159,10 +1171,6 @@ int main(int argc, char *argv[]) res = nfct_query(cth, NFCT_Q_DUMP, &family); nfct_close(ith); nfct_close(cth); - - fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); - fprintf(stderr, "%d flow entries has been deleted.\n", - delete_counter); break; case EXP_DELETE: @@ -1184,9 +1192,6 @@ int main(int argc, char *argv[]) nfct_callback_register(cth, NFCT_T_ALL, dump_cb, obj); res = nfct_query(cth, NFCT_Q_GET, obj); nfct_close(cth); - fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); - fprintf(stderr, "%d flow entry has been shown.\n", - res == -1 ? 0 : 1); break; case EXP_GET: @@ -1268,5 +1273,12 @@ int main(int argc, char *argv[]) exit_error(OTHER_PROBLEM, "Operation failed: %s", err2str(errno, command)); - return 0; + if (exit_msg[cmd][0]) { + fprintf(stderr, "%s v%s: ", PROGNAME, VERSION); + fprintf(stderr, exit_msg[cmd], counter); + if (counter == 0 && !(command & (CT_LIST | EXP_LIST))) + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; } -- cgit v1.2.3 From dc727615d7fb0f06dbaeb926ed236e75d47f157a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 1 Jul 2010 13:11:38 +0200 Subject: conntrack: add testsuite for NAT filtering options This patch adds the testsuite for the NAT filtering options. Signed-off-by: Pablo Neira Ayuso --- qa/testsuite/03nat | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 qa/testsuite/03nat (limited to 'qa/testsuite') diff --git a/qa/testsuite/03nat b/qa/testsuite/03nat new file mode 100644 index 0000000..8043af6 --- /dev/null +++ b/qa/testsuite/03nat @@ -0,0 +1,36 @@ +# create dummy +-I -s 1.1.1.1 -d 2.2.2.2 --dst-nat 3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# show +-L --dst-nat ; OK +# show +-L --dst-nat 3.3.3.3 ; OK +# show +-L --src-nat ; OK +# delete +-D -s 1.1.1.1 ; OK +# create dummy again +-I -s 1.1.1.1 -d 2.2.2.2 --src-nat 3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# show +-L --src-nat ; OK +# show +-L --src-nat 3.3.3.3 ; OK +# show +-L --dst-nat ; OK +# show any-nat +-L --any-nat ; OK +# delete +-D -s 1.1.1.1 ; OK +# bad combination +-L --dst-nat --any-nat ; BAD +# bad combination +-L --src-nat --any-nat ; BAD +# bad combination +-L --src-nat --dst-nat --any-nat ; BAD +# create +-I -s 1.1.1.1 -d 2.2.2.2 --dst-nat 3.3.3.3:80 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# show +-L --dst-nat :80 ; OK +# show +-L --any-nat :80 ; OK +# delete +-D -s 1.1.1.1 ; OK -- cgit v1.2.3 From c4413a601ba46e336e624b035a1b69f7aa1a9318 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 1 Jul 2010 16:45:26 +0200 Subject: conntrack: --[src|dst|any]-nat requires IP:PORT as argument This patch restricts the behaviour that we previously introduced in 142606c60808b3ab0496155ac3d086765e6baef3. Signed-off-by: Pablo Neira Ayuso --- qa/testsuite/03nat | 4 ++-- src/conntrack.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'qa/testsuite') diff --git a/qa/testsuite/03nat b/qa/testsuite/03nat index 8043af6..69fbff7 100644 --- a/qa/testsuite/03nat +++ b/qa/testsuite/03nat @@ -29,8 +29,8 @@ # create -I -s 1.1.1.1 -d 2.2.2.2 --dst-nat 3.3.3.3:80 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK # show --L --dst-nat :80 ; OK +-L --dst-nat 3.3.3.3:80 ; OK # show --L --any-nat :80 ; OK +-L --any-nat 3.3.3.3:80 ; OK # delete -D -s 1.1.1.1 ; OK diff --git a/src/conntrack.c b/src/conntrack.c index 82fe844..a5b49dd 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -816,6 +816,8 @@ nat_parse(char *arg, int portok, struct nf_conntrack *obj, int type) if (colon) { uint16_t port; + *colon = '\0'; + if (!portok) exit_error(PARAMETER_PROBLEM, "Need TCP or UDP with port specification"); @@ -841,7 +843,7 @@ nat_parse(char *arg, int portok, struct nf_conntrack *obj, int type) } if (parse_addr(arg, &parse) == AF_UNSPEC) - return; + exit_error(PARAMETER_PROBLEM, "Invalid IP address `%s'", arg); if (type == CT_OPT_SRC_NAT || type == CT_OPT_ANY_NAT) nfct_set_attr_u32(obj, ATTR_SNAT_IPV4, parse.v4); -- cgit v1.2.3 From 0b3f6c9538da47d546a0bc12c8bf5d8dd8fc2fa7 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 1 Jul 2010 16:52:41 +0200 Subject: conntrack: fix `conntrack --[src|dst|any]-nat IP:PORT' if port mismatches This patch fixes the filtering if the IP matches an entry but the PORT does not matches. Without this patch, the entry is shown when it should be not. Signed-off-by: Pablo Neira Ayuso --- qa/testsuite/03nat | 4 ++++ src/conntrack.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'qa/testsuite') diff --git a/qa/testsuite/03nat b/qa/testsuite/03nat index 69fbff7..f94e8ff 100644 --- a/qa/testsuite/03nat +++ b/qa/testsuite/03nat @@ -32,5 +32,9 @@ -L --dst-nat 3.3.3.3:80 ; OK # show -L --any-nat 3.3.3.3:80 ; OK +# show +-L --dst-nat 3.3.3.3:81 ; OK +# show +-L --dst-nat 1.1.1.1:80 ; OK # delete -D -s 1.1.1.1 ; OK diff --git a/src/conntrack.c b/src/conntrack.c index a5b49dd..6fdd1b4 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -890,10 +890,18 @@ filter_nat(const struct nf_conntrack *obj, const struct nf_conntrack *ct) has_srcnat = 1; } if (nfct_attr_is_set(obj, ATTR_SNAT_PORT)) { + int ret = 0; + check_port = 1; port = nfct_get_attr_u16(obj, ATTR_SNAT_PORT); if (nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT) && port == nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST)) + ret = 1; + + /* the address matches but the port does not. */ + if (check_address && has_srcnat && !ret) + has_srcnat = 0; + if (!check_address && ret) has_srcnat = 1; } if (!check_address && !check_port && @@ -912,10 +920,18 @@ filter_nat(const struct nf_conntrack *obj, const struct nf_conntrack *ct) has_dstnat = 1; } if (nfct_attr_is_set(obj, ATTR_DNAT_PORT)) { + int ret = 0; + check_port = 1; port = nfct_get_attr_u16(obj, ATTR_DNAT_PORT); if (nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT) && port == nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC)) + ret = 1; + + /* the address matches but the port does not. */ + if (check_address && has_dstnat && !ret) + has_dstnat = 0; + if (!check_address && ret) has_dstnat = 1; } if (!check_address && !check_port && -- cgit v1.2.3 From 3562ca2e16cac2af2ac6f344ba462b40a05d370f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 5 Jul 2010 17:58:45 +0200 Subject: conntrack: add zone support This patch adds `--zone' to the command line tool. This adds the missing user-space support for Patrick's McHardy iptables CT target. Signed-off-by: Pablo Neira Ayuso --- conntrack.8 | 5 ++++- include/conntrack.h | 2 +- qa/testsuite/04zone | 8 ++++++++ src/conntrack.c | 59 +++++++++++++++++++++++++++++++++-------------------- 4 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 qa/testsuite/04zone (limited to 'qa/testsuite') diff --git a/conntrack.8 b/conntrack.8 index fee3a8c..fb4336f 100644 --- a/conntrack.8 +++ b/conntrack.8 @@ -1,4 +1,4 @@ -.TH CONNTRACK 8 "Apr 11, 2009" "" "" +.TH CONNTRACK 8 "Jul 5, 2010" "" "" .\" Man page written by Harald Welte #define NUMBER_OF_CMD 18 -#define NUMBER_OF_OPT 23 +#define NUMBER_OF_OPT 24 struct ctproto_handler { struct list_head head; diff --git a/qa/testsuite/04zone b/qa/testsuite/04zone new file mode 100644 index 0000000..4ff3d34 --- /dev/null +++ b/qa/testsuite/04zone @@ -0,0 +1,8 @@ +# create dummy +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 --zone 1; OK +# display dummy +-L --zone 1; OK +# display dummy +-L --zone 0; OK +# delete dummy +-D --zone 1; OK diff --git a/src/conntrack.c b/src/conntrack.c index dd129c9..51ea472 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -193,12 +193,16 @@ enum ct_options { CT_OPT_ANY_NAT_BIT = 22, CT_OPT_ANY_NAT = (1 << CT_OPT_ANY_NAT_BIT), + + CT_OPT_ZONE_BIT = 23, + CT_OPT_ZONE = (1 << CT_OPT_ZONE_BIT), }; /* If you add a new option, you have to update NUMBER_OF_OPT in conntrack.h */ /* Update this mask to allow to filter based on new options. */ -#define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | CT_OPT_MARK |\ - CT_OPT_SECMARK | CT_OPT_STATUS | CT_OPT_ID) +#define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | \ + CT_OPT_MARK | CT_OPT_SECMARK | CT_OPT_STATUS | \ + CT_OPT_ID | CT_OPT_ZONE) static const char *optflags[NUMBER_OF_OPT] = { [CT_OPT_ORIG_SRC_BIT] = "src", @@ -224,6 +228,7 @@ static const char *optflags[NUMBER_OF_OPT] = { [CT_OPT_SECMARK_BIT] = "secmark", [CT_OPT_BUFFERSIZE_BIT] = "buffer-size", [CT_OPT_ANY_NAT_BIT] = "any-nat", + [CT_OPT_ZONE_BIT] = "zone", }; static struct option original_opts[] = { @@ -263,12 +268,13 @@ static struct option original_opts[] = { {"output", 1, 0, 'o'}, {"buffer-size", 1, 0, 'b'}, {"any-nat", 2, 0, 'j'}, + {"zone", 1, 0, 'w'}, {0, 0, 0, 0} }; static const char *getopt_str = "L::I::U::D::G::E::F::hVs:d:r:q:" "p:t:u:e:a:z[:]:{:}:m:i:f:o:n::" - "g::c:b:C::Sj::"; + "g::c:b:C::Sj::w:"; /* Table of legal combinations of commands and options. If any of the * given commands make an option legal, that option is legal (applies to @@ -283,25 +289,25 @@ static const char *getopt_str = "L::I::U::D::G::E::F::hVs:d:r:q:" static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = /* Well, it's better than "Re: Linux vs FreeBSD" */ { - /* s d r q p t u z e [ ] { } a m i f n g o c b j*/ -/*CT_LIST*/ {2,2,2,2,2,0,2,2,0,0,0,0,0,0,2,0,2,2,2,2,2,0,2}, -/*CT_CREATE*/ {3,3,3,3,1,1,2,0,0,0,0,0,0,2,2,0,0,2,2,0,0,0,0}, -/*CT_UPDATE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0}, -/*CT_DELETE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0}, -/*CT_GET*/ {3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0}, -/*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, -/*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}, -/*VERSION*/ {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}, -/*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}, -/*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}, -/*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}, -/*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}, -/*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}, -/*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}, -/*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}, -/*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}, -/*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}, + /* s d r q p t u z e [ ] { } a m i f n g o c b j w*/ +/*CT_LIST*/ {2,2,2,2,2,0,2,2,0,0,0,0,0,0,2,0,2,2,2,2,2,0,2,2}, +/*CT_CREATE*/ {3,3,3,3,1,1,2,0,0,0,0,0,0,2,2,0,0,2,2,0,0,0,0,2}, +/*CT_UPDATE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0}, +/*CT_DELETE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,2}, +/*CT_GET*/ {3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0}, +/*CT_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}, +/*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_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}, +/*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}, }; static const int cmd2type[][2] = { @@ -331,6 +337,7 @@ static const int opt2type[] = { ['c'] = CT_OPT_SECMARK, ['i'] = CT_OPT_ID, ['j'] = CT_OPT_ANY_NAT, + ['w'] = CT_OPT_ZONE, }; static const int opt2family_attr[][2] = { @@ -352,6 +359,7 @@ static const int opt2attr[] = { ['m'] = ATTR_MARK, ['c'] = ATTR_SECMARK, ['i'] = ATTR_ID, + ['w'] = ATTR_ZONE, }; static char exit_msg[NUMBER_OF_CMD][64] = { @@ -408,6 +416,7 @@ static const char usage_parameters[] = " -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n" " -t, --timeout timeout\t\tSet timeout\n" " -u, --status status\t\tSet status, eg. ASSURED\n" + " -w, --zone value\t\tSet conntrack zone\n" " -b, --buffer-size\t\tNetlink socket buffer size\n" ; @@ -1429,6 +1438,12 @@ int main(int argc, char *argv[]) nat_parse(tmp, obj, opt2type[c]); break; } + case 'w': + options |= opt2type[c]; + nfct_set_attr_u16(obj, + opt2attr[c], + strtoul(optarg, NULL, 0)); + break; case 'i': case 'm': case 'c': -- cgit v1.2.3 From df2b5109b185be8432e0bea920baef731536a8fd Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 15 Jun 2011 22:29:10 +0200 Subject: testsuite: add tests for --mark option Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- qa/testsuite/02filter | 3 +++ qa/testsuite/05mark | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 qa/testsuite/05mark (limited to 'qa/testsuite') diff --git a/qa/testsuite/02filter b/qa/testsuite/02filter index 1ae9abd..204c4e8 100644 --- a/qa/testsuite/02filter +++ b/qa/testsuite/02filter @@ -16,5 +16,8 @@ conntrack -U -s 1.1.1.1 -m 1 ; OK conntrack -L -m 1 ; OK # filter by layer 3 protocol conntrack -L -f ipv4 ; OK +# filter by mark +conntrack -L --mark 0 ; OK +conntrack -L --mark 0/0xffffffff; OK # delete dummy conntrack -D -d 2.2.2.2 ; OK diff --git a/qa/testsuite/05mark b/qa/testsuite/05mark new file mode 100644 index 0000000..4d99dea --- /dev/null +++ b/qa/testsuite/05mark @@ -0,0 +1,27 @@ +# create with a mark +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 --mark 42 ; OK +# find it again using mark +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42 ; OK +-L --mark 42; OK +# ct already exists +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 --mark 42/0xffffffff ; BAD +# delete by mark +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42/0xffffffff ; OK +# try again after del +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 --mark 417889/0xffffffff ; OK +# delete by mark +-D --mark 417889 ; OK +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 --mark 0xffffffff ; OK +# zap top 16. +-U -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 0/0xffff0000 ; OK +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 0x0000ffff ; OK +-U -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42/0xffff ; OK +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42/0x0000ffff ; OK +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42/42 ; OK +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 2/2 ; OK +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 2/3 ; OK +# OK, but no flow entries should be shown here: +-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 2/0xf ; OK +# BAD, because no updates done (mark is already 42). +-U -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42 ; BAD +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --mark 42 ; OK -- cgit v1.2.3