From: Tomasz Pala <gotar@polanet.pl>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH ulogd] log NAT events using IPFIX
Date: Tue, 12 Dec 2023 20:45:36 +0100 [thread overview]
Message-ID: <20231212194536.GA8196@polanet.pl> (raw)
In-Reply-To: <20231212184413.GA2168@polanet.pl>
[-- Attachment #1: Type: text/plain, Size: 134 bytes --]
This patch makes IPFIX output plugin to export translated (post-NAT)
IPv4 addresses and ports.
--
Tomasz Pala <gotar@pld-linux.org>
[-- Attachment #2: ulogd2-NAT_events.patch --]
[-- Type: text/plain, Size: 6388 bytes --]
diff --git a/include/ulogd/ipfix_protocol.h b/include/ulogd/ipfix_protocol.h
index 01dd96a..a34ee92 100644
--- a/include/ulogd/ipfix_protocol.h
+++ b/include/ulogd/ipfix_protocol.h
@@ -39,6 +39,7 @@ struct ipfix_vendor_field {
};
/* Information Element Identifiers as of draft-ietf-ipfix-info-11.txt */
+/* Updated list available at https://www.iana.org/assignments/ipfix/ipfix.xhtml */
enum {
IPFIX_octetDeltaCount = 1,
IPFIX_packetDeltaCount = 2,
@@ -217,6 +218,10 @@ enum {
/* reserved */
IPFIX_headerLengthIPv4 = 213,
IPFIX_mplsPayloadLength = 214,
+ IPFIX_postNATSourceIPv4Address = 225,
+ IPFIX_postNATDestinationIPv4Address = 226,
+ IPFIX_postNAPTSourceTransportPort = 227,
+ IPFIX_postNAPTDestinationTransportPort = 228,
};
/* Information elements of the netfilter vendor id */
diff --git a/input/flow/ulogd_inpflow_NFCT.c b/input/flow/ulogd_inpflow_NFCT.c
index 899b7e3..93c8844 100644
--- a/input/flow/ulogd_inpflow_NFCT.c
+++ b/input/flow/ulogd_inpflow_NFCT.c
@@ -265,8 +265,8 @@ static struct ulogd_key nfct_okeys[] = {
.name = "reply.ip.saddr",
.ipfix = {
.vendor = IPFIX_VENDOR_IETF,
- .field_id = IPFIX_sourceIPv4Address,
- },
+ .field_id = IPFIX_postNATDestinationIPv4Address,
+ }, /* reply source is after-DNAT destination */
},
{
.type = ULOGD_RET_IPADDR,
@@ -274,8 +274,8 @@ static struct ulogd_key nfct_okeys[] = {
.name = "reply.ip.daddr",
.ipfix = {
.vendor = IPFIX_VENDOR_IETF,
- .field_id = IPFIX_destinationIPv4Address,
- },
+ .field_id = IPFIX_postNATSourceIPv4Address,
+ }, /* reply destination is after-SNAT source */
},
{
.type = ULOGD_RET_UINT8,
@@ -292,7 +292,7 @@ static struct ulogd_key nfct_okeys[] = {
.name = "reply.l4.sport",
.ipfix = {
.vendor = IPFIX_VENDOR_IETF,
- .field_id = IPFIX_sourceTransportPort,
+ .field_id = IPFIX_postNAPTDestinationTransportPort,
},
},
{
@@ -301,7 +301,7 @@ static struct ulogd_key nfct_okeys[] = {
.name = "reply.l4.dport",
.ipfix = {
.vendor = IPFIX_VENDOR_IETF,
- .field_id = IPFIX_destinationTransportPort,
+ .field_id = IPFIX_postNAPTSourceTransportPort,
},
},
{
diff --git a/output/ipfix/ipfix.c b/output/ipfix/ipfix.c
index e0b3440..0ad34ec 100644
--- a/output/ipfix/ipfix.c
+++ b/output/ipfix/ipfix.c
@@ -26,7 +26,7 @@ struct ipfix_templ {
/* Template fields modeled after vy_ipfix_data */
static const struct ipfix_templ template = {
- .num_templ_elements = 10,
+ .num_templ_elements = 14,
.templ_elements = {
{
.id = IPFIX_sourceIPv4Address,
@@ -37,6 +37,14 @@ static const struct ipfix_templ template = {
.len = sizeof(uint32_t)
},
{
+ .id = IPFIX_postNATSourceIPv4Address,
+ .len = sizeof(uint32_t)
+ },
+ {
+ .id = IPFIX_postNATDestinationIPv4Address,
+ .len = sizeof(uint32_t)
+ },
+ {
.id = IPFIX_packetTotalCount,
.len = sizeof(uint32_t)
},
@@ -61,13 +69,21 @@ static const struct ipfix_templ template = {
.len = sizeof(uint16_t)
},
{
+ .id = IPFIX_postNAPTSourceTransportPort,
+ .len = sizeof(uint16_t)
+ },
+ {
+ .id = IPFIX_postNAPTDestinationTransportPort,
+ .len = sizeof(uint16_t)
+ },
+ {
.id = IPFIX_protocolIdentifier,
.len = sizeof(uint8_t)
},
{
.id = IPFIX_applicationId,
.len = sizeof(uint32_t)
- }
+ },
}
};
diff --git a/output/ipfix/ipfix.h b/output/ipfix/ipfix.h
index b0f3ae6..f671ea6 100644
--- a/output/ipfix/ipfix.h
+++ b/output/ipfix/ipfix.h
@@ -59,12 +59,16 @@ struct ipfix_msg {
struct vy_ipfix_data {
struct in_addr saddr;
struct in_addr daddr;
+ struct in_addr tsaddr; /* translated source address, as read from the reply destination */
+ struct in_addr tdaddr;
uint32_t packets;
uint32_t bytes;
uint32_t start; /* Unix time */
uint32_t end; /* Unix time */
uint16_t sport;
uint16_t dport;
+ uint16_t tsport;
+ uint16_t tdport;
uint8_t l4_proto;
uint32_t aid; /* Application ID */
} __attribute__((packed));
diff --git a/output/ipfix/ulogd_output_IPFIX.c b/output/ipfix/ulogd_output_IPFIX.c
index 1c0f730..167ee9a 100644
--- a/output/ipfix/ulogd_output_IPFIX.c
+++ b/output/ipfix/ulogd_output_IPFIX.c
@@ -97,6 +97,8 @@ struct ipfix_priv {
enum {
InIpSaddr = 0,
InIpDaddr,
+ InTIpSaddr,
+ InTIpDaddr,
InRawInPktCount,
InRawInPktLen,
InRawOutPktCount,
@@ -107,6 +109,8 @@ enum {
InFlowEndUsec,
InL4SPort,
InL4DPort,
+ InL4TSPort,
+ InL4TDPort,
InIpProto,
InCtMark
};
@@ -120,6 +124,14 @@ static struct ulogd_key ipfix_in_keys[] = {
.type = ULOGD_RET_IPADDR,
.name = "orig.ip.daddr"
},
+ [InTIpSaddr] = {
+ .type = ULOGD_RET_IPADDR,
+ .name = "reply.ip.daddr"
+ },
+ [InTIpDaddr] = {
+ .type = ULOGD_RET_IPADDR,
+ .name = "reply.ip.saddr"
+ },
[InRawInPktCount] = {
.type = ULOGD_RET_UINT64,
.name = "orig.raw.pktcount"
@@ -160,6 +172,14 @@ static struct ulogd_key ipfix_in_keys[] = {
.type = ULOGD_RET_UINT16,
.name = "orig.l4.dport"
},
+ [InL4TSPort] = {
+ .type = ULOGD_RET_UINT16,
+ .name = "reply.l4.dport"
+ },
+ [InL4TDPort] = {
+ .type = ULOGD_RET_UINT16,
+ .name = "reply.l4.sport"
+ },
[InIpProto] = {
.type = ULOGD_RET_UINT8,
.name = "orig.ip.protocol"
@@ -419,7 +439,7 @@ static int ipfix_stop(struct ulogd_pluginstance *pi)
static int ipfix_interp(struct ulogd_pluginstance *pi)
{
struct ipfix_priv *priv = (struct ipfix_priv *) &pi->private;
- char saddr[16], daddr[16], *send_template;
+ char saddr[16],tsaddr[16], daddr[16],tdaddr[16], *send_template;
struct vy_ipfix_data *data;
int oid, mtu, ret;
@@ -458,6 +478,8 @@ again:
data->saddr.s_addr = ikey_get_u32(&pi->input.keys[InIpSaddr]);
data->daddr.s_addr = ikey_get_u32(&pi->input.keys[InIpDaddr]);
+ data->tsaddr.s_addr = ikey_get_u32(&pi->input.keys[InTIpSaddr]);
+ data->tdaddr.s_addr = ikey_get_u32(&pi->input.keys[InTIpDaddr]);
data->packets = htonl((uint32_t) (ikey_get_u64(&pi->input.keys[InRawInPktCount])
+ ikey_get_u64(&pi->input.keys[InRawOutPktCount])));
@@ -470,6 +492,8 @@ again:
if (GET_FLAGS(pi->input.keys, InL4SPort) & ULOGD_RETF_VALID) {
data->sport = htons(ikey_get_u16(&pi->input.keys[InL4SPort]));
data->dport = htons(ikey_get_u16(&pi->input.keys[InL4DPort]));
+ data->tsport = htons(ikey_get_u16(&pi->input.keys[InL4TSPort]));
+ data->tdport = htons(ikey_get_u16(&pi->input.keys[InL4TDPort]));
}
data->aid = 0;
next prev parent reply other threads:[~2023-12-12 19:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-10 20:17 [PATCH ulogd] log NAT events using IPFIX Tomasz Pala
2023-12-12 13:47 ` Pablo Neira Ayuso
2023-12-12 18:44 ` Tomasz Pala
2023-12-12 19:45 ` Tomasz Pala [this message]
2023-12-12 20:08 ` Tomasz Pala
2023-12-13 11:49 ` Tomasz Pala
2023-12-13 11:29 ` Tomasz Pala
2023-12-13 12:27 ` Tomasz Pala
2023-12-13 23:42 ` Tomasz Pala
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231212194536.GA8196@polanet.pl \
--to=gotar@polanet.pl \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.