- * [PATCH ulogd2 v3 01/11] src: record length of integer key values
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 02/11] printpkt: fix statement punctuator Jeremy Sowden
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 include/ulogd/ulogd.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
index 092d9f521a70..cb0174042235 100644
--- a/include/ulogd/ulogd.h
+++ b/include/ulogd/ulogd.h
@@ -134,36 +134,42 @@ static inline void okey_set_b(struct ulogd_key *key, uint8_t value)
 {
 	key->u.value.b = value;
 	key->flags |= ULOGD_RETF_VALID;
+	key->len = sizeof(key->u.value.b);
 }
 
 static inline void okey_set_u8(struct ulogd_key *key, uint8_t value)
 {
 	key->u.value.ui8 = value;
 	key->flags |= ULOGD_RETF_VALID;
+	key->len = sizeof(key->u.value.ui8);
 }
 
 static inline void okey_set_u16(struct ulogd_key *key, uint16_t value)
 {
 	key->u.value.ui16 = value;
 	key->flags |= ULOGD_RETF_VALID;
+	key->len = sizeof(key->u.value.ui16);
 }
 
 static inline void okey_set_u32(struct ulogd_key *key, uint32_t value)
 {
 	key->u.value.ui32 = value;
 	key->flags |= ULOGD_RETF_VALID;
+	key->len = sizeof(key->u.value.ui32);
 }
 
 static inline void okey_set_u64(struct ulogd_key *key, uint64_t value)
 {
 	key->u.value.ui64 = value;
 	key->flags |= ULOGD_RETF_VALID;
+	key->len = sizeof(key->u.value.ui64);
 }
 
 static inline void okey_set_u128(struct ulogd_key *key, const void *value)
 {
-	memcpy(key->u.value.ui128, value, 16);
+	memcpy(key->u.value.ui128, value, sizeof(key->u.value.ui128));
 	key->flags |= ULOGD_RETF_VALID;
+	key->len = sizeof(key->u.value.ui128);
 }
 
 static inline void okey_set_ptr(struct ulogd_key *key, void *value)
@@ -309,6 +315,7 @@ void __ulogd_log(int level, char *file, int line, const char *message, ...)
 #define SET_NEEDED(x)	(x.flags |= ULOGD_RETF_NEEDED)
 
 #define GET_FLAGS(res, x)	(res[x].u.source->flags)
+#define GET_LENGTH(res, x)	(res[x].u.source->len)
 #define pp_is_valid(res, x)	\
 	(res[x].u.source && (GET_FLAGS(res, x) & ULOGD_RETF_VALID))
 
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 02/11] printpkt: fix statement punctuator
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 01/11] src: record length of integer key values Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 03/11] printpkt, raw2packet_BASE: keep gateway address in NBO Jeremy Sowden
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Replace comma with semicolon.
Fixes: d4cf078cb71a ("add ukey_* function for key assignation")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 util/printpkt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util/printpkt.c b/util/printpkt.c
index b9b47b2f63a0..11126b3c9af7 100644
--- a/util/printpkt.c
+++ b/util/printpkt.c
@@ -264,7 +264,7 @@ static int printpkt_ipv4(struct ulogd_key *res, char *buf)
 					   ikey_get_u32(&res[KEY_ICMP_GATEWAY]) >> 24);
 			break;
 		case ICMP_REDIRECT:
-			paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]),
+			paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]);
 			buf_cur += sprintf(buf_cur, "GATEWAY=%s ",
 					   inet_ntop(AF_INET,
 						     &paddr,
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 03/11] printpkt, raw2packet_BASE: keep gateway address in NBO
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 01/11] src: record length of integer key values Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 02/11] printpkt: fix statement punctuator Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 04/11] raw2packet_BASE: store ARP address values as integers Jeremy Sowden
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Everywhere else ipv4 addresses are left in NBO until output.  The only
exception is the IP2HBIN filter, which is explicitly intended to convert
from NBO to HBO.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 filter/raw2packet/ulogd_raw2packet_BASE.c | 2 +-
 util/printpkt.c                           | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/filter/raw2packet/ulogd_raw2packet_BASE.c b/filter/raw2packet/ulogd_raw2packet_BASE.c
index 9117d27da09a..14423486a880 100644
--- a/filter/raw2packet/ulogd_raw2packet_BASE.c
+++ b/filter/raw2packet/ulogd_raw2packet_BASE.c
@@ -645,7 +645,7 @@ static int _interp_icmp(struct ulogd_pluginstance *pi, struct icmphdr *icmph,
 		break;
 	case ICMP_REDIRECT:
 	case ICMP_PARAMETERPROB:
-		okey_set_u32(&ret[KEY_ICMP_GATEWAY], ntohl(icmph->un.gateway));
+		okey_set_u32(&ret[KEY_ICMP_GATEWAY], icmph->un.gateway);
 		break;
 	case ICMP_DEST_UNREACH:
 		if (icmph->code == ICMP_FRAG_NEEDED) {
diff --git a/util/printpkt.c b/util/printpkt.c
index 11126b3c9af7..09a219417f91 100644
--- a/util/printpkt.c
+++ b/util/printpkt.c
@@ -260,8 +260,9 @@ static int printpkt_ipv4(struct ulogd_key *res, char *buf)
 					   ikey_get_u16(&res[KEY_ICMP_ECHOSEQ]));
 			break;
 		case ICMP_PARAMETERPROB:
+			paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]);
 			buf_cur += sprintf(buf_cur, "PARAMETER=%u ",
-					   ikey_get_u32(&res[KEY_ICMP_GATEWAY]) >> 24);
+					   *(uint8_t *) &paddr);
 			break;
 		case ICMP_REDIRECT:
 			paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]);
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 04/11] raw2packet_BASE: store ARP address values as integers
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (2 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 03/11] printpkt, raw2packet_BASE: keep gateway address in NBO Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 05/11] ip2hbin: store ipv6 address as integer Jeremy Sowden
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel; +Cc: Robert O'Brien
Keys of type `ULOGD_RET_IPADDR` may be ipv4 or ipv6.  ARP protocol
addresses are 32-bits (i.e., ipv4).  By using `okey_set_u32` we keep
track of the size and allow downstream plug-ins to handle them
correctly.
Reported-by: Robert O'Brien <robrien@foxtrot-research.com>
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 filter/raw2packet/ulogd_raw2packet_BASE.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/filter/raw2packet/ulogd_raw2packet_BASE.c b/filter/raw2packet/ulogd_raw2packet_BASE.c
index 14423486a880..09e931349acf 100644
--- a/filter/raw2packet/ulogd_raw2packet_BASE.c
+++ b/filter/raw2packet/ulogd_raw2packet_BASE.c
@@ -896,18 +896,23 @@ static int _interp_arp(struct ulogd_pluginstance *pi, uint32_t len)
 	struct ulogd_key *ret = pi->output.keys;
 	const struct ether_arp *arph =
 		ikey_get_ptr(&pi->input.keys[INKEY_RAW_PCKT]);
+	uint32_t arp_spa, arp_tpa;
 
 	if (len < sizeof(struct ether_arp))
 		return ULOGD_IRET_OK;
 
-	okey_set_u16(&ret[KEY_ARP_HTYPE], ntohs(arph->arp_hrd));
-	okey_set_u16(&ret[KEY_ARP_PTYPE], ntohs(arph->arp_pro));
+	okey_set_u16(&ret[KEY_ARP_HTYPE],  ntohs(arph->arp_hrd));
+	okey_set_u16(&ret[KEY_ARP_PTYPE],  ntohs(arph->arp_pro));
 	okey_set_u16(&ret[KEY_ARP_OPCODE], ntohs(arph->arp_op));
 
 	okey_set_ptr(&ret[KEY_ARP_SHA], (void *)&arph->arp_sha);
-	okey_set_ptr(&ret[KEY_ARP_SPA], (void *)&arph->arp_spa);
 	okey_set_ptr(&ret[KEY_ARP_THA], (void *)&arph->arp_tha);
-	okey_set_ptr(&ret[KEY_ARP_TPA], (void *)&arph->arp_tpa);
+
+	memcpy(&arp_spa, arph->arp_spa, sizeof(arp_spa));
+	memcpy(&arp_tpa, arph->arp_tpa, sizeof(arp_tpa));
+
+	okey_set_u32(&ret[KEY_ARP_SPA], arp_spa);
+	okey_set_u32(&ret[KEY_ARP_TPA], arp_tpa);
 
 	return ULOGD_IRET_OK;
 }
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 05/11] ip2hbin: store ipv6 address as integer
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (3 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 04/11] raw2packet_BASE: store ARP address values as integers Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 06/11] ipfix: skip non-ipv4 addresses Jeremy Sowden
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
By using `okey_set_u128` we keep track of the address size and
downstream plug-ins can distinguish the address family.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 filter/ulogd_filter_IP2HBIN.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/filter/ulogd_filter_IP2HBIN.c b/filter/ulogd_filter_IP2HBIN.c
index 2711f9c3e12a..081616edbc51 100644
--- a/filter/ulogd_filter_IP2HBIN.c
+++ b/filter/ulogd_filter_IP2HBIN.c
@@ -157,15 +157,14 @@ static int interp_ip2hbin(struct ulogd_pluginstance *pi)
 		if (pp_is_valid(inp, i)) {
 			switch (convfamily) {
 			case AF_INET:
-				okey_set_u32(&ret[i-START_KEY],
-					ntohl(ikey_get_u32(&inp[i])));
+				okey_set_u32(&ret[i - START_KEY],
+					     ntohl(ikey_get_u32(&inp[i])));
 				break;
 			case AF_INET6:
-				okey_set_ptr(&ret[i-START_KEY],
-					(struct in6_addr *)ikey_get_u128(&inp[i]));
+				okey_set_u128(&ret[i - START_KEY],
+					      ikey_get_u128(&inp[i]));
 				break;
 			default:
-				;
 				break;
 			}
 		}
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 06/11] ipfix: skip non-ipv4 addresses
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (4 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 05/11] ip2hbin: store ipv6 address as integer Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 07/11] gprint, oprint: use inet_ntop to format ip addresses Jeremy Sowden
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
This plug-in expects ipv4 addresses.  Check the length of the key value
in order to filter out ipv6 addresses.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 output/ipfix/ulogd_output_IPFIX.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/output/ipfix/ulogd_output_IPFIX.c b/output/ipfix/ulogd_output_IPFIX.c
index 4863d008562e..1c0f730b5b7c 100644
--- a/output/ipfix/ulogd_output_IPFIX.c
+++ b/output/ipfix/ulogd_output_IPFIX.c
@@ -426,6 +426,9 @@ static int ipfix_interp(struct ulogd_pluginstance *pi)
 	if (!(GET_FLAGS(pi->input.keys, InIpSaddr) & ULOGD_RETF_VALID))
 		return ULOGD_IRET_OK;
 
+	if (GET_LENGTH(pi->input.keys, InIpSaddr) != sizeof(data->saddr))
+		return ULOGD_IRET_OK;
+
 	oid = oid_ce(pi->config_kset).u.value;
 	mtu = mtu_ce(pi->config_kset).u.value;
 	send_template = send_template_ce(pi->config_kset).u.string;
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 07/11] gprint, oprint: use inet_ntop to format ip addresses
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (5 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 06/11] ipfix: skip non-ipv4 addresses Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 08/11] gprint, oprint: add support for printing ipv6 addresses Jeremy Sowden
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Replace hand-rolled ipv4-only formatting code in order to be able to
support ipv6 addresses.  This also changes the byte-order expected by
oprint from HBO to NBO.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 output/ulogd_output_GPRINT.c | 20 ++++++++++----------
 output/ulogd_output_OPRINT.c | 30 ++++++++++++++----------------
 2 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/output/ulogd_output_GPRINT.c b/output/ulogd_output_GPRINT.c
index eeeec6ac3eb0..093d3ea2b254 100644
--- a/output/ulogd_output_GPRINT.c
+++ b/output/ulogd_output_GPRINT.c
@@ -27,6 +27,8 @@
 #include <time.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
 #include <ulogd/ulogd.h>
 #include <ulogd/conffile.h>
 
@@ -69,12 +71,6 @@ static struct config_keyset gprint_kset = {
 	},
 };
 
-#define NIPQUAD(addr) \
-        ((unsigned char *)&addr)[0], \
-        ((unsigned char *)&addr)[1], \
-        ((unsigned char *)&addr)[2], \
-        ((unsigned char *)&addr)[3]
-
 static int gprint_interp(struct ulogd_pluginstance *upi)
 {
 	struct gprint_priv *opi = (struct gprint_priv *) &upi->private;
@@ -158,20 +154,24 @@ static int gprint_interp(struct ulogd_pluginstance *upi)
 			rem -= ret;
 			size += ret;
 			break;
-		case ULOGD_RET_IPADDR:
+		case ULOGD_RET_IPADDR: {
+			struct in_addr ipv4addr;
+
 			ret = snprintf(buf+size, rem, "%s=", key->name);
 			if (ret < 0)
 				break;
 			rem -= ret;
 			size += ret;
 
-			ret = snprintf(buf+size, rem, "%u.%u.%u.%u,",
-				NIPQUAD(key->u.value.ui32));
-			if (ret < 0)
+			ipv4addr.s_addr = key->u.value.ui32;
+			if (!inet_ntop(AF_INET, &ipv4addr, buf + size, rem))
 				break;
+			ret = strlen(buf + size);
+
 			rem -= ret;
 			size += ret;
 			break;
+		}
 		default:
 			/* don't know how to interpret this key. */
 			break;
diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c
index 0409133e8227..b5586e850aa4 100644
--- a/output/ulogd_output_OPRINT.c
+++ b/output/ulogd_output_OPRINT.c
@@ -24,6 +24,8 @@
 #include <string.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
 #include <ulogd/ulogd.h>
 #include <ulogd/conffile.h>
 
@@ -31,18 +33,6 @@
 #define ULOGD_OPRINT_DEFAULT	"/var/log/ulogd_oprint.log"
 #endif
 
-#define NIPQUAD(addr) \
-	((unsigned char *)&addr)[0], \
-	((unsigned char *)&addr)[1], \
-        ((unsigned char *)&addr)[2], \
-        ((unsigned char *)&addr)[3]
-
-#define HIPQUAD(addr) \
-        ((unsigned char *)&addr)[3], \
-        ((unsigned char *)&addr)[2], \
-        ((unsigned char *)&addr)[1], \
-        ((unsigned char *)&addr)[0]
-
 struct oprint_priv {
 	FILE *of;
 };
@@ -59,7 +49,7 @@ static int oprint_interp(struct ulogd_pluginstance *upi)
 		if (!ret)
 			ulogd_log(ULOGD_NOTICE, "no result for %s ?!?\n",
 				  upi->input.keys[i].name);
-		
+
 		if (!IS_VALID(*ret))
 			continue;
 
@@ -85,10 +75,18 @@ static int oprint_interp(struct ulogd_pluginstance *upi)
 		case ULOGD_RET_UINT64:
 			fprintf(opi->of, "%" PRIu64 "\n", ret->u.value.ui64);
 			break;
-		case ULOGD_RET_IPADDR:
-			fprintf(opi->of, "%u.%u.%u.%u\n",
-				HIPQUAD(ret->u.value.ui32));
+		case ULOGD_RET_IPADDR: {
+			char addrbuf[INET_ADDRSTRLEN + 1] = "";
+			struct in_addr ipv4addr;
+
+			ipv4addr.s_addr = ret->u.value.ui32;
+			if (!inet_ntop(AF_INET, &ipv4addr, addrbuf,
+				       sizeof(addrbuf)))
+				break;
+
+			fprintf(opi->of, "%s\n", addrbuf);
 			break;
+		}
 		case ULOGD_RET_NONE:
 			fprintf(opi->of, "<none>\n");
 			break;
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 08/11] gprint, oprint: add support for printing ipv6 addresses
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (6 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 07/11] gprint, oprint: use inet_ntop to format ip addresses Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 09/11] sqlite3: correct binding of ipv4 addresses and 64-bit integers Jeremy Sowden
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 output/ulogd_output_GPRINT.c | 16 ++++++++++++++--
 output/ulogd_output_OPRINT.c | 21 ++++++++++++++++-----
 2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/output/ulogd_output_GPRINT.c b/output/ulogd_output_GPRINT.c
index 093d3ea2b254..37829fa49e9d 100644
--- a/output/ulogd_output_GPRINT.c
+++ b/output/ulogd_output_GPRINT.c
@@ -155,7 +155,10 @@ static int gprint_interp(struct ulogd_pluginstance *upi)
 			size += ret;
 			break;
 		case ULOGD_RET_IPADDR: {
+			struct in6_addr ipv6addr;
 			struct in_addr ipv4addr;
+			int family;
+			void *addr;
 
 			ret = snprintf(buf+size, rem, "%s=", key->name);
 			if (ret < 0)
@@ -163,8 +166,17 @@ static int gprint_interp(struct ulogd_pluginstance *upi)
 			rem -= ret;
 			size += ret;
 
-			ipv4addr.s_addr = key->u.value.ui32;
-			if (!inet_ntop(AF_INET, &ipv4addr, buf + size, rem))
+			if (key->len == sizeof(ipv6addr)) {
+				memcpy(ipv6addr.s6_addr, key->u.value.ui128,
+				       sizeof(ipv6addr.s6_addr));
+				addr = &ipv6addr;
+				family = AF_INET6;
+			} else {
+				ipv4addr.s_addr = key->u.value.ui32;
+				addr = &ipv4addr;
+				family = AF_INET;
+			}
+			if (!inet_ntop(family, addr, buf + size, rem))
 				break;
 			ret = strlen(buf + size);
 
diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c
index b5586e850aa4..13934ff19efb 100644
--- a/output/ulogd_output_OPRINT.c
+++ b/output/ulogd_output_OPRINT.c
@@ -76,12 +76,23 @@ static int oprint_interp(struct ulogd_pluginstance *upi)
 			fprintf(opi->of, "%" PRIu64 "\n", ret->u.value.ui64);
 			break;
 		case ULOGD_RET_IPADDR: {
-			char addrbuf[INET_ADDRSTRLEN + 1] = "";
+			char addrbuf[INET6_ADDRSTRLEN + 1] = "";
+			struct in6_addr ipv6addr;
 			struct in_addr ipv4addr;
-
-			ipv4addr.s_addr = ret->u.value.ui32;
-			if (!inet_ntop(AF_INET, &ipv4addr, addrbuf,
-				       sizeof(addrbuf)))
+			int family;
+			void *addr;
+
+			if (ret->len == sizeof(ipv6addr)) {
+				memcpy(ipv6addr.s6_addr, ret->u.value.ui128,
+				       sizeof(ipv6addr.s6_addr));
+				addr = &ipv6addr;
+				family = AF_INET6;
+			} else {
+				ipv4addr.s_addr = ret->u.value.ui32;
+				addr = &ipv4addr;
+				family = AF_INET;
+			}
+			if (!inet_ntop(family, addr, addrbuf, sizeof(addrbuf)))
 				break;
 
 			fprintf(opi->of, "%s\n", addrbuf);
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 09/11] sqlite3: correct binding of ipv4 addresses and 64-bit integers
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (7 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 08/11] gprint, oprint: add support for printing ipv6 addresses Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 10/11] sqlite3: insert ipv6 addresses as null rather than garbage Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 11/11] db: insert ipv6 addresses in the same format as ip2bin Jeremy Sowden
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Hitherto we have bound ipv4 addresses as 64-bit ints and 64-bit ints as
32-bit.
Move a `ULOGD_RET_BOOL` case for consistency and fix some nearby
formatting.
Fix some nearby formatting.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 output/sqlite3/ulogd_output_SQLITE3.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/output/sqlite3/ulogd_output_SQLITE3.c b/output/sqlite3/ulogd_output_SQLITE3.c
index 0a9ad67edcff..3a823892a2dd 100644
--- a/output/sqlite3/ulogd_output_SQLITE3.c
+++ b/output/sqlite3/ulogd_output_SQLITE3.c
@@ -145,6 +145,10 @@ sqlite3_interp(struct ulogd_pluginstance *pi)
 		}
 
 		switch (f->key->type) {
+		case ULOGD_RET_BOOL:
+			ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.b);
+			break;
+
 		case ULOGD_RET_INT8:
 			ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.i8);
 			break;
@@ -158,7 +162,7 @@ sqlite3_interp(struct ulogd_pluginstance *pi)
 			break;
 
 		case ULOGD_RET_INT64:
-			ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.i64);
+			ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.i64);
 			break;
 			
 		case ULOGD_RET_UINT8:
@@ -174,17 +178,16 @@ sqlite3_interp(struct ulogd_pluginstance *pi)
 			break;
 
 		case ULOGD_RET_IPADDR:
-		case ULOGD_RET_UINT64:
-			ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.ui64);
+			ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.ui32);
 			break;
 
-		case ULOGD_RET_BOOL:
-			ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.b);
+		case ULOGD_RET_UINT64:
+			ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.ui64);
 			break;
 
 		case ULOGD_RET_STRING:
 			ret = sqlite3_bind_text(priv->p_stmt, i, k_ret->u.value.ptr,
-									strlen(k_ret->u.value.ptr), SQLITE_STATIC);
+						strlen(k_ret->u.value.ptr), SQLITE_STATIC);
 			break;
 
 		default:
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 10/11] sqlite3: insert ipv6 addresses as null rather than garbage
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (8 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 09/11] sqlite3: correct binding of ipv4 addresses and 64-bit integers Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  2023-08-21 19:42 ` [PATCH ulogd2 v3 11/11] db: insert ipv6 addresses in the same format as ip2bin Jeremy Sowden
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Currently, the plug-in assumes that all IP addresses are 32-bit ipv4
addresses, so ipv6 addresses get truncated and inserted as garbage.
Insert nulls instead.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 output/sqlite3/ulogd_output_SQLITE3.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/output/sqlite3/ulogd_output_SQLITE3.c b/output/sqlite3/ulogd_output_SQLITE3.c
index 3a823892a2dd..6aeb7a3865e1 100644
--- a/output/sqlite3/ulogd_output_SQLITE3.c
+++ b/output/sqlite3/ulogd_output_SQLITE3.c
@@ -33,6 +33,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <arpa/inet.h>
+#include <netinet/in.h>
 #include <ulogd/ulogd.h>
 #include <ulogd/conffile.h>
 #include <sqlite3.h>
@@ -178,7 +179,11 @@ sqlite3_interp(struct ulogd_pluginstance *pi)
 			break;
 
 		case ULOGD_RET_IPADDR:
-			ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.ui32);
+			if (k_ret->len == sizeof(struct in_addr))
+				ret = sqlite3_bind_int(priv->p_stmt, i,
+						       k_ret->u.value.ui32);
+			else
+				ret = sqlite3_bind_null(priv->p_stmt, i);
 			break;
 
 		case ULOGD_RET_UINT64:
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread
- * [PATCH ulogd2 v3 11/11] db: insert ipv6 addresses in the same format as ip2bin
  2023-08-21 19:42 [PATCH ulogd2 v3 00/11] Fixes for handling and output of IP addresses Jeremy Sowden
                   ` (9 preceding siblings ...)
  2023-08-21 19:42 ` [PATCH ulogd2 v3 10/11] sqlite3: insert ipv6 addresses as null rather than garbage Jeremy Sowden
@ 2023-08-21 19:42 ` Jeremy Sowden
  10 siblings, 0 replies; 12+ messages in thread
From: Jeremy Sowden @ 2023-08-21 19:42 UTC (permalink / raw)
  To: Netfilter Devel
Move a `ULOGD_RET_BOOL` case for consistency.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 filter/ulogd_filter_IP2BIN.c | 33 +----------------------------
 include/ulogd/ulogd.h        | 41 ++++++++++++++++++++++++++++++++++++
 util/db.c                    | 19 +++++++++++++----
 3 files changed, 57 insertions(+), 36 deletions(-)
diff --git a/filter/ulogd_filter_IP2BIN.c b/filter/ulogd_filter_IP2BIN.c
index 74e46835ae53..7f7bea5071a7 100644
--- a/filter/ulogd_filter_IP2BIN.c
+++ b/filter/ulogd_filter_IP2BIN.c
@@ -116,27 +116,12 @@ static struct ulogd_key ip2bin_keys[] = {
 
 static char ipbin_array[MAX_KEY - START_KEY + 1][IPADDR_LENGTH];
 
-/**
- * Convert IPv4 address (as 32-bit unsigned integer) to IPv6 address:
- * add 96 bits prefix "::ffff:" to get IPv6 address "::ffff:a.b.c.d".
- */
-static inline void uint32_to_ipv6(const uint32_t ipv4, struct in6_addr *ipv6)
-{
-	ipv6->s6_addr32[0] = 0x00000000;
-	ipv6->s6_addr32[1] = 0x00000000;
-	ipv6->s6_addr32[2] = htonl(0xffff);
-	ipv6->s6_addr32[3] = ipv4;
-}
-
 static int ip2bin(struct ulogd_key *inp, int index, int oindex)
 {
 	char family = ikey_get_u8(&inp[KEY_OOB_FAMILY]);
 	char convfamily = family;
-	unsigned char *addr8;
 	struct in6_addr *addr;
 	struct in6_addr ip4_addr;
-	char *buffer;
-	int i, written;
 
 	if (family == AF_BRIDGE) {
 		if (!pp_is_valid(inp, KEY_OOB_PROTOCOL)) {
@@ -176,23 +161,7 @@ static int ip2bin(struct ulogd_key *inp, int index, int oindex)
 			return ULOGD_IRET_ERR;
 	}
 
-	buffer = ipbin_array[oindex];
-	/* format IPv6 to BINARY(16) as "0x..." */
-	buffer[0] = '0';
-	buffer[1] = 'x';
-	buffer += 2;
-	addr8 = &addr->s6_addr[0];
-	for (i = 0; i < 4; i++) {
-		written = sprintf(buffer, "%02x%02x%02x%02x",
-				  addr8[0], addr8[1], addr8[2], addr8[3]);
-		if (written != 2 * 4) {
-			buffer[0] = 0;
-			return ULOGD_IRET_ERR;
-		}
-		buffer += written;
-		addr8 += 4;
-	}
-	buffer[0] = 0;
+	format_ipv6(ipbin_array[oindex], IPADDR_LENGTH, addr);
 
 	return ULOGD_IRET_OK;
 }
diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
index cb0174042235..c7cf40277fcb 100644
--- a/include/ulogd/ulogd.h
+++ b/include/ulogd/ulogd.h
@@ -18,6 +18,7 @@
 #include <signal.h>	/* need this because of extension-sighandler */
 #include <sys/types.h>
 #include <inttypes.h>
+#include <netinet/in.h>
 #include <string.h>
 #include <config.h>
 
@@ -208,6 +209,46 @@ static inline void *ikey_get_ptr(struct ulogd_key *key)
 	return key->u.source->u.value.ptr;
 }
 
+/**
+ * Convert IPv4 address (as 32-bit unsigned integer) to IPv6 address: add 96-bit
+ * prefix "::ffff" to get IPv6 address "::ffff:a.b.c.d".
+ */
+static inline struct in6_addr *
+uint32_to_ipv6(uint32_t ipv4, struct in6_addr *ipv6)
+{
+	static const uint8_t IPV4_IN_IPV6_PREFIX[12] = {
+		[10] = 0xff,
+		[11] = 0xff,
+	};
+	uint8_t *p = ipv6->s6_addr;
+
+	memcpy(p, IPV4_IN_IPV6_PREFIX, sizeof(IPV4_IN_IPV6_PREFIX));
+	p += sizeof(IPV4_IN_IPV6_PREFIX);
+	memcpy(p, &ipv4, sizeof(ipv4));
+
+	return ipv6;
+}
+
+static inline void
+format_ipv6(char *buf, size_t size, const struct in6_addr *ipv6)
+{
+	unsigned i = 0;
+
+	if (size > 2 + sizeof (*ipv6) * 2) {
+		buf[i++] = '0';
+		buf[i++] = 'x';
+
+		for (unsigned j = 0; i < sizeof(*ipv6); j += 4, i += 8) {
+			sprintf(buf + i, "%02hhx%02hhx%02hhx%02hhx",
+				ipv6->s6_addr[j + 0],
+				ipv6->s6_addr[j + 1],
+				ipv6->s6_addr[j + 2],
+				ipv6->s6_addr[j + 3]);
+		}
+	}
+	buf[i] = '\0';
+}
+
 struct ulogd_pluginstance_stack;
 struct ulogd_pluginstance;
 
diff --git a/util/db.c b/util/db.c
index ebd9f152ed83..749a45ff5cd5 100644
--- a/util/db.c
+++ b/util/db.c
@@ -344,6 +344,9 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start)
 		}
 
 		switch (res->type) {
+		case ULOGD_RET_BOOL:
+			sprintf(stmt_ins, "'%d',", res->u.value.b);
+			break;
 		case ULOGD_RET_INT8:
 			sprintf(stmt_ins, "%d,", res->u.value.i8);
 			break;
@@ -363,16 +366,24 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start)
 			sprintf(stmt_ins, "%u,", res->u.value.ui16);
 			break;
 		case ULOGD_RET_IPADDR:
-			/* fallthrough when logging IP as uint32_t */
+			if (res->len == sizeof(struct in_addr))
+				sprintf(stmt_ins, "%u,", res->u.value.ui32);
+			else {
+				struct in6_addr ipv6;
+				char addrbuf[2 + sizeof(ipv6) * 2  + 1];
+
+				memcpy(ipv6.s6_addr, res->u.value.ui128,
+				       sizeof(ipv6.s6_addr));
+				format_ipv6(addrbuf, sizeof(addrbuf), &ipv6);
+				sprintf(stmt_ins, "%s,", addrbuf);
+			}
+			break;
 		case ULOGD_RET_UINT32:
 			sprintf(stmt_ins, "%u,", res->u.value.ui32);
 			break;
 		case ULOGD_RET_UINT64:
 			sprintf(stmt_ins, "%" PRIu64 ",", res->u.value.ui64);
 			break;
-		case ULOGD_RET_BOOL:
-			sprintf(stmt_ins, "'%d',", res->u.value.b);
-			break;
 		case ULOGD_RET_STRING:
 			*(stmt_ins++) = '\'';
 			if (res->u.value.ptr) {
-- 
2.40.1
^ permalink raw reply related	[flat|nested] 12+ messages in thread