]> git.ipfire.org Git - people/ms/libloc.git/commitdiff
network: Implement bit length function for IPv4
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 7 Mar 2022 10:01:23 +0000 (10:01 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 7 Mar 2022 10:01:23 +0000 (10:01 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libloc/private.h
src/test-network.c

index 3b8782a1f592708c20f08199ba75cdc91221a8af..7b008d57f1cf2103ea6a8ae39561967b31f21ff2 100644 (file)
@@ -94,7 +94,7 @@ static inline struct in6_addr loc_prefix_to_bitmask(const unsigned int prefix) {
        return bitmask;
 }
 
-static inline unsigned int loc_address_bit_length(const struct in6_addr* address) {
+static inline unsigned int __loc_address6_bit_length(const struct in6_addr* address) {
        unsigned int length = 128;
 
        for (int octet = 0; octet <= 15; octet++) {
@@ -108,6 +108,27 @@ static inline unsigned int loc_address_bit_length(const struct in6_addr* address
        return length;
 }
 
+static inline unsigned int __loc_address4_bit_length(const struct in6_addr* address) {
+       unsigned int length = 32;
+
+       for (int octet = 12; octet <= 15; octet++) {
+               if (address->s6_addr[octet]) {
+                       length -= __builtin_clz(address->s6_addr[octet]) - 24;
+                       break;
+               } else
+                       length -= 8;
+       }
+
+       return length;
+}
+
+static inline unsigned int loc_address_bit_length(const struct in6_addr* address) {
+       if (IN6_IS_ADDR_V4MAPPED(address))
+               return __loc_address4_bit_length(address);
+       else
+               return __loc_address6_bit_length(address);
+}
+
 static inline struct in6_addr loc_address_and(
                const struct in6_addr* address, const struct in6_addr* bitmask) {
        struct in6_addr a;
index 1d4550cc910b46003e960cd17f2ecffeb0f1a6cb..7001071fbb2ade794367c5cad6c2f191c7a765ba 100644 (file)
@@ -311,6 +311,8 @@ int main(int argc, char** argv) {
        } bit_length_tests[] = {
                { "::/0", 0 },
                { "2001::/128", 126 },
+               { "1.0.0.0/32", 25 },
+               { "255.255.255.255/32", 32 },
                { NULL, 0, },
        };