]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
db: insert ipv6 addresses in the same format as ip2bin
authorJeremy Sowden <jeremy@azazel.net>
Mon, 21 Aug 2023 19:42:37 +0000 (20:42 +0100)
committerFlorian Westphal <fw@strlen.de>
Thu, 14 Sep 2023 12:22:49 +0000 (14:22 +0200)
Move a `ULOGD_RET_BOOL` case for consistency.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
filter/ulogd_filter_IP2BIN.c
include/ulogd/ulogd.h
util/db.c

index 74e46835ae53f66bdc46782aa52968db763b69ce..7f7bea5071a7c1b11c693e68dc5dead2dc66a3fc 100644 (file)
@@ -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;
 }
index cb0174042235c04d5e744aebdf3f029543602f17..c7cf40277fcbf1af4f5562cc78778980e987284c 100644 (file)
@@ -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;
 
index ebd9f152ed83b000bbb3a3e60f21ed028e210583..749a45ff5cd5316c7fdde5511ce9c918d8db607a 100644 (file)
--- 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) {