]> git.ipfire.org Git - location/libloc.git/commitdiff
network: Add function that counts the bit length of an addres
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 6 Mar 2022 14:28:26 +0000 (14:28 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 6 Mar 2022 14:28:26 +0000 (14:28 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libloc/private.h
src/test-network.c

index 675e14b774ff081d87b6a2f113f34b77ec25186a..6b43990a58cb73c9eafb8a29a761a7390103e867 100644 (file)
@@ -94,6 +94,20 @@ 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) {
+       unsigned int length = 128;
+
+       for (int octet = 0; octet <= 15; octet++) {
+               if (address->s6_addr[octet]) {
+                       length -= __builtin_clz(address->s6_addr[octet]) - 24;
+                       break;
+               } else
+                       length -= 8;
+       }
+
+       return length;
+}
+
 static inline struct in6_addr loc_address_and(
                const struct in6_addr* address, const struct in6_addr* bitmask) {
        struct in6_addr a;
index 4582fbe60bda7d27a55f7c358e8ef8f608b7ddec..92088ee2a29ed15a7397bd9298f45cdf69100fdb 100644 (file)
@@ -25,6 +25,7 @@
 #include <libloc/libloc.h>
 #include <libloc/database.h>
 #include <libloc/network.h>
+#include <libloc/private.h>
 #include <libloc/writer.h>
 
 int main(int argc, char** argv) {
@@ -311,6 +312,36 @@ int main(int argc, char** argv) {
        }
        loc_network_unref(network1);
 
+       const struct bit_length_test {
+               const char* network;
+               unsigned int bit_length;
+       } bit_length_tests[] = {
+               { "::/0", 0 },
+               { "2001::/128", 126 },
+               { NULL, 0, },
+       };
+
+       for (const struct bit_length_test* t = bit_length_tests; t->network; t++) {
+               err = loc_network_new_from_string(ctx, &network1, t->network);
+               if (err) {
+                       fprintf(stderr, "Could not create network %s: %m\n", t->network);
+                       exit(EXIT_FAILURE);
+               }
+
+               const struct in6_addr* addr = loc_network_get_first_address(network1);
+
+               unsigned int bit_length = loc_address_bit_length(addr);
+
+               if (bit_length != t->bit_length) {
+                       printf("Bit length of %s didn't match: %u != %u\n",
+                               t->network, t->bit_length, bit_length);
+                       loc_network_unref(network1);
+                       exit(EXIT_FAILURE);
+               }
+
+               loc_network_unref(network1);
+       }
+
        loc_unref(ctx);
        fclose(f);