CT_INFO is absolutely necessary while rther are not due to presence of NFLOG_KEY_RAW. Anyway i did this way Added missed dependency on LIBMNL here --- configure.ac | 3 +- input/packet/Makefile.am | 5 +- input/packet/ulogd_inppkt_NFLOG.c | 105 ++++++++++++++++++++++-------- 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/configure.ac b/configure.ac index daaf69f..5b55e1c 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,8 @@ AC_ARG_ENABLE([nflog], [enable_nflog=$enableval], [enable_nflog=yes]) AS_IF([test "x$enable_nflog" = "xyes"], - [PKG_CHECK_MODULES([LIBNETFILTER_LOG], [libnetfilter_log >= 1.0.2]) + [PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.5]) + PKG_CHECK_MODULES([LIBNETFILTER_LOG], [libnetfilter_log >= 1.0.2]) AC_DEFINE([BUILD_NFLOG], [1], [Building nflog module])], [enable_nflog=no]) AM_CONDITIONAL([BUILD_NFLOG], [test "x$enable_nflog" = "xyes"]) diff --git a/input/packet/Makefile.am b/input/packet/Makefile.am index 20c51ec..79a7ddb 100644 --- a/input/packet/Makefile.am +++ b/input/packet/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/Make_global.am -AM_CPPFLAGS += ${LIBNETFILTER_LOG_CFLAGS} ${LIBNETFILTER_CONNTRACK_CFLAGS} +AM_CPPFLAGS += ${LIBNETFILTER_LOG_CFLAGS} ${LIBNETFILTER_CONNTRACK_CFLAGS} ${LIBMNL_CFLAGS} pkglib_LTLIBRARIES = ulogd_inppkt_UNIXSOCK.la @@ -12,6 +12,7 @@ pkglib_LTLIBRARIES += ulogd_inppkt_NFLOG.la ulogd_inppkt_NFLOG_la_SOURCES = ulogd_inppkt_NFLOG.c ulogd_inppkt_NFLOG_la_LDFLAGS = -avoid-version -module -ulogd_inppkt_NFLOG_la_LIBADD = $(LIBNETFILTER_LOG_LIBS) \ +ulogd_inppkt_NFLOG_la_LIBADD = $(LIBMNL_LIBS) \ + $(LIBNETFILTER_LOG_LIBS) \ $(LIBNETFILTER_CONNTRACK_LIBS) endif diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c index b7042be..1e69369 100644 --- a/input/packet/ulogd_inppkt_NFLOG.c +++ b/input/packet/ulogd_inppkt_NFLOG.c @@ -16,10 +16,15 @@ #ifdef BUILD_NFCT #include #include +#include #else struct nf_conntrack; #endif +struct conn_track_info { + struct nf_conntrack *ct; + uint32_t info; +}; #ifndef NFLOG_GROUP_DEFAULT #define NFLOG_GROUP_DEFAULT 0 @@ -154,6 +159,8 @@ enum nflog_keys { NFLOG_KEY_OOB_SEQ_LOCAL, NFLOG_KEY_OOB_SEQ_GLOBAL, NFLOG_KEY_OOB_FAMILY, + NFLOG_KEY_OOB_VERSION, + NFLOG_KEY_OOB_RES_ID, NFLOG_KEY_OOB_PROTOCOL, NFLOG_KEY_OOB_UID, NFLOG_KEY_OOB_GID, @@ -163,6 +170,7 @@ enum nflog_keys { NFLOG_KEY_RAW_MAC_ADDRLEN, NFLOG_KEY_RAW, NFLOG_KEY_RAW_CT, + NFLOG_KEY_CT_INFO, }; static struct ulogd_key output_keys[] = { @@ -304,6 +312,24 @@ static struct ulogd_key output_keys[] = { .flags = ULOGD_RETF_NONE, .name = "oob.family", }, + [NFLOG_KEY_OOB_VERSION] = { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "oob.version", + .ipfix = { + .vendor = IPFIX_VENDOR_NETFILTER, + .field_id = IPFIX_NF_hook, + }, + }, + [NFLOG_KEY_OOB_RES_ID] = { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "oob.resid", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_flowStartSeconds, + }, + }, [NFLOG_KEY_OOB_PROTOCOL] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, @@ -339,47 +365,67 @@ static struct ulogd_key output_keys[] = { .flags = ULOGD_RETF_NONE, .name = "ct", }, + [NFLOG_KEY_CT_INFO] = { + .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .name = "ct_info", + }, }; -struct nf_conntrack *build_ct(struct nfgenmsg *nfmsg) +void build_ct(struct nfgenmsg *nfmsg, struct conn_track_info *res) { #ifdef BUILD_NFCT struct nlmsghdr *nlh = (struct nlmsghdr *)((void *)nfmsg - sizeof(*nlh)); struct nlattr *attr, *ctattr = NULL; - struct nf_conntrack *ct; + int found = 0; + + res->ct = NULL; + res->info = (uint32_t)-1; mnl_attr_for_each(attr, nlh, sizeof(struct nfgenmsg)) { - if (mnl_attr_get_type(attr) == NFULA_CT) { - ctattr = attr; + switch (mnl_attr_get_type(attr)) { + case NFULA_CT: + { + ctattr = attr; + found |= 1; + break; + } + case NFULA_CT_INFO: { + res->info = ntohl(mnl_attr_get_u32(attr)); + found |= 2; + break; + } + } + if (found == 3) { break; } } - if (!ctattr) - return NULL; - ct = nfct_new(); - if (!ct) { + if (!ctattr) { + ulogd_log(ULOGD_INFO, "ct attribute not present\n"); + return; + } + + res->ct = nfct_new(); + if (!res->ct) { ulogd_log(ULOGD_ERROR, "failed to allocate nfct\n"); - return NULL; + return; } if (nfct_payload_parse(mnl_attr_get_payload(ctattr), mnl_attr_get_payload_len(ctattr), - nfmsg->nfgen_family, ct) < 0) { + nfmsg->nfgen_family, res->ct) < 0) { ulogd_log(ULOGD_ERROR, "failed to parse nfct payload\n"); - nfct_destroy(ct); - return NULL; + nfct_destroy(res->ct); + res->ct = NULL; + return; } - - return ct; -#else - return NULL; #endif } static inline int -interp_packet(struct ulogd_pluginstance *upi, uint8_t pf_family, - struct nflog_data *ldata, struct nf_conntrack *ct) +interp_packet(struct ulogd_pluginstance *upi, struct nfgenmsg *header, + struct nflog_data *ldata, struct conn_track_info *ct) { struct ulogd_key *ret = upi->output.keys; @@ -396,8 +442,9 @@ interp_packet(struct ulogd_pluginstance *upi, uint8_t pf_family, uint32_t uid; uint32_t gid; - okey_set_u8(&ret[NFLOG_KEY_OOB_FAMILY], - pf_family); + okey_set_u8(&ret[NFLOG_KEY_OOB_FAMILY], header->nfgen_family); + okey_set_u16(&ret[NFLOG_KEY_OOB_RES_ID], ntohs(header->res_id)); + okey_set_u8(&ret[NFLOG_KEY_OOB_VERSION], header->version); okey_set_u8(&ret[NFLOG_KEY_RAW_LABEL], label_ce(upi->config_kset).u.value); @@ -460,8 +507,10 @@ 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); + if (ct->ct != NULL) { + okey_set_ptr(&ret[NFLOG_KEY_RAW_CT], ct->ct); + okey_set_u32(&ret[NFLOG_KEY_CT_INFO], ct->info); + } ulogd_propagate_results(upi); return 0; @@ -537,22 +586,24 @@ 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); + struct conn_track_info ct; int ret = 0; + build_ct(nfmsg, &ct); + /* 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, ct); + ret = interp_packet(npi, nfmsg, nfa, &ct); if (ret != 0) goto release_ct; } - ret = interp_packet(upi, nfmsg->nfgen_family, nfa, ct); + ret = interp_packet(upi, nfmsg, nfa, &ct); release_ct: #ifdef BUILD_NFCT - if (ct != NULL) - nfct_destroy(ct); + if (ct.ct != NULL) + nfct_destroy(ct.ct); #endif return ret; -- 2.51.0