summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org>2005-10-16 21:13:29 +0000
committer/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org>2005-10-16 21:13:29 +0000
commitda9b980f8d34c436b31d5a0a09b4ea27849c9c82 (patch)
tree8b3e27bae375b64c2b3d35e1e9b1bb226f9514a1
parentcce8dd1bd45465dd9b18e4f02b5d007cb39079b0 (diff)
See ChangeLog
-rw-r--r--ChangeLog8
-rw-r--r--Makefile.am2
-rw-r--r--configure.in4
-rw-r--r--extensions/libct_proto_icmp.c41
-rw-r--r--extensions/libct_proto_sctp.c31
-rw-r--r--extensions/libct_proto_tcp.c49
-rw-r--r--extensions/libct_proto_udp.c35
-rw-r--r--include/libct_proto.h25
-rw-r--r--src/Makefile.am2
-rw-r--r--src/conntrack.c263
-rw-r--r--src/libct.c660
11 files changed, 253 insertions, 867 deletions
diff --git a/ChangeLog b/ChangeLog
index 1a44a43..2942f78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-10-14
+<pablo@netfilter.org>
+ o Kill config.h.in, it's generated by the autocrap
+ o The conntrack tool now uses libnetfilter_conntrack :)
+ o libct.c has been killed, now it's in libnetfilter_conntrack
+ o Check if you're root or CAP_NET_ADMIN
+ o Bumped version number to 0.86
+
2005-10-07
<chentschel@iplan.com.ar>
o Fixed ICMP options
diff --git a/Makefile.am b/Makefile.am
index 18a67c6..8d9faf6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,7 @@ EXTRA_DIST = $(man_MANS)
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I${KERNELDIR}
SUBDIRS = src extensions
DIST_SUBDIRS = include src extensions
-LINKOPTS = -ldl -lnfnetlink -lnfnetlink_conntrack
+LINKOPTS = -ldl -lnfnetlink -lnetfilter_conntrack
AM_CFLAGS = -g
$(OBJECTS): libtool
diff --git a/configure.in b/configure.in
index cd6d7b5..0f0fc5f 100644
--- a/configure.in
+++ b/configure.in
@@ -2,7 +2,7 @@ AC_INIT
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(conntrack, 0.81)
+AM_INIT_AUTOMAKE(conntrack, 0.63)
AM_CONFIG_HEADER(config.h)
AC_PROG_CC
@@ -22,7 +22,7 @@ dnl AC_CHECK_LIB([c], [main])
AC_CHECK_LIB([dl], [dlopen])
AC_CHECK_LIB([nfnetlink], [nfnl_listen])
-AC_CHECK_LIB([nfnetlink_conntrack], [ctnl_register_handler] ,,,[-lnfnetlink])
+AC_CHECK_LIB([netfilter_conntrack], [nfct_dump_conntrack_table] ,,,[-lnetfilter_conntrack])
# Checks for header files.
dnl AC_HEADER_STDC
diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c
index be81507..7142fa7 100644
--- a/extensions/libct_proto_icmp.c
+++ b/extensions/libct_proto_icmp.c
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <netinet/in.h> /* For htons */
#include <netinet/ip_icmp.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include "libct_proto.h"
static struct option opts[] = {
@@ -52,10 +53,10 @@ static u_int8_t invmap[]
[ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
int parse(char c, char *argv[],
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- struct ctnl_tuple *mask,
- union ctnl_protoinfo *proto,
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply,
+ struct nfct_tuple *mask,
+ union nfct_protoinfo *proto,
unsigned int *flags)
{
switch(c) {
@@ -85,24 +86,9 @@ int parse(char c, char *argv[],
return 1;
}
-void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple)
-{
- if (cda[CTA_PROTO_ICMP_TYPE-1])
- tuple->l4dst.icmp.type =
- *(u_int8_t *)NFA_DATA(cda[CTA_PROTO_ICMP_TYPE-1]);
-
- if (cda[CTA_PROTO_ICMP_CODE-1])
- tuple->l4dst.icmp.code =
- *(u_int8_t *)NFA_DATA(cda[CTA_PROTO_ICMP_CODE-1]);
-
- if (cda[CTA_PROTO_ICMP_ID-1])
- tuple->l4src.icmp.id =
- *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_ICMP_ID-1]);
-}
-
int final_check(unsigned int flags,
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply)
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply)
{
if (!(flags & ICMP_TYPE))
return 0;
@@ -112,21 +98,10 @@ int final_check(unsigned int flags,
return 1;
}
-void print_proto(struct ctnl_tuple *t)
-{
- fprintf(stdout, "type=%d code=%d ", t->l4dst.icmp.type,
- t->l4dst.icmp.code);
- /* ID only makes sense with ECHO */
- if (t->l4dst.icmp.type == 8)
- fprintf(stdout, "id=%d ", t->l4src.icmp.id);
-}
-
static struct ctproto_handler icmp = {
.name = "icmp",
- .protonum = 1,
+ .protonum = IPPROTO_ICMP,
.parse_opts = parse,
- .parse_proto = parse_proto,
- .print_proto = print_proto,
.final_check = final_check,
.help = help,
.opts = opts,
diff --git a/extensions/libct_proto_sctp.c b/extensions/libct_proto_sctp.c
index 9afb661..bc91966 100644
--- a/extensions/libct_proto_sctp.c
+++ b/extensions/libct_proto_sctp.c
@@ -12,9 +12,8 @@
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h> /* For htons */
-#include <linux/netfilter/nfnetlink_conntrack.h>
#include "libct_proto.h"
-#include <libnfnetlink_conntrack/libnfnetlink_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
static struct option opts[] = {
{"orig-port-src", 1, 0, '1'},
@@ -63,10 +62,10 @@ void help()
}
int parse_options(char c, char *argv[],
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- struct ctnl_tuple *mask,
- union ctnl_protoinfo *proto,
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply,
+ struct nfct_tuple *mask,
+ union nfct_protoinfo *proto,
unsigned int *flags)
{
switch(c) {
@@ -100,7 +99,7 @@ int parse_options(char c, char *argv[],
for (i=0; i<10; i++) {
if (strcmp(optarg, states[i]) == 0) {
/* FIXME: Add state to
- * ctnl_protoinfo
+ * nfct_protoinfo
proto->sctp.state = i; */
break;
}
@@ -116,8 +115,8 @@ int parse_options(char c, char *argv[],
}
int final_check(unsigned int flags,
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply)
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply)
{
if ((flags & (ORIG_SPORT|ORIG_DPORT))
&& !(flags & (REPL_SPORT|REPL_DPORT))) {
@@ -137,7 +136,7 @@ int final_check(unsigned int flags,
return 0;
}
-void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple)
+void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple)
{
if (cda[CTA_PROTO_SRC_PORT-1])
tuple->l4src.sctp.port =
@@ -147,7 +146,7 @@ void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple)
*(u_int16_t *)NFA_DATA(cda[CTA_PROTO_DST_PORT-1]);
}
-void parse_protoinfo(struct nfattr *cda[], struct ctnl_conntrack *ct)
+void parse_protoinfo(struct nfattr *cda[], struct nfct_conntrack *ct)
{
/* if (cda[CTA_PROTOINFO_SCTP_STATE-1])
ct->protoinfo.sctp.state =
@@ -155,12 +154,12 @@ void parse_protoinfo(struct nfattr *cda[], struct ctnl_conntrack *ct)
*/
}
-void print_protoinfo(union ctnl_protoinfo *protoinfo)
+void print_protoinfo(union nfct_protoinfo *protoinfo)
{
/* fprintf(stdout, "%s ", states[protoinfo->sctp.state]); */
}
-void print_proto(struct ctnl_tuple *tuple)
+void print_proto(struct nfct_tuple *tuple)
{
fprintf(stdout, "sport=%u dport=%u ", htons(tuple->l4src.sctp.port),
htons(tuple->l4dst.sctp.port));
@@ -168,12 +167,8 @@ void print_proto(struct ctnl_tuple *tuple)
static struct ctproto_handler sctp = {
.name = "sctp",
- .protonum = 132,
+ .protonum = IPPROTO_SCTP,
.parse_opts = parse_options,
- .parse_protoinfo = parse_protoinfo,
- .parse_proto = parse_proto,
- .print_proto = print_proto,
- .print_protoinfo = print_protoinfo,
.final_check = final_check,
.help = help,
.opts = opts,
diff --git a/extensions/libct_proto_tcp.c b/extensions/libct_proto_tcp.c
index 4f3094f..3b06aa2 100644
--- a/extensions/libct_proto_tcp.c
+++ b/extensions/libct_proto_tcp.c
@@ -12,8 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h> /* For htons */
-#include <linux/netfilter/nfnetlink_conntrack.h>
-#include <libnfnetlink_conntrack/libnfnetlink_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include "libct_proto.h"
@@ -76,10 +75,10 @@ void help()
}
int parse_options(char c, char *argv[],
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- struct ctnl_tuple *mask,
- union ctnl_protoinfo *proto,
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply,
+ struct nfct_tuple *mask,
+ union nfct_protoinfo *proto,
unsigned int *flags)
{
switch(c) {
@@ -139,8 +138,8 @@ int parse_options(char c, char *argv[],
}
int final_check(unsigned int flags,
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply)
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply)
{
if ((flags & (ORIG_SPORT|ORIG_DPORT))
&& !(flags & (REPL_SPORT|REPL_DPORT))) {
@@ -160,42 +159,10 @@ int final_check(unsigned int flags,
return 0;
}
-void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple)
-{
- if (cda[CTA_PROTO_SRC_PORT-1])
- tuple->l4src.tcp.port =
- *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_SRC_PORT-1]);
- if (cda[CTA_PROTO_DST_PORT-1])
- tuple->l4dst.tcp.port =
- *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_DST_PORT-1]);
-}
-
-void parse_protoinfo(struct nfattr *cda[], struct ctnl_conntrack *ct)
-{
- if (cda[CTA_PROTOINFO_TCP_STATE-1])
- ct->protoinfo.tcp.state =
- *(u_int8_t *)NFA_DATA(cda[CTA_PROTOINFO_TCP_STATE-1]);
-}
-
-void print_protoinfo(union ctnl_protoinfo *protoinfo)
-{
- fprintf(stdout, "%s ", states[protoinfo->tcp.state]);
-}
-
-void print_proto(struct ctnl_tuple *tuple)
-{
- fprintf(stdout, "sport=%u dport=%u ", htons(tuple->l4src.tcp.port),
- htons(tuple->l4dst.tcp.port));
-}
-
static struct ctproto_handler tcp = {
.name = "tcp",
- .protonum = 6,
+ .protonum = IPPROTO_TCP,
.parse_opts = parse_options,
- .parse_protoinfo = parse_protoinfo,
- .parse_proto = parse_proto,
- .print_proto = print_proto,
- .print_protoinfo = print_protoinfo,
.final_check = final_check,
.help = help,
.opts = opts,
diff --git a/extensions/libct_proto_udp.c b/extensions/libct_proto_udp.c
index ecde5f2..8e77f0c 100644
--- a/extensions/libct_proto_udp.c
+++ b/extensions/libct_proto_udp.c
@@ -11,9 +11,8 @@
#include <getopt.h>
#include <stdlib.h>
#include <netinet/in.h> /* For htons */
-#include <linux/netfilter/nfnetlink_conntrack.h>
#include "libct_proto.h"
-#include <libnfnetlink_conntrack/libnfnetlink_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
static struct option opts[] = {
{"orig-port-src", 1, 0, '1'},
@@ -56,10 +55,10 @@ void help()
}
int parse_options(char c, char *argv[],
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- struct ctnl_tuple *mask,
- union ctnl_protoinfo *proto,
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply,
+ struct nfct_tuple *mask,
+ union nfct_protoinfo *proto,
unsigned int *flags)
{
switch(c) {
@@ -104,8 +103,8 @@ int parse_options(char c, char *argv[],
}
int final_check(unsigned int flags,
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply)
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply)
{
if ((flags & (ORIG_SPORT|ORIG_DPORT))
&& !(flags & (REPL_SPORT|REPL_DPORT))) {
@@ -125,28 +124,10 @@ int final_check(unsigned int flags,
return 0;
}
-void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple)
-{
- if (cda[CTA_PROTO_SRC_PORT-1])
- tuple->l4src.udp.port =
- *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_SRC_PORT-1]);
- if (cda[CTA_PROTO_DST_PORT-1])
- tuple->l4dst.udp.port =
- *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_DST_PORT-1]);
-}
-
-void print_proto(struct ctnl_tuple *tuple)
-{
- fprintf(stdout, "sport=%u dport=%u ", htons(tuple->l4src.udp.port),
- htons(tuple->l4dst.udp.port));
-}
-
static struct ctproto_handler udp = {
.name = "udp",
- .protonum = 17,
+ .protonum = IPPROTO_UDP,
.parse_opts = parse_options,
- .parse_proto = parse_proto,
- .print_proto = print_proto,
.final_check = final_check,
.help = help,
.opts = opts,
diff --git a/include/libct_proto.h b/include/libct_proto.h
index b358e1a..db434d6 100644
--- a/include/libct_proto.h
+++ b/include/libct_proto.h
@@ -1,11 +1,9 @@
#ifndef _LIBCT_PROTO_H
#define _LIBCT_PROTO_H
-/* FIXME: Rename this file pablo... */
-
#include "linux_list.h"
#include <getopt.h>
-#include <libnfnetlink_conntrack/libnfnetlink_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#define LIBCT_VERSION "0.1.0"
@@ -16,8 +14,6 @@
#define IPS_DST_NAT_DONE (1 << 8)
#define IPS_CONFIRMED (1 << 3)
-struct cta_proto;
-
struct ctproto_handler {
struct list_head head;
@@ -28,20 +24,15 @@ struct ctproto_handler {
enum ctattr_protoinfo protoinfo_attr;
int (*parse_opts)(char c, char *argv[],
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- struct ctnl_tuple *mask,
- union ctnl_protoinfo *proto,
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply,
+ struct nfct_tuple *mask,
+ union nfct_protoinfo *proto,
unsigned int *flags);
- void (*parse_proto)(struct nfattr *cda[], struct ctnl_tuple *tuple);
- void (*parse_protoinfo)(struct nfattr *cda[],
- struct ctnl_conntrack *ct);
- void (*print_proto)(struct ctnl_tuple *t);
- void (*print_protoinfo)(union ctnl_protoinfo *protoinfo);
int (*final_check)(unsigned int flags,
- struct ctnl_tuple *orig,
- struct ctnl_tuple *reply);
+ struct nfct_tuple *orig,
+ struct nfct_tuple *reply);
void (*help)();
@@ -53,8 +44,6 @@ struct ctproto_handler {
extern void register_proto(struct ctproto_handler *h);
extern void unregister_proto(struct ctproto_handler *h);
-extern struct ctproto_handler *findproto(char *name);
-
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
diff --git a/src/Makefile.am b/src/Makefile.am
index ae3f429..71ad3d5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
bin_PROGRAMS = conntrack
-conntrack_SOURCES = conntrack.c libct.c
+conntrack_SOURCES = conntrack.c
INCLUDES= $(all_includes) -I$(top_srcdir)/include -I${KERNELDIR}
conntrack_LDFLAGS = $(all_libraries) -rdynamic
diff --git a/src/conntrack.c b/src/conntrack.c
index 1d5227e..8132dcb 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -1,5 +1,5 @@
/*
- * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
+ * (C) 2005 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* 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
@@ -42,19 +42,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <dlfcn.h>
#include <string.h>
-#include <libnfnetlink_conntrack/libnfnetlink_conntrack.h>
#include "linux_list.h"
#include "libct_proto.h"
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#define PROGNAME "conntrack"
-#define VERSION "0.82"
-
-#if 0
-#define DEBUGP printf
-#else
-#define DEBUGP
-#endif
+#define VERSION "0.86"
#ifndef PROC_SYS_MODPROBE
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
@@ -197,6 +192,7 @@ static struct option original_opts[] = {
#define OPTION_OFFSET 256
+struct nfct_handle *cth;
static struct option *opts = original_opts;
static unsigned int global_option_offset = 0;
@@ -236,12 +232,53 @@ char *lib_dir = CONNTRACK_LIB_DIR;
LIST_HEAD(proto_list);
-char *proto2str[IPPROTO_MAX] = {
- [IPPROTO_TCP] = "tcp",
- [IPPROTO_UDP] = "udp",
- [IPPROTO_ICMP] = "icmp",
- [IPPROTO_SCTP] = "sctp"
-};
+void register_proto(struct ctproto_handler *h)
+{
+ if (strcmp(h->version, LIBCT_VERSION) != 0) {
+ fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
+ h->name, h->version, LIBCT_VERSION);
+ exit(1);
+ }
+ list_add(&h->head, &proto_list);
+}
+
+void unregister_proto(struct ctproto_handler *h)
+{
+ list_del(&h->head);
+}
+
+static struct nfct_proto *findproto(char *name)
+{
+ struct list_head *i;
+ struct nfct_proto *cur = NULL, *handler = NULL;
+
+ 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 nfct_proto *) i;
+ if (strcmp(cur->name, name) == 0) {
+ handler = cur;
+ break;
+ }
+ }
+
+ if (!handler) {
+ 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());
+ }
+
+ return handler;
+}
enum exittype {
OTHER_PROBLEM = 1,
@@ -383,7 +420,9 @@ err2str(int err, enum action command)
{ CT_GET, -EAFNOSUPPORT, "protocol not supported" },
{ CT_CREATE, -ETIME, "conntrack has expired" },
{ EXP_CREATE, -ENOENT, "master conntrack not found" },
- { EXP_CREATE, -EINVAL, "invalid parameters" }
+ { EXP_CREATE, -EINVAL, "invalid parameters" },
+ { ~0UL, -EPERM, "sorry, you must be root or get "
+ "CAP_NET_ADMIN capability to do this"}
};
for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
@@ -394,7 +433,7 @@ err2str(int err, enum action command)
return strerror(err);
}
-static void dump_tuple(struct ctnl_tuple *tp)
+static void dump_tuple(struct nfct_tuple *tp)
{
fprintf(stdout, "tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n",
tp, tp->protonum,
@@ -553,7 +592,7 @@ int iptables_insmod(const char *modname, const char *modprobe)
/* Shamelessly stolen from libipt_DNAT ;). Ranges expected in network order. */
static void
-nat_parse(char *arg, int portok, struct ctnl_nat *range)
+nat_parse(char *arg, int portok, struct nfct_nat *range)
{
char *colon, *dash, *error;
unsigned long ip;
@@ -625,6 +664,13 @@ nat_parse(char *arg, int portok, struct ctnl_nat *range)
range->max_ip = range->min_ip;
}
+static void event_sighandler(int s)
+{
+ fprintf(stdout, "Now closing conntrack event dumping...\n");
+ nfct_close(cth);
+ exit(0);
+}
+
void usage(char *prog) {
fprintf(stdout, "Tool to manipulate conntrack and expectations. Version %s\n", VERSION);
fprintf(stdout, "Usage: %s [commands] [options]\n", prog);
@@ -659,11 +705,11 @@ int main(int argc, char *argv[])
{
char c;
unsigned int command = 0, options = 0;
- struct ctnl_tuple orig, reply, mask, *o = NULL, *r = NULL;
- struct ctnl_tuple exptuple;
+ struct nfct_tuple orig, reply, mask, *o = NULL, *r = NULL;
+ struct nfct_tuple exptuple;
struct ctproto_handler *h = NULL;
- union ctnl_protoinfo proto;
- struct ctnl_nat range;
+ union nfct_protoinfo proto;
+ struct nfct_nat range;
unsigned long timeout = 0;
unsigned int status = IPS_CONFIRMED;
unsigned long id = 0;
@@ -671,13 +717,13 @@ int main(int argc, char *argv[])
int manip = -1;
int res = 0, retry = 2;
- memset(&proto, 0, sizeof(union ctnl_protoinfo));
- memset(&orig, 0, sizeof(struct ctnl_tuple));
- memset(&reply, 0, sizeof(struct ctnl_tuple));
- memset(&mask, 0, sizeof(struct ctnl_tuple));
- memset(&exptuple, 0, sizeof(struct ctnl_tuple));
- memset(&range, 0, sizeof(struct ctnl_nat));
-
+ memset(&proto, 0, sizeof(union nfct_protoinfo));
+ memset(&orig, 0, sizeof(struct nfct_tuple));
+ memset(&reply, 0, sizeof(struct nfct_tuple));
+ memset(&mask, 0, sizeof(struct nfct_tuple));
+ memset(&exptuple, 0, sizeof(struct nfct_tuple));
+ memset(&range, 0, sizeof(struct nfct_nat));
+
while ((c = getopt_long(argc, argv,
"L::I::U::D::G::E::F::hVs:d:r:q:p:t:u:e:a:z[:]:{:}:",
opts, NULL)) != -1) {
@@ -846,14 +892,24 @@ int main(int argc, char *argv[])
retry--;
switch(command) {
case CT_LIST:
+ cth = nfct_open(CONNTRACK, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
+ nfct_set_callback(cth, nfct_default_conntrack_display);
if (options & CT_OPT_ZERO)
- res = dump_conntrack_table(1);
+ res = nfct_dump_conntrack_table_zero(cth);
else
- res = dump_conntrack_table(0);
+ res = nfct_dump_conntrack_table(cth);
break;
+ nfct_close(cth);
case EXP_LIST:
- res = dump_expect_list();
+ cth = nfct_open(EXPECT, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
+ nfct_set_callback(cth, nfct_default_expect_display);
+ res = nfct_dump_expect_list(cth);
+ nfct_close(cth);
break;
case CT_CREATE:
@@ -866,25 +922,43 @@ int main(int argc, char *argv[])
orig.src.v4 = reply.dst.v4;
orig.dst.v4 = reply.src.v4;
}
+ cth = nfct_open(CONNTRACK, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
if (options & CT_OPT_NATRANGE)
- res = create_conntrack(&orig, &reply, timeout,
- &proto, status, &range);
+ res = nfct_create_conntrack_nat(cth,
+ &orig,
+ &reply,
+ timeout,
+ &proto,
+ status,
+ &range);
else
- res = create_conntrack(&orig, &reply, timeout,
- &proto, status, NULL);
+ res = nfct_create_conntrack(cth, &orig,
+ &reply,
+ timeout,
+ &proto,
+ status);
+ nfct_close(cth);
break;
case EXP_CREATE:
+ cth = nfct_open(EXPECT, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
if (options & CT_OPT_ORIG)
- res = create_expectation(&orig,
- &exptuple,
- &mask,
- timeout);
+ res = nfct_create_expectation(cth,
+ &orig,
+ &exptuple,
+ &mask,
+ timeout);
else if (options & CT_OPT_REPL)
- res = create_expectation(&reply,
- &exptuple,
- &mask,
- timeout);
+ res = nfct_create_expectation(cth,
+ &reply,
+ &exptuple,
+ &mask,
+ timeout);
+ nfct_close(cth);
break;
case CT_UPDATE:
@@ -897,60 +971,117 @@ int main(int argc, char *argv[])
orig.src.v4 = reply.dst.v4;
orig.dst.v4 = reply.src.v4;
}
- res = update_conntrack(&orig, &reply, timeout,
- &proto, status);
+ cth = nfct_open(CONNTRACK, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
+ res = nfct_update_conntrack(cth, &orig, &reply,
+ timeout, &proto,
+ status);
+ nfct_close(cth);
break;
case CT_DELETE:
+ cth = nfct_open(CONNTRACK, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
if (options & CT_OPT_ORIG)
- res = delete_conntrack(&orig, CTA_TUPLE_ORIG,
- CTNL_DIR_ORIGINAL);
+ res = nfct_delete_conntrack(cth,&orig,
+ NFCT_DIR_ORIGINAL);
else if (options & CT_OPT_REPL)
- res = delete_conntrack(&reply, CTA_TUPLE_REPLY,
- CTNL_DIR_REPLY);
+ res = nfct_delete_conntrack(cth,&reply,
+ NFCT_DIR_REPLY);
+ nfct_close(cth);
break;
case EXP_DELETE:
+ cth = nfct_open(EXPECT, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
if (options & CT_OPT_ORIG)
- res = delete_expectation(&orig);
+ res = nfct_delete_expectation(cth,&orig);
else if (options & CT_OPT_REPL)
- res = delete_expectation(&reply);
+ res = nfct_delete_expectation(cth,&reply);
+ nfct_close(cth);
break;
case CT_GET:
+ cth = nfct_open(CONNTRACK, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
if (options & CT_OPT_ORIG)
- res = get_conntrack(&orig, id);
+ res = nfct_get_conntrack(cth,&orig, id);
else if (options & CT_OPT_REPL)
- res = get_conntrack(&reply, id);
+ res = nfct_get_conntrack(cth,&reply, id);
+ nfct_close(cth);
break;
case EXP_GET:
+ cth = nfct_open(EXPECT, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
if (options & CT_OPT_ORIG)
- res = get_expect(&orig, CTA_TUPLE_ORIG);
+ res = nfct_get_expectation(cth,&orig);
else if (options & CT_OPT_REPL)
- res = get_expect(&reply, CTA_TUPLE_REPLY);
+ res = nfct_get_expectation(cth,&reply);
+ nfct_close(cth);
break;
case CT_FLUSH:
- res = flush_conntrack();
+ cth = nfct_open(CONNTRACK, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
+ res = nfct_flush_conntrack_table(cth);
+ nfct_close(cth);
break;
case EXP_FLUSH:
- res = flush_expectation();
+ cth = nfct_open(EXPECT, 0);
+ if (!cth)
+ exit_error(OTHER_PROBLEM, "Not enough memory");
+ res = nfct_flush_expectation_table(cth);
+ nfct_close(cth);
break;
case CT_EVENT:
- if (options & CT_OPT_EVENT_MASK)
- res = event_conntrack(event_mask);
- else
- res = event_conntrack(~0U);
+ if (options & CT_OPT_EVENT_MASK) {
+ cth = nfct_open(CONNTRACK, event_mask);
+ if (!cth)
+ exit_error(OTHER_PROBLEM,
+ "Not enough memory");
+ signal(SIGINT, event_sighandler);
+ nfct_set_callback(cth, nfct_default_conntrack_display);
+ res = nfct_event_conntrack(cth);
+ } else {
+ cth = nfct_open(CONNTRACK, ~0U);
+ if (!cth)
+ exit_error(OTHER_PROBLEM,
+ "Not enough memory");
+ signal(SIGINT, event_sighandler);
+ nfct_set_callback(cth, nfct_default_conntrack_display);
+ res = nfct_event_conntrack(cth);
+ }
+ nfct_close(cth);
break;
case EXP_EVENT:
- if (options & CT_OPT_EVENT_MASK)
- res = event_expectation(event_mask);
- else
- res = event_expectation(~0U);
+ if (options & CT_OPT_EVENT_MASK) {
+ cth = nfct_open(EXPECT, event_mask);
+ if (!cth)
+ exit_error(OTHER_PROBLEM,
+ "Not enough memory");
+ signal(SIGINT, event_sighandler);
+ nfct_set_callback(cth, nfct_default_expect_display);
+ res = nfct_event_expectation(cth);
+ } else {
+ cth = nfct_open(EXPECT, ~0U);
+ if (!cth)
+ exit_error(OTHER_PROBLEM,
+ "Not enough memory");
+ signal(SIGINT, event_sighandler);
+ nfct_set_callback(cth, nfct_default_expect_display);
+ res = nfct_event_expectation(cth);
+ }
+ nfct_close(cth);
break;
case CT_VERSION:
diff --git a/src/libct.c b/src/libct.c
deleted file mode 100644
index 36aacbd..0000000
--- a/src/libct.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
- * Harald Welte <laforge@netfilter.org>
- *
- * 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>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-/* From kernel.h */
-#define INT_MAX ((int)(~0U>>1))
-#define INT_MIN (-INT_MAX - 1)
-#include <libnfnetlink_conntrack/libnfnetlink_conntrack.h>
-#include "linux_list.h"
-#include "libct_proto.h"
-
-#if 0
-#define DEBUGP printf
-#else
-#define DEBUGP
-#endif
-
-static struct ctnl_handle cth;
-extern char *lib_dir;
-extern struct list_head proto_list;
-extern char *proto2str[];
-
-static void dump_tuple(struct ctnl_tuple *tp)
-{
- fprintf(stdout, "tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n",
- tp, tp->protonum,
- NIPQUAD(tp->src.v4), ntohs(tp->l4src.all),
- NIPQUAD(tp->dst.v4), ntohs(tp->l4dst.all));
-}
-
-static void print_status(unsigned int status)
-{
- if (status & IPS_ASSURED)
- fprintf(stdout, "[ASSURED] ");
- if (!(status & IPS_SEEN_REPLY))
- fprintf(stdout, "[UNREPLIED] ");
-}
-
-static void parse_ip(struct nfattr *attr, struct ctnl_tuple *tuple)
-{
- struct nfattr *tb[CTA_IP_MAX];
-
- memset(tb, 0, CTA_IP_MAX * sizeof(struct nfattr *));
-
- nfnl_parse_nested(tb, CTA_IP_MAX, attr);
- if (tb[CTA_IP_V4_SRC-1])
- tuple->src.v4 = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
-
- if (tb[CTA_IP_V4_DST-1])
- tuple->dst.v4 = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
-}
-
-static void parse_proto(struct nfattr *attr, struct ctnl_tuple *tuple)
-{
- struct nfattr *tb[CTA_PROTO_MAX];
- struct ctproto_handler *h;
- int dir = CTNL_DIR_REPLY;
-
- memset(tb, 0, CTA_PROTO_MAX * sizeof(struct nfattr *));
-
- nfnl_parse_nested(tb, CTA_PROTO_MAX, attr);
- if (tb[CTA_PROTO_NUM-1])
- tuple->protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
-
- h = findproto(proto2str[tuple->protonum]);
- if (h && h->parse_proto)
- h->parse_proto(tb, tuple);
-}
-
-static void parse_tuple(struct nfattr *attr, struct ctnl_tuple *tuple)
-{
- struct nfattr *tb[CTA_TUPLE_MAX];
-
- memset(tb, 0, CTA_TUPLE_MAX*sizeof(struct nfattr *));
-
- nfnl_parse_nested(tb, CTA_TUPLE_MAX, attr);
- if (tb[CTA_TUPLE_IP-1])
- parse_ip(tb[CTA_TUPLE_IP-1], tuple);
- if (tb[CTA_TUPLE_PROTO-1])
- parse_proto(tb[CTA_TUPLE_PROTO-1], tuple);
-}
-
-static void parse_protoinfo(struct nfattr *attr, struct ctnl_conntrack *ct)
-{
- struct nfattr *tb[CTA_PROTOINFO_MAX];
- struct ctproto_handler *h;
-
- memset(tb, 0, CTA_PROTOINFO_MAX*sizeof(struct nfattr *));
-
- nfnl_parse_nested(tb,CTA_PROTOINFO_MAX, attr);
-
- h = findproto(proto2str[ct->tuple[CTNL_DIR_ORIGINAL].protonum]);
- if (h && h->parse_protoinfo)
- h->parse_protoinfo(tb, ct);
-}
-
-/* Pablo: What is the equivalence of be64_to_cpu in userspace?
- *
- * Harald: Good question. I don't think there's a standard way [yet?],
- * so I'd suggest manually implementing it by "#if little endian" bitshift
- * operations in C (at least for now).
- *
- * All the payload of any nfattr will always be in network byte order.
- * This would allow easy transport over a real network in the future
- * (e.g. jamal's netlink2).
- *
- * Pablo: I've called it __be64_to_cpu instead of be64_to_cpu, since maybe
- * there will one in the userspace headers someday. We don't want to
- * pollute POSIX space naming,
- */
-
-#include <byteswap.h>
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define __be64_to_cpu(x) (x)
-# else
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define __be64_to_cpu(x) __bswap_64(x)
-# endif
-#endif
-
-static void parse_counters(struct nfattr *attr, struct ctnl_conntrack *ct,
- enum ctattr_type parent)
-{
- struct nfattr *tb[CTA_COUNTERS_MAX];
- int dir = (parent == CTA_COUNTERS_ORIG ? CTNL_DIR_REPLY
- : CTNL_DIR_ORIGINAL);
-
- memset(tb, 0, CTA_COUNTERS_MAX*sizeof(struct nfattr *));
-
- nfnl_parse_nested(tb, CTA_COUNTERS_MAX, attr);
- if (tb[CTA_COUNTERS_PACKETS-1])
- ct->counters[dir].packets
- = __be64_to_cpu(*(u_int64_t *)
- NFA_DATA(tb[CTA_COUNTERS_PACKETS-1]));
- if (tb[CTA_COUNTERS_BYTES-1])
- ct->counters[dir].bytes
- = __be64_to_cpu(*(u_int64_t *)
- NFA_DATA(tb[CTA_COUNTERS_BYTES-1]));
-}
-
-/* Some people seem to like counting in decimal... */
-#define STATUS 1
-#define PROTOINFO 2
-#define TIMEOUT 4
-#define MARK 8
-#define COUNTERS 16
-#define USE 32
-#define ID 64
-
-static int handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg)
-{
- struct nfgenmsg *nfmsg;
- struct nfattr *nfa;
- int min_len = sizeof(struct nfgenmsg);;
- struct ctproto_handler *h = NULL;
- struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh));
- int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
- struct ctnl_conntrack ct;
- unsigned int flags = 0;
-
- memset(&ct, 0, sizeof(struct ctnl_conntrack));
-
- nfmsg = NLMSG_DATA(nlh);
-
- if (nlh->nlmsg_len < min_len)
- return -EINVAL;
-
- while (NFA_OK(attr, attrlen)) {
- switch(attr->nfa_type) {
- case CTA_TUPLE_ORIG:
- parse_tuple(attr, &ct.tuple[CTNL_DIR_ORIGINAL]);
- break;
- case CTA_TUPLE_REPLY:
- parse_tuple(attr, &ct.tuple[CTNL_DIR_REPLY]);
- break;
- case CTA_STATUS:
- ct.status = ntohl(*(u_int32_t *)NFA_DATA(attr));
- flags |= STATUS;
- break;
- case CTA_PROTOINFO:
- parse_protoinfo(attr, &ct);
- flags |= PROTOINFO;
- break;
- case CTA_TIMEOUT:
- ct.timeout = ntohl(*(u_int32_t *)NFA_DATA(attr));
- flags |= TIMEOUT;
- break;
- case CTA_MARK:
- ct.mark = ntohl(*(u_int32_t *)NFA_DATA(attr));
- flags |= MARK;
- break;
- case CTA_COUNTERS_ORIG:
- case CTA_COUNTERS_REPLY:
- parse_counters(attr, &ct, attr->nfa_type-1);
- flags |= COUNTERS;
- break;
- case CTA_USE:
- ct.use = ntohl(*(u_int32_t *)NFA_DATA(attr));
- flags |= USE;
- break;
- case CTA_ID:
- ct.id = ntohl(*(u_int32_t *)NFA_DATA(attr));
- flags |= ID;
- break;
- }
- attr = NFA_NEXT(attr, attrlen);
- }
-
- fprintf(stdout, "%-8s %u ",
- proto2str[ct.tuple[CTNL_DIR_ORIGINAL].protonum] == NULL ?
- "unknown" : proto2str[ct.tuple[CTNL_DIR_ORIGINAL].protonum],
- ct.tuple[CTNL_DIR_ORIGINAL].protonum);
-
- if (flags & TIMEOUT)
- fprintf(stdout, "%lu ", ct.timeout);
-
- h = findproto(proto2str[ct.tuple[CTNL_DIR_ORIGINAL].protonum]);
- if ((flags & PROTOINFO) && h && h->print_protoinfo)
- h->print_protoinfo(&ct.protoinfo);
-
- fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
- NIPQUAD(ct.tuple[CTNL_DIR_ORIGINAL].src.v4),
- NIPQUAD(ct.tuple[CTNL_DIR_ORIGINAL].dst.v4));
-
- if (h && h->print_proto)
- h->print_proto(&ct.tuple[CTNL_DIR_ORIGINAL]);
-
- if (flags & COUNTERS)
- fprintf(stdout, "packets=%llu bytes=%llu ",
- ct.counters[CTNL_DIR_ORIGINAL].packets,
- ct.counters[CTNL_DIR_ORIGINAL].bytes);
-
- fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
- NIPQUAD(ct.tuple[CTNL_DIR_REPLY].src.v4),
- NIPQUAD(ct.tuple[CTNL_DIR_REPLY].dst.v4));
-
- h = findproto(proto2str[ct.tuple[CTNL_DIR_ORIGINAL].protonum]);
- if (h && h->print_proto)
- h->print_proto(&ct.tuple[CTNL_DIR_REPLY]);
-
- if (flags & COUNTERS)
- fprintf(stdout, "packets=%llu bytes=%llu ",
- ct.counters[CTNL_DIR_REPLY].packets,
- ct.counters[CTNL_DIR_REPLY].bytes);
-
- if (flags & STATUS)
- print_status(ct.status);
-
- if (flags & MARK)
- fprintf(stdout, "mark=%lu ", ct.mark);
- if (flags & USE)
- fprintf(stdout, "use=%u ", ct.use);
- if (flags & ID)
- fprintf(stdout, "id=%u ", ct.id);
-
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-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)
-{
- int type = NFNL_MSG_TYPE(nlh->nlmsg_type);
- fprintf(stdout, "%9s ", typemsg2str(type, nlh->nlmsg_flags));
- return handler(sock, nlh, arg);
-}
-
-static int expect_handler(struct sockaddr_nl *sock, struct nlmsghdr *nlh, void *arg)
-{
- struct nfgenmsg *nfmsg;
- struct nfattr *nfa;
- int min_len = sizeof(struct nfgenmsg);;
- struct ctproto_handler *h = NULL;
- struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh));
- int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
- struct ctnl_tuple tuple, mask;
- unsigned long timeout = 0;
- u_int32_t id = 0;
- unsigned int flags;
-
- memset(&tuple, 0, sizeof(struct ctnl_tuple));
- memset(&mask, 0, sizeof(struct ctnl_tuple));
-
- nfmsg = NLMSG_DATA(nlh);
-
- if (nlh->nlmsg_len < min_len)
- return -EINVAL;
-
- while (NFA_OK(attr, attrlen)) {
- switch(attr->nfa_type) {
-
- case CTA_EXPECT_TUPLE:
- parse_tuple(attr, &tuple);
- break;
- case CTA_EXPECT_MASK:
- parse_tuple(attr, &mask);
- break;
- case CTA_EXPECT_TIMEOUT:
- timeout = htonl(*(unsigned long *)
- NFA_DATA(attr));
- break;
- case CTA_EXPECT_ID:
- id = htonl(*(u_int32_t *)NFA_DATA(attr));
- break;
- }
- attr = NFA_NEXT(attr, attrlen);
- }
- fprintf(stdout, "%ld proto=%d ", timeout, tuple.protonum);
-
- fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
- NIPQUAD(tuple.src.v4),
- NIPQUAD(tuple.dst.v4));
-
- fprintf(stdout, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
- NIPQUAD(mask.src.v4),
- NIPQUAD(mask.dst.v4));
-
- fprintf(stdout, "id=%u ", id);
-
- fputc('\n', stdout);
-
- return 0;
-}
-
-int create_conntrack(struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- unsigned long timeout,
- union ctnl_protoinfo *proto,
- unsigned int status,
- struct ctnl_nat *range)
-{
- struct ctnl_conntrack ct;
- int ret;
-
- memset(&ct, 0, sizeof(struct ctnl_conntrack));
- ct.tuple[CTNL_DIR_ORIGINAL] = *orig;
- ct.tuple[CTNL_DIR_REPLY] = *reply;
- ct.timeout = htonl(timeout);
- ct.status = status;
- ct.protoinfo = *proto;
- if (range)
- ct.nat = *range;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, 0)) < 0)
- return ret;
-
- ret = ctnl_new_conntrack(&cth, &ct);
-
- ctnl_close(&cth);
-
- return ret;
-}
-
-int update_conntrack(struct ctnl_tuple *orig,
- struct ctnl_tuple *reply,
- unsigned long timeout,
- union ctnl_protoinfo *proto,
- unsigned int status)
-{
- struct ctnl_conntrack ct;
- int ret;
-
- memset(&ct, 0, sizeof(struct ctnl_conntrack));
- ct.tuple[CTNL_DIR_ORIGINAL] = *orig;
- ct.tuple[CTNL_DIR_REPLY] = *reply;
- ct.timeout = htonl(timeout);
- ct.status = status;
- ct.protoinfo = *proto;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, 0)) < 0)
- return ret;
-
- ret = ctnl_upd_conntrack(&cth, &ct);
-
- ctnl_close(&cth);
-
- return ret;
-}
-
-int delete_conntrack(struct ctnl_tuple *tuple, int dir)
-{
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, 0)) < 0)
- return ret;
-
- ret = ctnl_del_conntrack(&cth, tuple, dir);
- ctnl_close(&cth);
-
- return ret;
-}
-
-/* get_conntrack_handler */
-int get_conntrack(struct ctnl_tuple *tuple, int dir)
-{
- struct ctnl_msg_handler h = {
- .type = 0,
- .handler = handler
- };
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, 0)) < 0)
- return ret;
-
- ctnl_register_handler(&cth, &h);
-
- ret = ctnl_get_conntrack(&cth, tuple, dir);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int dump_conntrack_table(int zero)
-{
- int ret;
- struct ctnl_msg_handler h = {
- .type = IPCTNL_MSG_CT_NEW, /* Hm... really? */
- .handler = handler
- };
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, 0)) < 0)
- return ret;
-
- ctnl_register_handler(&cth, &h);
-
- if (zero) {
- ret = ctnl_list_conntrack_zero_counters(&cth, AF_INET);
- } else
- ret = ctnl_list_conntrack(&cth, AF_INET);
-
- ctnl_close(&cth);
-
- return ret;
-}
-
-static void event_sighandler(int s)
-{
- fprintf(stdout, "Now closing conntrack event dumping...\n");
- ctnl_close(&cth);
- exit(0);
-}
-
-int event_conntrack(unsigned int event_mask)
-{
- struct ctnl_msg_handler hnew = {
- .type = IPCTNL_MSG_CT_NEW,
- .handler = event_handler
- };
- struct ctnl_msg_handler hdestroy = {
- .type = IPCTNL_MSG_CT_DELETE,
- .handler = event_handler
- };
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, event_mask)) < 0)
- return ret;
-
- signal(SIGINT, event_sighandler);
- ctnl_register_handler(&cth, &hnew);
- ctnl_register_handler(&cth, &hdestroy);
- ret = ctnl_event_conntrack(&cth, AF_INET);
- ctnl_close(&cth);
-
- return 0;
-}
-
-struct ctproto_handler *findproto(char *name)
-{
- void *h = NULL;
- struct list_head *i;
- struct ctproto_handler *cur = NULL, *handler = NULL;
-
- 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) {
- handler = cur;
- break;
- }
- }
-
- if (!handler) {
- 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
- DEBUGP(stderr, "%s\n", dlerror());
- }
-
- return handler;
-}
-
-void register_proto(struct ctproto_handler *h)
-{
- if (strcmp(h->version, LIBCT_VERSION) != 0) {
- fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
- h->name, h->version, LIBCT_VERSION);
- exit(1);
- }
- list_add(&h->head, &proto_list);
-}
-
-void unregister_proto(struct ctproto_handler *h)
-{
- list_del(&h->head);
-}
-
-int dump_expect_list()
-{
- struct ctnl_msg_handler h = {
- .type = IPCTNL_MSG_EXP_NEW,
- .handler = expect_handler
- };
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK_EXP, 0)) < 0)
- return ret;
-
- ctnl_register_handler(&cth, &h);
-
- ret = ctnl_list_expect(&cth, AF_INET);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int flush_conntrack()
-{
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK, 0)) < 0)
- return ret;
-
- ret = ctnl_flush_conntrack(&cth);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int get_expect(struct ctnl_tuple *tuple)
-{
- struct ctnl_msg_handler h = {
- .type = IPCTNL_MSG_EXP_NEW,
- .handler = expect_handler
- };
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK_EXP, 0)) < 0)
- return 0;
-
- ctnl_register_handler(&cth, &h);
-
- ret = ctnl_get_expect(&cth, tuple);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int create_expectation(struct ctnl_tuple *tuple,
- struct ctnl_tuple *exptuple,
- struct ctnl_tuple *mask,
- unsigned long timeout)
-{
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK_EXP, 0)) < 0)
- return ret;
-
-
- ret = ctnl_new_expect(&cth, tuple, exptuple, mask, timeout);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int delete_expectation(struct ctnl_tuple *tuple)
-{
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK_EXP, 0)) < 0)
- return ret;
-
- ret = ctnl_del_expect(&cth, tuple);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int event_expectation(unsigned int event_mask)
-{
- struct ctnl_msg_handler hnew = {
- .type = IPCTNL_MSG_EXP_NEW,
- .handler = expect_handler
- };
- struct ctnl_msg_handler hdestroy = {
- .type = IPCTNL_MSG_EXP_DELETE,
- .handler = expect_handler
- };
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK_EXP, event_mask)) < 0)
- return ret;
-
- ctnl_register_handler(&cth, &hnew);
- ctnl_register_handler(&cth, &hdestroy);
- ret = ctnl_event_expect(&cth, AF_INET);
- ctnl_close(&cth);
-
- return ret;
-}
-
-int flush_expectation()
-{
- int ret;
-
- if ((ret = ctnl_open(&cth, NFNL_SUBSYS_CTNETLINK_EXP, 0)) < 0)
- return ret;
-
- ret = ctnl_flush_expect(&cth);
- ctnl_close(&cth);
-
- return ret;
-}
-