From d894e26211f38db37015850afab6b7331edeecdb Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org" Date: Sun, 1 May 2005 23:19:42 +0000 Subject: o Created changelog file o Deleted libctnetlink.h and libnfnetlink.h from the include/ dir. o Added support for version (-V) and help (-h) o Added event mask based support o Added GPLv2 headers o Use fprintf instead of printf o Defined print_tuple and print_proto output interfaces o ctnl_[get|del]_conntrack handles return value from kernel via msgerr o Added support for conntrack table flushing o Added test case file (test.sh) o Improve dump output o Autoconf stuff for conntrack + some pablo's modifications. o Fixed packet counters formatting (use %llu instead of %lu) --- src/libct.c | 174 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 109 insertions(+), 65 deletions(-) (limited to 'src/libct.c') diff --git a/src/libct.c b/src/libct.c index 143901b..d44b920 100644 --- a/src/libct.c +++ b/src/libct.c @@ -1,3 +1,11 @@ +/* + * (C) 2005 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ #include #include #include @@ -16,9 +24,18 @@ #define DEBUGP #endif +extern char *lib_dir; extern struct list_head proto_list; extern char *proto2str[]; +static void print_status(unsigned int status) +{ + if (status & IPS_ASSURED) + fprintf(stdout, "[ASSURED] "); + if (!(status & IPS_SEEN_REPLY)) + fprintf(stdout, "[UNREPLIED] "); +} + static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) { struct nfgenmsg *nfmsg; @@ -52,49 +69,48 @@ static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) switch(attr->nfa_type) { case CTA_ORIG: orig = NFA_DATA(attr); - printf("src=%u.%u.%u.%u dst=%u.%u.%u.%u ", + fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(orig->src.ip), NIPQUAD(orig->dst.ip)); h = findproto(proto2str[orig->dst.protonum]); - if (h && h->print) - h->print(orig); + if (h && h->print_tuple) + h->print_tuple(orig); break; case CTA_RPLY: reply = NFA_DATA(attr); - printf("src=%u.%u.%u.%u dst=%u.%u.%u.%u ", + fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(reply->src.ip), NIPQUAD(reply->dst.ip)); h = findproto(proto2str[reply->dst.protonum]); - if (h && h->print) - h->print(reply); + if (h && h->print_tuple) + h->print_tuple(reply); break; case CTA_STATUS: status = NFA_DATA(attr); - printf("status=%u ", *status); + print_status(*status); break; case CTA_PROTOINFO: proto = NFA_DATA(attr); - if (proto2str[proto->num_proto]) - printf("%s %d ", proto2str[proto->num_proto], proto->num_proto); - else - printf("unknown %d ", proto->num_proto); + if (proto2str[proto->num_proto]) { + fprintf(stdout, "%s %d ", proto2str[proto->num_proto], proto->num_proto); + h = findproto(proto2str[proto->num_proto]); + if (h && h->print_proto) + h->print_proto(&proto->proto); + } else + fprintf(stdout, "unknown %d ", proto->num_proto); break; case CTA_TIMEOUT: timeout = NFA_DATA(attr); - printf("timeout=%lu ", *timeout); + fprintf(stdout, "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); + fprintf(stdout, "mark=%lu ", *mark); break; case CTA_COUNTERS: ctr = NFA_DATA(attr); - printf("orig_packets=%lu orig_bytes=%lu, " - "reply_packets=%lu reply_bytes=%lu ", + fprintf(stdout, "orig_packets=%llu orig_bytes=%llu, " + "reply_packets=%llu reply_bytes=%llu ", ctr->orig.packets, ctr->orig.bytes, ctr->reply.packets, ctr->reply.bytes); break; @@ -103,7 +119,7 @@ static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg) DEBUGP("nfa->nfa_len: %d\n", attr->nfa_len); attr = NFA_NEXT(attr, attrlen); } - printf("\n"); + fprintf(stdout, "\n"); return 0; } @@ -154,55 +170,54 @@ static int event_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, DEBUGP("size:%d\n", nlh->nlmsg_len); - printf("type: [%s] ", typemsg2str(type, nlh->nlmsg_flags)); + fprintf(stdout, "[%s] ", typemsg2str(type, nlh->nlmsg_flags)); while (NFA_OK(attr, attrlen)) { switch(attr->nfa_type) { case CTA_ORIG: orig = NFA_DATA(attr); - printf("src=%u.%u.%u.%u dst=%u.%u.%u.%u ", + fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(orig->src.ip), NIPQUAD(orig->dst.ip)); h = findproto(proto2str[orig->dst.protonum]); - if (h && h->print) - h->print(orig); + if (h && h->print_tuple) + h->print_tuple(orig); break; case CTA_RPLY: reply = NFA_DATA(attr); - printf("src=%u.%u.%u.%u dst=%u.%u.%u.%u ", + fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(reply->src.ip), NIPQUAD(reply->dst.ip)); h = findproto(proto2str[reply->dst.protonum]); - if (h && h->print) - h->print(reply); + if (h && h->print_tuple) + h->print_tuple(reply); break; case CTA_STATUS: status = NFA_DATA(attr); - printf("status:%u ", *status); + print_status(*status); break; case CTA_PROTOINFO: proto = NFA_DATA(attr); - if (proto2str[proto->num_proto]) - printf("%s %d ", proto2str[proto->num_proto], proto->num_proto); - else - printf("unknown %d ", proto->num_proto); + if (proto2str[proto->num_proto]) { + fprintf(stdout, "%s %d ", proto2str[proto->num_proto], proto->num_proto); + h = findproto(proto2str[proto->num_proto]); + if (h && h->print_proto) + h->print_proto(&proto->proto); + } else + fprintf(stdout, "unknown %d ", proto->num_proto); break; case CTA_TIMEOUT: timeout = NFA_DATA(attr); - printf("timeout:%lu ", *timeout); + fprintf(stdout, "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); + fprintf(stdout, "mark=%lu ", *mark); break; case CTA_COUNTERS: ctr = NFA_DATA(attr); - printf("orig_packets=%lu orig_bytes=%lu, " - "reply_packets=%lu reply_bytes=%lu ", + fprintf(stdout, "orig_packets=%llu orig_bytes=%llu, " + "reply_packets=%llu reply_bytes=%llu ", ctr->orig.packets, ctr->orig.bytes, ctr->reply.packets, ctr->reply.bytes); break; @@ -211,7 +226,7 @@ static int event_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, DEBUGP("nfa->nfa_len: %d\n", attr->nfa_len); attr = NFA_NEXT(attr, attrlen); } - printf("\n"); + fprintf(stdout, "\n"); return 0; } @@ -246,32 +261,32 @@ static int expect_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void * switch(attr->nfa_type) { case CTA_EXP_TUPLE: exp = NFA_DATA(attr); - printf("src=%u.%u.%u.%u dst=%u.%u.%u.%u ", + fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(exp->src.ip), NIPQUAD(exp->dst.ip)); h = findproto(proto2str[exp->dst.protonum]); - if (h && h->print) - h->print(exp); + if (h && h->print_tuple) + h->print_tuple(exp); break; case CTA_EXP_MASK: mask = NFA_DATA(attr); - printf("src=%u.%u.%u.%u dst=%u.%u.%u.%u ", + fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(mask->src.ip), NIPQUAD(mask->dst.ip)); h = findproto(proto2str[mask->dst.protonum]); - if (h && h->print) - h->print(mask); + if (h && h->print_tuple) + h->print_tuple(mask); break; case CTA_EXP_TIMEOUT: timeout = NFA_DATA(attr); - printf("timeout:%lu ", *timeout); + fprintf(stdout, "timeout:%lu ", *timeout); break; } DEBUGP("nfa->nfa_type: %d\n", attr->nfa_type); DEBUGP("nfa->nfa_len: %d\n", attr->nfa_len); attr = NFA_NEXT(attr, attrlen); } - printf("\n"); + fprintf(stdout, "\n"); return 0; } @@ -288,13 +303,11 @@ int create_conntrack(struct ip_conntrack_tuple *orig, cta.num_proto = orig->dst.protonum; memcpy(&cta.proto, proto, sizeof(*proto)); - if (ctnl_open(&cth, 0) < 0) { - printf("error\n"); - exit(0); - } + if (ctnl_open(&cth, 0) < 0) + return -1; /* FIXME: please unify returns values... */ - if (ctnl_new_conntrack(&cth, orig, reply, timeout, proto, status) < 0) + if (ctnl_new_conntrack(&cth, orig, reply, timeout, &cta, status) < 0) return -1; if (ctnl_close(&cth) < 0) @@ -304,8 +317,7 @@ int create_conntrack(struct ip_conntrack_tuple *orig, } int delete_conntrack(struct ip_conntrack_tuple *tuple, - enum ctattr_type_t t, - unsigned long id) + enum ctattr_type_t t) { struct nfattr *cda[CTA_MAX]; struct ctnl_handle cth; @@ -314,7 +326,7 @@ int delete_conntrack(struct ip_conntrack_tuple *tuple, return -1; /* FIXME: please unify returns values... */ - if (ctnl_del_conntrack(&cth, tuple, t, id) < 0) + if (ctnl_del_conntrack(&cth, tuple, t) < 0) return -1; if (ctnl_close(&cth) < 0) @@ -341,7 +353,7 @@ int get_conntrack(struct ip_conntrack_tuple *tuple, ctnl_register_handler(&cth, &h); /* FIXME!!!! get_conntrack_handler returns -100 */ - if (ctnl_get_conntrack(&cth, tuple, t, id) != -100) + if (ctnl_get_conntrack(&cth, tuple, t) != -100) return -1; if (ctnl_close(&cth) < 0) @@ -413,6 +425,10 @@ struct ctproto_handler *findproto(char *name) if (!name) return handler; + lib_dir = getenv("CONNTRACK_LIB_DIR"); + if (!lib_dir) + lib_dir = CONNTRACK_LIB_DIR; + list_for_each(i, &proto_list) { cur = (struct ctproto_handler *) i; if (strcmp(cur->name, name) == 0) { @@ -422,13 +438,13 @@ struct ctproto_handler *findproto(char *name) } if (!handler) { - char path[sizeof("extensions/libct_proto_.so") - + strlen(name)]; - sprintf(path, "extensions/libct_proto_%s.so", name); + char path[sizeof("libct_proto_.so") + + strlen(name) + strlen(lib_dir)]; + sprintf(path, "%s/libct_proto_%s.so", lib_dir, name); if (dlopen(path, RTLD_NOW)) handler = findproto(name); -/* else - fprintf (stderr, "%s\n", dlerror());*/ + else + DEBUGP(stderr, "%s\n", dlerror()); } return handler; @@ -466,16 +482,44 @@ int dump_expect_list() return 0; } -int set_dump_mask(unsigned int mask) +int set_mask(unsigned int mask, int type) { struct ctnl_handle cth; + enum ctattr_type_t cta_type; + + switch(type) { + case 0: + cta_type = CTA_DUMPMASK; + break; + case 1: + cta_type = CTA_EVENTMASK; + break; + default: + return -1; + } if (ctnl_open(&cth, 0) < 0) return -1; - if (ctnl_set_dumpmask(&cth, mask) < 0) + if (ctnl_set_mask(&cth, mask, cta_type) < 0) + return -1; + + if (ctnl_close(&cth) < 0) return -1; + + return 0; +} + +int flush_conntrack() +{ + struct ctnl_handle cth; + if (ctnl_open(&cth, 0) < 0) + return -1; + + if (ctnl_flush_conntrack(&cth) < 0) + return -1; + if (ctnl_close(&cth) < 0) return -1; -- cgit v1.2.3