summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Sowden <jeremy@azazel.net>2023-08-21 20:42:37 +0100
committerFlorian Westphal <fw@strlen.de>2023-09-14 14:22:49 +0200
commit9aa04788a317f0bc34050cd07ee81d66fda4cc8c (patch)
tree160c28717cf7779a254e8731bfa6e199d4a717ae
parent083d56967d3940a3a29d11c881d1b78e6033c24f (diff)
db: insert ipv6 addresses in the same format as ip2binHEADmaster
Move a `ULOGD_RET_BOOL` case for consistency. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r--filter/ulogd_filter_IP2BIN.c33
-rw-r--r--include/ulogd/ulogd.h41
-rw-r--r--util/db.c19
3 files changed, 57 insertions, 36 deletions
diff --git a/filter/ulogd_filter_IP2BIN.c b/filter/ulogd_filter_IP2BIN.c
index 74e4683..7f7bea5 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 cb01740..c7cf402 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 ebd9f15..749a45f 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) {