summaryrefslogtreecommitdiffstats
path: root/src/libnetfilter_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnetfilter_log.c')
-rw-r--r--src/libnetfilter_log.c302
1 files changed, 229 insertions, 73 deletions
diff --git a/src/libnetfilter_log.c b/src/libnetfilter_log.c
index 567049c..339c961 100644
--- a/src/libnetfilter_log.c
+++ b/src/libnetfilter_log.c
@@ -4,7 +4,7 @@
* (C) 2005, 2008-2010 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 version 2
+ * it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation (or any later at your option)
*
* This program is distributed in the hope that it will be useful,
@@ -33,6 +33,9 @@
#include <libnfnetlink/libnfnetlink.h>
#include <libnetfilter_log/libnetfilter_log.h>
+#include <libmnl/libmnl.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
/**
* \mainpage
*
@@ -82,7 +85,7 @@ struct nflog_g_handle
int nflog_errno;
/***********************************************************************
- * low level stuff
+ * low level stuff
***********************************************************************/
static void del_gh(struct nflog_g_handle *gh)
@@ -158,11 +161,6 @@ static int __nflog_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
return gh->cb(gh, nfmsg, &nfldata, gh->data);
}
-static struct nfnl_callback pkt_cb = {
- .call = &__nflog_rcv_pkt,
- .attr_count = NFULA_MAX,
-};
-
/* public interface */
struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h)
@@ -182,15 +180,15 @@ struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h)
*
* Here's a little code snippet that binds to the group 100:
* \verbatim
- printf("binding this socket to group 0\n");
- qh = nflog_bind_group(h, 0);
- if (!qh) {
- fprintf(stderr, "no handle for grup 0\n");
+ printf("binding this socket to group 100\n");
+ gh = nflog_bind_group(h, 100);
+ if (!gh) {
+ fprintf(stderr, "no handle for group 100\n");
exit(1);
}
printf("setting copy_packet mode\n");
- if (nflog_set_mode(qh, NFULNL_COPY_PACKET, 0xffff) < 0) {
+ if (nflog_set_mode(gh, NFULNL_COPY_PACKET, 0xffff) < 0) {
fprintf(stderr, "can't set packet copy mode\n");
exit(1);
}
@@ -207,22 +205,37 @@ struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h)
}
\endverbatim
*
- * Data and information about the packet can be fetch by using message parsing
- * functions (See \link Parsing \endlink).
+ * Data and information about the packet can be fetched by using message parsing
+ * \htmlonly
+ functions (See <a class="el" href="group__Parsing.html">Parsing</a>).
+\endhtmlonly
+ * \manonly
+functions.
+.PP
+\fBSee also:\fP
+.RS 4
+\fBLibrarySetup\fP man page (\fBman nflog_open\fP)
+.br
+\fBParsing\fP man page (\fBman nflog_get_gid\fP)
+.RE
+.PP
+.SH SYNOPSIS
+.nf
+\fB
+#include <stddef.h>
+#include <libnetfilter_log/libnetfilter_log.h>
+\endmanonly
* @{
*/
/**
* nflog_fd - get the file descriptor associated with the nflog handler
- * \param log handler obtained via call to nflog_open()
+ * \param h handler obtained via call to nflog_open()
*
* \return a file descriptor for the netlink connection associated with the
* given log connection handle. The file descriptor can then be used for
* receiving the logged packets for processing.
*
- * This function returns a file descriptor that can be used for communication
- * over the netlink connection associated with the given log connection
- * handle.
*/
int nflog_fd(struct nflog_handle *h)
{
@@ -237,15 +250,18 @@ struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh)
{
struct nflog_handle *h;
int err;
+ struct nfnl_callback pkt_cb = {
+ .call = &__nflog_rcv_pkt,
+ .attr_count = NFULA_MAX,
+ };
- h = malloc(sizeof(*h));
+ h = calloc(1, sizeof(*h));
if (!h)
return NULL;
- memset(h, 0, sizeof(*h));
h->nfnlh = nfnlh;
- h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
+ h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
NFULNL_MSG_MAX, 0);
if (!h->nfnlssh) {
/* FIXME: nflog_errno */
@@ -280,7 +296,9 @@ out_free:
* it by calling nflog_close(). A new netlink connection is obtained internally
* and associated with the log connection handle returned.
*
- * \return a pointer to a new log handle or NULL on failure.
+ * \return a pointer to a new log handle or NULL on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
struct nflog_handle *nflog_open(void)
{
@@ -307,6 +325,20 @@ struct nflog_handle *nflog_open(void)
* @}
*/
+/**
+ * \addtogroup Log
+ * @{
+ */
+
+/**
+ * nflog_callback_register - register function to process packets
+ *
+ * \param gh Netfilter log group handle obtained by call to nflog_bind_group()
+ * \param cb callback function to call for each logged packet
+ * \param data custom data to pass to the callback function
+ \return 0
+ */
+
int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb,
void *data)
{
@@ -316,17 +348,42 @@ int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb,
return 0;
}
+/**
+ * nflog_handle_packet - handle a packet received from the nflog subsystem
+ * \param h Netfilter log handle obtained via call to nflog_open()
+ * \param buf nflog data received from the kernel
+ * \param len length of packet data in buffer
+ *
+ * Triggers an associated callback for each packet contained in \b buf.
+ * Data can be read from the queue using nflog_fd() and \b recv().
+ * See example code in the Detailed Description.
+ * \return 0 on success, -1 if either the callback returned -ve or \b buf
+ * contains corrupt data. \b errno is not reliably set:
+ * caller should zeroise first if interested.
+ */
+
int nflog_handle_packet(struct nflog_handle *h, char *buf, int len)
{
return nfnl_handle_packet(h->nfnlh, buf, len);
}
/**
+ * @}
+ */
+
+/**
* \addtogroup LibrarySetup
*
* When the program has finished with libnetfilter_log, it has to call
* the nflog_close() function to release all associated resources.
*
+ * \manonly
+.SH SYNOPSIS
+.nf
+\fB
+#include <netinet/in.h>
+#include <libnetfilter_log/libnetfilter_log.h>
+\endmanonly
* @{
*/
@@ -336,7 +393,9 @@ int nflog_handle_packet(struct nflog_handle *h, char *buf, int len)
*
* This function closes the nflog handler and free associated resources.
*
- * \return 0 on success, non-zero on failure.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * as for __close__(2)
*/
int nflog_close(struct nflog_handle *h)
{
@@ -353,7 +412,9 @@ int nflog_close(struct nflog_handle *h)
* Binds the given log connection handle to process packets belonging to
* the given protocol family (ie. PF_INET, PF_INET6, etc).
*
- * \return integer inferior to 0 in case of failure
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * \b EOPNOTSUPP Not running as root
*/
int nflog_bind_pf(struct nflog_handle *h, uint16_t pf)
{
@@ -368,6 +429,9 @@ int nflog_bind_pf(struct nflog_handle *h, uint16_t pf)
*
* Unbinds the given nflog handle from processing packets belonging
* to the given protocol family.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * \b EOPNOTSUPP Not running as root
*/
int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf)
{
@@ -388,21 +452,27 @@ int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf)
* \param h Netfilter log handle obtained via call to nflog_open()
* \param num the number of the group to bind to
*
- * \return a nflog_g_handle pointing to the newly created group
+ * \return an nflog_g_handle for the newly created group or NULL on failure.
+ * \par Errors
+ * \b EBUSY This process has already binded to the group
+ * \n
+ * \b EOPNOTSUPP Request rejected by kernel. Another process has already
+ * binded to the group, or this process is not running as root
*/
struct nflog_g_handle *
nflog_bind_group(struct nflog_handle *h, uint16_t num)
{
struct nflog_g_handle *gh;
-
- if (find_gh(h, num))
+
+ if (find_gh(h, num)) {
+ errno = EBUSY;
return NULL;
-
- gh = malloc(sizeof(*gh));
+ }
+
+ gh = calloc(1, sizeof(*gh));
if (!gh)
return NULL;
- memset(gh, 0, sizeof(*gh));
gh->h = h;
gh->id = num;
@@ -428,7 +498,9 @@ nflog_bind_group(struct nflog_handle *h, uint16_t num)
* nflog_unbind_group - unbind a group handle.
* \param gh Netfilter log group handle obtained via nflog_bind_group()
*
- * \return -1 in case of error and errno is explicity in case of error.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_unbind_group(struct nflog_g_handle *gh)
{
@@ -443,7 +515,7 @@ int nflog_unbind_group(struct nflog_g_handle *gh)
/**
* nflog_set_mode - set the amount of packet data that nflog copies to userspace
- * \param qh Netfilter log handle obtained by call to nflog_bind_group().
+ * \param gh Netfilter log group handle obtained by call to nflog_bind_group().
* \param mode the part of the packet that we are interested in
* \param range size of the packet that we want to get
*
@@ -454,7 +526,9 @@ int nflog_unbind_group(struct nflog_g_handle *gh)
* - NFULNL_COPY_META - copy only packet metadata
* - NFULNL_COPY_PACKET - copy entire packet
*
- * \return -1 on error; >= otherwise.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_set_mode(struct nflog_g_handle *gh,
uint8_t mode, uint32_t range)
@@ -479,15 +553,17 @@ int nflog_set_mode(struct nflog_g_handle *gh,
/**
* nflog_set_timeout - set the maximum time to push log buffer for this group
- * \param gh Netfilter log handle obtained by call to nflog_bind_group().
+ * \param gh Netfilter log group handle obtained by call to nflog_bind_group().
* \param timeout Time to wait until the log buffer is pushed to userspace
*
- * This function allows to set the maximum time that nflog waits until it
+ * This function allows one to set the maximum time that nflog waits until it
* pushes the log buffer to userspace if no new logged packets have occured.
* Basically, nflog implements a buffer to reduce the computational cost
* of delivering the log message to userspace.
*
- * \return -1 in case of error and errno is explicity set.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout)
{
@@ -506,13 +582,15 @@ int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout)
/**
* nflog_set_qthresh - set the maximum amount of logs in buffer for this group
- * \param gh Netfilter log handle obtained by call to nflog_bind_group().
+ * \param gh Netfilter log group handle obtained by call to nflog_bind_group().
* \param qthresh Maximum number of log entries
*
* This function determines the maximum number of log entries in the buffer
* until it is pushed to userspace.
*
- * \return -1 in case of error and errno is explicity set.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh)
{
@@ -531,17 +609,19 @@ int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh)
/**
* nflog_set_nlbufsiz - set the size of the nflog buffer for this group
- * \param gh Netfilter log handle obtained by call to nflog_bind_group().
+ * \param gh Netfilter log group handle obtained by call to nflog_bind_group().
* \param nlbufsiz Size of the nflog buffer
*
* This function sets the size (in bytes) of the buffer that is used to
* stack log messages in nflog.
*
- * NOTE: The use of this function is strongly discouraged. The default
+ * \warning The use of this function is strongly discouraged. The default
* buffer size (which is one memory page) provides the optimum results
* in terms of performance. Do not use this function in your applications.
*
- * \return -1 in case of error and errno is explicity set.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz)
{
@@ -567,15 +647,18 @@ int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz)
/**
* nflog_set_flags - set the nflog flags for this group
- * \param gh Netfilter log handle obtained by call to nflog_bind_group().
+ * \param gh Netfilter log group handle obtained by call to nflog_bind_group().
* \param flags Flags that you want to set
*
* There are two existing flags:
*
* - NFULNL_CFG_F_SEQ: This enables local nflog sequence numbering.
* - NFULNL_CFG_F_SEQ_GLOBAL: This enables global nflog sequence numbering.
+ * - NFULNL_CFG_F_CONNTRACK: This enables to acquire related conntrack.
*
- * \return -1 in case of error and errno is explicity set.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags)
{
@@ -598,6 +681,13 @@ int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags)
/**
* \defgroup Parsing Message parsing functions
+ * \manonly
+.SH SYNOPSIS
+.nf
+\fB
+#include <stddef.h>
+#include <libnetfilter_log/libnetfilter_log.h>
+\endmanonly
* @{
*/
@@ -612,8 +702,8 @@ int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags)
* The nfulnl_msg_packet_hdr structure is defined in libnetfilter_log.h as:
*\verbatim
struct nfulnl_msg_packet_hdr {
- uint16_t hw_protocol; // hw protocol (network order)
- uint8_t hook; // netfilter hook
+ uint16_t hw_protocol; // hw protocol (network order)
+ uint8_t hook; // netfilter hook
uint8_t _pad;
} __attribute__ ((packed));
\endverbatim
@@ -673,9 +763,11 @@ uint32_t nflog_get_nfmark(struct nflog_data *nfad)
* \param nfad Netlink packet data handle passed to callback function
* \param tv structure to fill with timestamp info
*
- * Retrieves the received timestamp when the given logged packet.
+ * Retrieves the received timestamp from the given logged packet.
*
- * \return 0 on success, a negative value on failure.
+ * \return 0 on success, -1 on failure with \b errno set.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv)
{
@@ -700,8 +792,8 @@ int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv)
* returned index is 0, the packet was locally generated or the input
* interface is not known (ie. POSTROUTING?).
*
- * \warning all nflog_get_dev() functions return 0 if not set, since linux
- * only allows ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1)
+ * \warning all nflog_get_dev() functions return 0 if not set, since Linux
+ * only allows ifindex >= 1, see net/core/dev.c:9819 (in 5.14.3)
*/
uint32_t nflog_get_indev(struct nflog_data *nfad)
{
@@ -710,6 +802,7 @@ uint32_t nflog_get_indev(struct nflog_data *nfad)
/**
* nflog_get_physindev - get the physical interface that the packet was received
+ * through
* \param nfad Netlink packet data handle passed to callback function
*
* \return The index of the physical device the packet was received via.
@@ -722,10 +815,10 @@ uint32_t nflog_get_physindev(struct nflog_data *nfad)
}
/**
- * nflog_get_outdev - gets the interface that the packet will be routed out
+ * nflog_get_outdev - gets the interface that the packet will be routed to
* \param nfad Netlink packet data handle passed to callback function
*
- * \return The index of the device the packet will be sent out. If the
+ * \return The index of the device the packet will be sent to. If the
* returned index is 0, the packet is destined for localhost or the output
* interface is not yet known (ie. PREROUTING?).
*/
@@ -735,15 +828,12 @@ uint32_t nflog_get_outdev(struct nflog_data *nfad)
}
/**
- * nflog_get_physoutdev - get the physical interface that the packet output
+ * nflog_get_physoutdev - get the physical interface for packet output
* \param nfad Netlink packet data handle passed to callback function
*
- * The index of the physical device the packet will be sent out. If the
+ * \return Index of physical device the packet will be routed to. If the
* returned index is 0, the packet is destined for localhost or the
* physical output interface is not yet known (ie. PREROUTING?).
- *
- * \return The index of physical interface that the packet output will be
- * routed out.
*/
uint32_t nflog_get_physoutdev(struct nflog_data *nfad)
{
@@ -762,12 +852,16 @@ uint32_t nflog_get_physoutdev(struct nflog_data *nfad)
*
* The nfulnl_msg_packet_hw structure is defined in libnetfilter_log.h as:
* \verbatim
- struct nfulnl_msg_packet_hw {
- uint16_t hw_addrlen;
- uint16_t _pad;
- uint8_t hw_addr[8];
- } __attribute__ ((packed));
+ struct nfulnl_msg_packet_hw {
+ uint16_t hw_addrlen; // Network Byte Order
+ uint16_t _pad;
+ uint8_t hw_addr[8];
+ } __attribute__ ((packed));
\endverbatim
+ *
+ * \return Pointer to struct nfulnl_msg_packet_hw from originating host
+ * or NULL if none available (e.g. locally-originated packet not for \b lo
+ * interface).
*/
struct nfulnl_msg_packet_hw *nflog_get_packet_hw(struct nflog_data *nfad)
{
@@ -784,7 +878,7 @@ struct nfulnl_msg_packet_hw *nflog_get_packet_hw(struct nflog_data *nfad)
* data retrieved by this function will depend on the mode set with the
* nflog_set_mode() function.
*
- * \return -1 on error, otherwise > 0.
+ * \return payload length, or -1 if this is not available
*/
int nflog_get_payload(struct nflog_data *nfad, char **data)
{
@@ -800,7 +894,7 @@ int nflog_get_payload(struct nflog_data *nfad, char **data)
* \param nfad Netlink packet data handle passed to callback function
*
* \return the string prefix that is specified as argument to the iptables'
- * NFLOG target.
+ * NFLOG target or NULL if this is not available.
*/
char *nflog_get_prefix(struct nflog_data *nfad)
{
@@ -808,10 +902,13 @@ char *nflog_get_prefix(struct nflog_data *nfad)
}
/**
- * nflog_get_uid - get the UID of the user that has generated the packet
+ * nflog_get_uid - get the UID of the user that generated the packet
* \param nfad Netlink packet data handle passed to callback function
+ * \param uid UID of the user that generated the packet,
+ * if the function returns zero
*
- * \return the UID of the user that has genered the packet, if any.
+ * \return 0 on success or -1 if UID was unavailable (\b uid
+ * is then invalid)
*/
int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid)
{
@@ -825,8 +922,11 @@ int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid)
/**
* nflog_get_gid - get the GID of the user that has generated the packet
* \param nfad Netlink packet data handle passed to callback function
+ * \param gid GID of the user that generated the packet,
+ * if the function returns zero
*
- * \return the GID of the user that has genered the packet, if any.
+ * \return 0 on success or -1 if GID was unavailable (\b gid
+ * is then invalid)
*/
int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid)
{
@@ -840,10 +940,13 @@ int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid)
/**
* nflog_get_seq - get the local nflog sequence number
* \param nfad Netlink packet data handle passed to callback function
+ * \param seq local nflog sequence number,
+ * if the function returns zero
*
* You must enable this via nflog_set_flags().
*
- * \return the local nflog sequence number.
+ * \return 0 on success or -1 if sequence number was unavailable (\b seq
+ * is then invalid)
*/
int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq)
{
@@ -857,10 +960,13 @@ int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq)
/**
* nflog_get_seq_global - get the global nflog sequence number
* \param nfad Netlink packet data handle passed to callback function
+ * \param seq global nflog sequence number,
+ * if the function returns zero
*
* You must enable this via nflog_set_flags().
*
- * \return the global nflog sequence number.
+ * \return 0 on success or -1 if sequence number was unavailable (\b seq
+ * is then invalid)
*/
int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq)
{
@@ -872,6 +978,38 @@ int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq)
}
/**
+ * nflog_get_ct_id - get the conntrack id
+ * \param nfad Netlink packet data handle passed to callback function
+ * \param id conntrack id, if the function returns zero
+ *
+ * You must enable this via nflog_set_flags().
+ *
+ * \return 0 on success or -1 if conntrack itself or its id was unavailable
+ */
+int nflog_get_ctid(struct nflog_data *nfad, uint32_t *id)
+{
+ struct nlattr *cta = (struct nlattr *)nfad->nfa[NFULA_CT - 1];
+ struct nlattr *attr, *ida = NULL;
+
+ if (!cta)
+ return -1;
+
+ mnl_attr_for_each_nested(attr, cta) {
+ if (mnl_attr_get_type(attr) == CTA_ID) {
+ ida = attr;
+ break;
+ }
+ }
+
+ if (!ida || mnl_attr_validate(ida, MNL_TYPE_U32) < 0)
+ return -1;
+
+ *id = ntohl(mnl_attr_get_u32(ida));
+
+ return 0;
+}
+
+/**
* @}
*/
@@ -887,7 +1025,13 @@ do { \
} while (0)
/**
- * \defgroup Printing
+ * \defgroup Printing Printing
+ * \manonly
+.SH SYNOPSIS
+.nf
+\fB
+#include <libnetfilter_log/libnetfilter_log.h>
+\endmanonly
* @{
*/
@@ -907,20 +1051,23 @@ do { \
* - NFLOG_XML_PHYSDEV: include the physical device information
* - NFLOG_XML_PAYLOAD: include the payload (in hexadecimal)
* - NFLOG_XML_TIME: include the timestamp
+ * - NFLOG_XML_CTID: include conntrack id
* - NFLOG_XML_ALL: include all the logging information (all flags set)
*
- * You can combine this flags with an binary OR.
+ * You can combine these flags with a bitwise OR.
*
* \return -1 in case of failure, otherwise the length of the string that
* would have been printed into the buffer (in case that there is enough
* room in it). See snprintf() return value for more information.
+ * \par Errors
+ * from underlying calls, in exceptional circumstances
*/
int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)
{
- struct nfulnl_msg_packet_hdr *ph;
- struct nfulnl_msg_packet_hw *hwph;
- uint32_t mark, ifi;
int size, offset = 0, len = 0, ret;
+ struct nfulnl_msg_packet_hw *hwph;
+ struct nfulnl_msg_packet_hdr *ph;
+ uint32_t mark, ifi, ctid;
char *data;
size = snprintf(buf + offset, rem, "<log>");
@@ -1039,6 +1186,15 @@ int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)
SNPRINTF_FAILURE(size, rem, offset, len);
}
+ if (flags & NFLOG_XML_CTID) {
+ ret = nflog_get_ctid(tb, &ctid);
+ if (ret >= 0) {
+ size = snprintf(buf + offset, rem,
+ "<ctid>%u</ctid>", ctid);
+ SNPRINTF_FAILURE(size, rem, offset, len);
+ }
+ }
+
ret = nflog_get_payload(tb, &data);
if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) {
int i;