diff options
author | laforge <laforge> | 2005-11-04 14:03:11 +0000 |
---|---|---|
committer | laforge <laforge> | 2005-11-04 14:03:11 +0000 |
commit | 336b6a34b4817411b2f756c8355428831b62c436 (patch) | |
tree | 9d509364fd1765e93f1835c3001f49edab085cd3 /input/flow/ulogd_inpflow_NFCT.c | |
parent | bf2e90b99abbb4eabec9ebcc96b34a9d6bc1914d (diff) |
rename CTNL to NFCT
Diffstat (limited to 'input/flow/ulogd_inpflow_NFCT.c')
-rw-r--r-- | input/flow/ulogd_inpflow_NFCT.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/input/flow/ulogd_inpflow_NFCT.c b/input/flow/ulogd_inpflow_NFCT.c new file mode 100644 index 0000000..6fca16e --- /dev/null +++ b/input/flow/ulogd_inpflow_NFCT.c @@ -0,0 +1,220 @@ +/* ulogd_input_CTNL.c, Version $Revision$ + * + * ulogd input plugin for ctnetlink + * + * (C) 2005 by Harald Welte <laforge@gnumonks.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + */ + +#include <errno.h> +#include <ulogd/ulogd.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> + +struct nfct_pluginstance { + struct nfct_handle *cth; + struct ulogd_fd nfct_fd; +}; + + +static struct ulogd_key nfct_okeys[] = { + { + .type = ULOGD_RET_IPADDR, + .flags = ULOGD_RETF_NONE, + .key = "ip.saddr", + .ipfix = { }, + }, + { + .type = ULOGD_RET_IPADDR, + .flags = ULOGD_RETF_NONE, + .key = "ip.daddr", + .ipfix = { }, + }, + { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "ip.protocol", + .ipfix = { }, + }, + { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.sport", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = 7, + }, + }, + { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.dport", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = 11, + }, + }, + { + .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .name = "raw.pktlen", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = 1, + }, + }, + { + .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .name = "raw.pktcount", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = 2, + }, + }, + +}; + +static int propagate_ct_flow(struct ulogd_pluginstance *upi, + struct nfct_conntrack *ct, + int dir) +{ + struct ulogd_key *ret = upi->output; + + ret[0].u.value.ui32 = ct->tuple[dir].src.v4; + ret[0].flags |= ULOGD_RETF_VALID; + + ret[1].u.value.ui32 = ct->tuple[dir].dst.v4; + ret[1].flags |= ULOGD_RETF_VALID; + + ret[2].u.value.ui8 = ct->tuple[dir].protonum; + ret[2].flags |= ULOGD_RETF_VALID; + + switch (ct->tuple[1].protonum) { + case IPPROTO_TCP: + ret[3].u.value.ui16 = ct->tuple[dir].l4src.tcp.port; + ret[3].flags |= ULOGD_RETF_VALID; + ret[4].u.value.ui16 = ct->tuple[dir].l4dst.tcp.port; + ret[4].flags |= ULOGD_RETF_VALID; + break; + case IPPROTO_UDP: + break; + case IPPROTO_SCTP: + break; + } + + if (dir == NF_CT_DIR_ORIG && flags & NFCT_COUNTERS_ORIG || + dir == NF_CT_DIR_REPLY && flags & NFCT_COUNTERS_REPLY) { + ret[5].u.value.ui64 = ct->counters[dir].bytes; + ret[5].flags |= ULOGD_RETF_VALID; + + ret[6].u.value.ui64 = ct->counters[dir].packets; + ret[6].flags |= ULOGD_RETF_VALID; + } + + return ulogd_propagate_results(upi); +} + +static int propagate_ct(struct ulogd_pluginstance *upi, + struct nfct_conntrack *ct) +{ + int rc; + + rc = propagate_ct_flow(upi, ct, NF_CT_DIR_ORIGINAL); + if (rc < 0) + return rc; + return propagate_ct_flow(upi, ct, NF_CT_DIR_REPLY); +} + +static int event_handler(void *arg, unsigned int flags, int type) +{ + struct nfct_conntrack *ct = foo; + + if (type == NFCT_MSG_NEW) + /* FIXME: build hash table with timestamp of start of + * connection */ + } else if (type == NFCT_MSG_DESTROY) + /* We have the final count of bytes for this connection */ + } + + return 0; +} + +static int read_cb_nfct(int fd, unsigned int what, void *param) +{ + struct nfct_pluginstance *cpi = + (struct ulogd_nfct_pluginstance *) param; + + if (!(what & ULOGD_FD_READ)) + return 0; + + /* FIXME: implement this */ + nfct_event_conntrack(&cpi->cth, AF_INET); +} + +static int constructor_nfct(struct ulogd_pluginstance *upi) +{ + struct nfct_pluginstance *cpi = + (struct nfct_pluginstance *)upi->private; + + memset(cpi, NULL, sizeof(*cpi)); + + /* FIXME: make eventmask configurable */ + cpi->cth = nfct_open(NFNL_SUBSYS_CTNETLINK, NF_NETLINK_CONNTRACK_NEW| + NF_NETLINK_CONNTRACK_DESTROY); + if (!cph->cth) { + print("error opening ctnetlink\n"); + return -1; + } + + nfct_register_callback(cpi->cth, &event_handler); + + cpi->nfct_fd.fd = nfct_fd(cpi->cth); + cpi->nfct_fd.cb = &read_cb_nfct; + cpi->nfct_fd.data = cpi; + cpi->nfct_fd.when = ULOGD_FD_READ; + + ulogd_register_fd(&cpi->nfct_fd); + + return &cpi->upi; +} + + +static int destructor_nfct(struct ulogd_pluginstance *pi) +{ + struct nfct_pluginstance *cpi = (void *) pi; + int rc; + + rc = nfct_close(cpi->cth); + if (rc < 0) + return rc; + + return 0; +} + +static struct ulogd_plugin nfct_plugin = { + .name = "CTNL", + .input = { + .type = ULOGD_DTYPE_SOURCE, + }, + .output = { + .keys = &nfct_okeys, + .num_keys = ARRAY_SIZE(nfct_okeys), + .type = ULOGD_DTYPE_FLOW, + }, + .config_kset = , + .interp = , + .configure = + .start = &constructor_nfct, + .stop = &destructor_nfct, +}; + +void __attribute__ ((constructor)) init(void); + +void init(void) +{ + ulogd_register_plugin(&nfct_plugin); +} + |