]> git.ipfire.org Git - location/libloc.git/blobdiff - src/libloc/private.h
network: Implement bit length function for IPv4
[location/libloc.git] / src / libloc / private.h
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;