summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conntrack.c43
-rw-r--r--src/libct.c68
2 files changed, 82 insertions, 29 deletions
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 <laforge@netfilter.org>:
+ * Add support for conntrack accounting and conntrack mark
+ *
*/
#include <stdio.h>
#include <getopt.h>
@@ -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);
}