From ad65e17d206aaf8b9fed9a32ac3158ced49bee03 Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org" Date: Sat, 16 Apr 2005 13:32:44 +0000 Subject: - add support for new list-conntrack-and-zero-counters flag (-z) - distinguish between real NEW and UPDATE messages in event log - add support to print the conntrack mark --- src/conntrack.c | 43 ++++++++++++++++++++++++------------ src/libct.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 82 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/conntrack.c b/src/conntrack.c index dfb3849..d276c17 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -22,6 +22,10 @@ * for introducing me to advanced firewalling stuff. * * --pablo 13/04/2005 + * + * 2005-04-16 Harald Welte : + * Add support for conntrack accounting and conntrack mark + * */ #include #include @@ -37,7 +41,7 @@ #include "libct_proto.h" #define PROGNAME "conntrack" -#define VERSION "0.12" +#define VERSION "0.13" #if 0 #define DEBUGP printf @@ -94,11 +98,14 @@ enum options { CT_OPT_STATUS_BIT = 7, CT_OPT_STATUS = (1 << CT_OPT_STATUS_BIT), + + CT_OPT_ZERO_BIT = 8, + CT_OPT_ZERO = (1 << CT_OPT_ZERO_BIT), }; -#define NUMBER_OF_OPT 8 +#define NUMBER_OF_OPT 9 static const char optflags[NUMBER_OF_OPT] -= { 's', 'd', 'r', 'q', 'p', 'i', 't', 'u'}; += { 's', 'd', 'r', 'q', 'p', 'i', 't', 'u', 'z'}; static struct option original_opts[] = { {"dump", 1, 0, 'L'}, @@ -115,6 +122,7 @@ static struct option original_opts[] = { {"timeout", 1, 0, 't'}, {"id", 1, 0, 'i'}, {"status", 1, 0, 'u'}, + {"zero", 0, 0, 'z'}, {0, 0, 0, 0} }; @@ -135,13 +143,13 @@ static unsigned int global_option_offset = 0; 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 -i -t -u*/ -/*LIST*/ {'x','x','x','x','x','x','x','x'}, -/*CREATE*/ {'+','+','+','+','+','x','+','+'}, -/*DELETE*/ {' ',' ',' ',' ',' ','+','x','x'}, -/*GET*/ {' ',' ',' ',' ','+','+','x','x'}, -/*FLUSH*/ {'x','x','x','x','x','x','x','x'}, -/*EVENT*/ {'x','x','x','x','x','x','x','x'} + /* -s -d -r -q -p -i -t -u -z */ +/*LIST*/ {'x','x','x','x','x','x','x','x',' '}, +/*CREATE*/ {'+','+','+','+','+','x','+','+','x'}, +/*DELETE*/ {' ',' ',' ',' ',' ','+','x','x','x'}, +/*GET*/ {' ',' ',' ',' ','+','+','x','x','x'}, +/*FLUSH*/ {'x','x','x','x','x','x','x','x','x'}, +/*EVENT*/ {'x','x','x','x','x','x','x','x','x'} }; LIST_HEAD(proto_list); @@ -293,6 +301,7 @@ printf("-p Layer 4 Protocol\n"); printf("-t Timeout\n"); printf("-i Conntrack ID\n"); printf("-u Status\n"); +printf("-z Zero Counters\n"); } int main(int argc, char *argv[]) @@ -314,7 +323,7 @@ int main(int argc, char *argv[]) reply.dst.dir = IP_CT_DIR_REPLY; while ((c = getopt_long(argc, argv, - "L:I:D:G:E:s:d:r:q:p:i:t:u:", opts, NULL)) != -1) { + "L:I:D:G:E:s:d:r:q:p:i:t:u:z", opts, NULL)) != -1) { switch(c) { case 'L': command |= CT_LIST; @@ -396,6 +405,9 @@ int main(int argc, char *argv[]) "flag: %s\n", optarg); break; } + case 'z': + options |= CT_OPT_ZERO; + break; default: if (h && !h->parse(c - h->option_offset, argv, &orig, &reply)) @@ -416,9 +428,12 @@ int main(int argc, char *argv[]) switch(command) { case CT_LIST: printf("list\n"); - if (type == 0) - dump_conntrack_table(); - else + if (type == 0) { + if (options & CT_OPT_ZERO) + dump_conntrack_table(1); + else + dump_conntrack_table(0); + } else dump_expect_list(); break; case CT_CREATE: diff --git a/src/libct.c b/src/libct.c index 3828c0c..47743d8 100644 --- a/src/libct.c +++ b/src/libct.c @@ -64,9 +64,10 @@ static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); struct ip_conntrack_tuple *orig, *reply; + struct cta_counters *ctr; unsigned long *status, *timeout; struct cta_proto *proto; - unsigned long *id; + unsigned long *id, *mark; while (NFA_OK(attr, attrlen)) { switch(attr->nfa_type) { @@ -90,23 +91,34 @@ static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) break; case CTA_STATUS: status = NFA_DATA(attr); - printf("status:%u ", *status); + printf("status=%u ", *status); break; case CTA_PROTOINFO: proto = NFA_DATA(attr); if (proto2str[proto->num_proto]) - printf("%s %d", proto2str[proto->num_proto], proto->num_proto); + printf("%s %d ", proto2str[proto->num_proto], proto->num_proto); else printf("unknown %d ", proto->num_proto); break; case CTA_TIMEOUT: timeout = NFA_DATA(attr); - printf("timeout:%lu ", *timeout); + printf("timeout=%lu ", *timeout); break; /* case CTA_ID: id = NFA_DATA(attr); printf(" id:%lu ", *id); break;*/ + case CTA_MARK: + mark = NFA_DATA(attr); + printf("mark=%lu ", *mark); + break; + case CTA_COUNTERS: + ctr = NFA_DATA(attr); + printf("orig_packets=%lu orig_bytes=%lu, " + "reply_packets=%lu reply_bytes=%lu ", + ctr->orig.packets, ctr->orig.bytes, + ctr->reply.packets, ctr->reply.bytes); + break; } DEBUGP("nfa->nfa_type: %d\n", attr->nfa_type); DEBUGP("nfa->nfa_len: %d\n", attr->nfa_len); @@ -121,12 +133,20 @@ static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) return 0; } -/* FIXME: use event messages better */ -static char *typemsg2str[] = { - "NEW", - "GET", - "DESTROY" -}; +static char *typemsg2str(type, flags) +{ + char *ret = "UNKNOWN"; + + if (type == IPCTNL_MSG_CT_NEW) { + if (flags & NLM_F_CREATE) + ret = "NEW"; + else + ret = "UPDATE"; + } else if (type == IPCTNL_MSG_CT_DELETE) + ret = "DESTROY"; + + return ret; +} static int event_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) @@ -151,14 +171,15 @@ static int event_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, DEBUGP("size:%d\n", nlh->nlmsg_len); - printf("type: [%s] ", typemsg2str[type]); + printf("type: [%s] ", typemsg2str(type, nlh->nlmsg_flags)); while (nlh->nlmsg_len > min_len) { struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh)); int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); struct ip_conntrack_tuple *orig, *reply; - unsigned long *status, *timeout; + struct cta_counters *ctr; + unsigned long *status, *timeout, *mark; struct cta_proto *proto; unsigned long *id; @@ -189,7 +210,7 @@ static int event_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, case CTA_PROTOINFO: proto = NFA_DATA(attr); if (proto2str[proto->num_proto]) - printf("%s %d", proto2str[proto->num_proto], proto->num_proto); + printf("%s %d ", proto2str[proto->num_proto], proto->num_proto); else printf("unknown %d ", proto->num_proto); break; @@ -201,6 +222,17 @@ static int event_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, id = NFA_DATA(attr); printf(" id:%lu ", *id); break;*/ + case CTA_MARK: + mark = NFA_DATA(attr); + printf("mark=%lu ", *mark); + break; + case CTA_COUNTERS: + ctr = NFA_DATA(attr); + printf("orig_packets=%lu orig_bytes=%lu, " + "reply_packets=%lu reply_bytes=%lu ", + ctr->orig.packets, ctr->orig.bytes, + ctr->reply.packets, ctr->reply.bytes); + break; } DEBUGP("nfa->nfa_type: %d\n", attr->nfa_type); DEBUGP("nfa->nfa_len: %d\n", attr->nfa_len); @@ -365,8 +397,9 @@ void get_conntrack(struct ip_conntrack_tuple *tuple, } } -void dump_conntrack_table() +void dump_conntrack_table(int zero) { + int ret; struct ctnl_handle cth; struct ctnl_msg_handler h = { .type = 0, /* Hm... really? */ @@ -380,7 +413,12 @@ void dump_conntrack_table() ctnl_register_handler(&cth, &h); - if (ctnl_list_conntrack(&cth, AF_INET) != -100) { + if (zero) { + ret = ctnl_list_conntrack_zero_counters(&cth, AF_INET); + } else + ret = ctnl_list_conntrack(&cth, AF_INET); + + if (ret != -100) { printf("error list\n"); exit(0); } -- cgit v1.2.3