summaryrefslogtreecommitdiffstats
path: root/src/libct.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libct.c')
-rw-r--r--src/libct.c174
1 files changed, 109 insertions, 65 deletions
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 <pablo@eurodev.net>
+ *
+ * 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 <stdio.h>
#include <getopt.h>
#include <dlfcn.h>
@@ -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;