From edbf280e6e043eaf38d4526e421cd68fcf7bc5c0 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 22 Mar 2024 14:41:44 +0000 Subject: [PATCH] address: Fix bit length calculation I have no idea what the previous version computed, but it wasn't the right thing. Signed-off-by: Michael Tremer --- src/libloc/address.h | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/libloc/address.h b/src/libloc/address.h index f4c0ee3..d6d7ca5 100644 --- a/src/libloc/address.h +++ b/src/libloc/address.h @@ -131,10 +131,30 @@ static inline struct in6_addr loc_prefix_to_bitmask(const unsigned int prefix) { } static inline unsigned int loc_address_bit_length(const struct in6_addr* address) { + unsigned int bitlength = 0; + int octet = 0; - foreach_octet_in_address(octet, address) { - if (address->s6_addr[octet]) - return (15 - octet) * 8 + 32 - __builtin_clz(address->s6_addr[octet]); + + // Initialize the bit length + if (IN6_IS_ADDR_V4MAPPED(address)) + bitlength = 32; + else + bitlength = 128; + + // Walk backwards until we find the first one + foreach_octet_in_address_reverse(octet, address) { + // Count all trailing zeroes + int trailing_zeroes = __builtin_ctz(address->s6_addr[octet]); + + // We only have one byte + if (trailing_zeroes > 8) + trailing_zeroes = 8; + + // Remove any trailing zeroes from the total length + bitlength -= trailing_zeroes; + + if (trailing_zeroes < 8) + return bitlength; } return 0; -- 2.39.5