diff options
Diffstat (limited to 'input/packet/ulogd_inppkt_NFLOG.c')
-rw-r--r-- | input/packet/ulogd_inppkt_NFLOG.c | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c index a367959..4fdeb12 100644 --- a/input/packet/ulogd_inppkt_NFLOG.c +++ b/input/packet/ulogd_inppkt_NFLOG.c @@ -12,6 +12,13 @@ #include <ulogd/ulogd.h> #include <libnfnetlink/libnfnetlink.h> #include <libnetfilter_log/libnetfilter_log.h> +#ifdef BUILD_NFCT +#include <libmnl/libmnl.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#else +struct nf_conntrack; +#endif + #ifndef NFLOG_GROUP_DEFAULT #define NFLOG_GROUP_DEFAULT 0 @@ -33,7 +40,7 @@ struct nflog_input { /* configuration entries */ static struct config_keyset libulog_kset = { - .num_ces = 11, + .num_ces = 12, .ces = { { .key = "bufsize", @@ -102,6 +109,12 @@ static struct config_keyset libulog_kset = { .options = CONFIG_OPT_NONE, .u.value = 0, }, + { + .key = "attach_conntrack", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = 0, + }, } }; @@ -116,6 +129,7 @@ static struct config_keyset libulog_kset = { #define nlsockbufmaxsize_ce(x) (x->ces[8]) #define nlthreshold_ce(x) (x->ces[9]) #define nltimeout_ce(x) (x->ces[10]) +#define attach_conntrack_ce(x) (x->ces[11]) enum nflog_keys { NFLOG_KEY_RAW_MAC = 0, @@ -141,6 +155,7 @@ enum nflog_keys { NFLOG_KEY_RAW_MAC_SADDR, NFLOG_KEY_RAW_MAC_ADDRLEN, NFLOG_KEY_RAW, + NFLOG_KEY_RAW_CT, }; static struct ulogd_key output_keys[] = { @@ -312,11 +327,52 @@ static struct ulogd_key output_keys[] = { .flags = ULOGD_RETF_NONE, .name = "raw", }, + [NFLOG_KEY_RAW_CT] = { + .type = ULOGD_RET_RAW, + .flags = ULOGD_RETF_NONE, + .name = "ct", + }, }; +struct nf_conntrack *build_ct(struct nfgenmsg *nfmsg) +{ +#ifdef BUILD_NFCT + struct nlmsghdr *nlh = + (struct nlmsghdr *)((void *)nfmsg - sizeof(*nlh)); + struct nlattr *attr, *ctattr = NULL; + struct nf_conntrack *ct; + + mnl_attr_for_each(attr, nlh, sizeof(struct nfgenmsg)) { + if (mnl_attr_get_type(attr) == NFULA_CT) { + ctattr = attr; + break; + } + } + if (!ctattr) + return NULL; + + ct = nfct_new(); + if (!ct) { + ulogd_log(ULOGD_ERROR, "failed to allocate nfct\n"); + return NULL; + } + if (nfct_payload_parse(mnl_attr_get_payload(ctattr), + mnl_attr_get_payload_len(ctattr), + nfmsg->nfgen_family, ct) < 0) { + ulogd_log(ULOGD_ERROR, "failed to parse nfct payload\n"); + nfct_destroy(ct); + return NULL; + } + + return ct; +#else + return NULL; +#endif +} + static inline int interp_packet(struct ulogd_pluginstance *upi, uint8_t pf_family, - struct nflog_data *ldata) + struct nflog_data *ldata, struct nf_conntrack *ct) { struct ulogd_key *ret = upi->output.keys; @@ -397,6 +453,9 @@ interp_packet(struct ulogd_pluginstance *upi, uint8_t pf_family, okey_set_ptr(&ret[NFLOG_KEY_RAW], ldata); + if (ct != NULL) + okey_set_ptr(&ret[NFLOG_KEY_RAW_CT], ct); + ulogd_propagate_results(upi); return 0; } @@ -471,16 +530,25 @@ static int msg_cb(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg, { struct ulogd_pluginstance *upi = data; struct ulogd_pluginstance *npi = NULL; + void *ct = build_ct(nfmsg); int ret = 0; /* since we support the re-use of one instance in several * different stacks, we duplicate the message to let them know */ llist_for_each_entry(npi, &upi->plist, plist) { - ret = interp_packet(npi, nfmsg->nfgen_family, nfa); + ret = interp_packet(npi, nfmsg->nfgen_family, nfa, ct); if (ret != 0) - return ret; + goto release_ct; } - return interp_packet(upi, nfmsg->nfgen_family, nfa); + ret = interp_packet(upi, nfmsg->nfgen_family, nfa, ct); + +release_ct: +#ifdef BUILD_NFCT + if (ct != NULL) + nfct_destroy(ct); +#endif + + return ret; } static int configure(struct ulogd_pluginstance *upi, @@ -595,8 +663,10 @@ static int start(struct ulogd_pluginstance *upi) flags = 0; if (seq_ce(upi->config_kset).u.value != 0) flags = NFULNL_CFG_F_SEQ; - if (seq_ce(upi->config_kset).u.value != 0) + if (seq_global_ce(upi->config_kset).u.value != 0) flags |= NFULNL_CFG_F_SEQ_GLOBAL; + if (attach_conntrack_ce(upi->config_kset).u.value != 0) + flags |= NFULNL_CFG_F_CONNTRACK; if (flags) { if (nflog_set_flags(ui->nful_gh, flags) < 0) ulogd_log(ULOGD_ERROR, "unable to set flags 0x%x\n", |