Commit f69e0c8b authored by Michael Tremer's avatar Michael Tremer

network: Add function that counts the bit length of an addres

Signed-off-by: default avatarMichael Tremer <michael.tremer@ipfire.org>
parent 30f0f0ed
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment