Currently, the only use of the output of IP2BIN is embedding in literal SQL strings, so it converts the binary data to a suitably formatted hexadecimal string and propagates that. However, we will shortly introduce prep & exec support to the DB API, at which point we may want the raw binary data in the output plug-ins. Therefore, in order to avoid having to decode the hex back to binary, defer the hex encoding to where it is used. At the same time, resize the buffers. IPv6 addresses are 128 *bits*, so the buffers do not need to be 128 *bytes*. Signed-off-by: Jeremy Sowden <jeremy@xxxxxxxxxx> --- filter/ulogd_filter_IP2BIN.c | 61 +++++++++++++----------------------- util/db.c | 10 +++++- 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/filter/ulogd_filter_IP2BIN.c b/filter/ulogd_filter_IP2BIN.c index ca6d3abae884..6a4e10e4fb58 100644 --- a/filter/ulogd_filter_IP2BIN.c +++ b/filter/ulogd_filter_IP2BIN.c @@ -28,8 +28,6 @@ #include <ulogd/ulogd.h> #include <netinet/if_ether.h> -#define IPADDR_LENGTH 128 - enum input_keys { KEY_OOB_FAMILY, KEY_OOB_PROTOCOL, @@ -89,32 +87,38 @@ static struct ulogd_key ip2bin_inp[] = { static struct ulogd_key ip2bin_keys[] = { { .type = ULOGD_RET_RAWSTR, + .len = sizeof(struct in6_addr), .name = "ip.saddr.bin", }, { .type = ULOGD_RET_RAWSTR, + .len = sizeof(struct in6_addr), .name = "ip.daddr.bin", }, { .type = ULOGD_RET_RAWSTR, + .len = sizeof(struct in6_addr), .name = "orig.ip.saddr.bin", }, { .type = ULOGD_RET_RAWSTR, + .len = sizeof(struct in6_addr), .name = "orig.ip.daddr.bin", }, { .type = ULOGD_RET_RAWSTR, + .len = sizeof(struct in6_addr), .name = "reply.ip.saddr.bin", }, { .type = ULOGD_RET_RAWSTR, + .len = sizeof(struct in6_addr), .name = "reply.ip.daddr.bin", }, }; -static char ipbin_array[MAX_KEY - START_KEY + 1][IPADDR_LENGTH]; +static unsigned char ipbin_array[MAX_KEY - START_KEY + 1][sizeof(struct in6_addr)]; /** * Convert IPv4 address (as 32-bit unsigned integer) to IPv6 address: @@ -130,13 +134,8 @@ static inline void uint32_to_ipv6(const uint32_t ipv4, struct in6_addr *ipv6) 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; + char family = ikey_get_u8(&inp[KEY_OOB_FAMILY]), convfamily = family; + struct in6_addr *addr, ip4_addr; if (family == AF_BRIDGE) { if (!pp_is_valid(inp, KEY_OOB_PROTOCOL)) { @@ -162,37 +161,21 @@ static int ip2bin(struct ulogd_key *inp, int index, int oindex) } switch (convfamily) { - case AF_INET6: - addr = (struct in6_addr *)ikey_get_u128(&inp[index]); - break; - case AF_INET: - /* Convert IPv4 to IPv4 in IPv6 */ - addr = &ip4_addr; - uint32_to_ipv6(ikey_get_u32(&inp[index]), addr); - break; - default: - /* TODO handle error */ - ulogd_log(ULOGD_NOTICE, "Unknown protocol family\n"); - return ULOGD_IRET_ERR; + case AF_INET6: + addr = (struct in6_addr *)ikey_get_u128(&inp[index]); + break; + case AF_INET: + /* Convert IPv4 to IPv4 in IPv6 */ + addr = &ip4_addr; + uint32_to_ipv6(ikey_get_u32(&inp[index]), addr); + break; + default: + /* TODO handle error */ + ulogd_log(ULOGD_NOTICE, "Unknown protocol family\n"); + 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; + memcpy(ipbin_array[oindex], &addr->s6_addr, sizeof(addr->s6_addr)); return ULOGD_IRET_OK; } diff --git a/util/db.c b/util/db.c index 42b59cc6284c..271cd25efeaf 100644 --- a/util/db.c +++ b/util/db.c @@ -594,7 +594,15 @@ _bind_sql_stmt(struct ulogd_pluginstance *upi, struct db_stmt *stmt) sqlp += sprintf(sqlp, "',"); break; case ULOGD_RET_RAWSTR: - sqlp += sprintf(sqlp, "%s,", (char *) res->u.value.ptr); + strcpy(sqlp, "0x"); + sqlp += 2; + { + unsigned char *cp = res->u.value.ptr; + unsigned int j; + for (j = 0; j < res->len; ++j) + sqlp += sprintf(sqlp, "%02x", cp[j]); + } + *sqlp++ = ','; break; case ULOGD_RET_RAW: ulogd_log(ULOGD_NOTICE, -- 2.35.1