From 1fd09d0b09756649968fec42c737c88b92e4f11f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 7 Mar 2022 12:22:14 +0000 Subject: [PATCH] network: Pass prefix in native length When creating an IPv4 subnet, the prefix had to be mapped to the mapped syntax (i.e. add 96). This doesn't seem too intuitive to me. Signed-off-by: Michael Tremer --- src/libloc/address.h | 41 ++++++++++++++++++++++++++++------------- src/network-list.c | 2 +- src/network.c | 29 ++++++++++------------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/libloc/address.h b/src/libloc/address.h index 57540bb..692ed12 100644 --- a/src/libloc/address.h +++ b/src/libloc/address.h @@ -33,6 +33,34 @@ static inline int loc_address_family(const struct in6_addr* address) { return AF_INET6; } +static inline unsigned int loc_address_family_bit_length(const int family) { + switch (family) { + case AF_INET6: + return 128; + + case AF_INET: + return 32; + + default: + return 0; + } +} + +/* + Checks whether prefix is valid for the given address +*/ +static inline int loc_address_valid_prefix(const struct in6_addr* address, unsigned int prefix) { + const int family = loc_address_family(address); + + // What is the largest possible prefix? + const unsigned int bit_length = loc_address_family_bit_length(family); + + if (prefix <= bit_length) + return 1; + + return 0; +} + static inline int loc_address_cmp(const struct in6_addr* a1, const struct in6_addr* a2) { for (unsigned int i = 0; i < 16; i++) { if (a1->s6_addr[i] > a2->s6_addr[i]) @@ -247,19 +275,6 @@ static inline void loc_address_decrement(struct in6_addr* address) { } } -static inline int loc_address_family_bit_length(const int family) { - switch (family) { - case AF_INET6: - return 128; - - case AF_INET: - return 32; - - default: - return -1; - } -} - static inline int loc_address_all_zeroes(const struct in6_addr* address) { struct in6_addr all_zeroes = IN6ADDR_ANY_INIT; diff --git a/src/network-list.c b/src/network-list.c index 2765cec..095d82f 100644 --- a/src/network-list.c +++ b/src/network-list.c @@ -358,7 +358,7 @@ int loc_network_list_summarize(struct loc_ctx* ctx, int bits = (bits1 > bits2) ? bits2 : bits1; // Create a network - r = loc_network_new(ctx, &network, &start, 128 - bits); + r = loc_network_new(ctx, &network, &start, family_bit_length - bits); if (r) return r; diff --git a/src/network.c b/src/network.c index 3967e29..445f1ef 100644 --- a/src/network.c +++ b/src/network.c @@ -47,22 +47,10 @@ struct loc_network { enum loc_network_flags flags; }; -static int valid_prefix(struct in6_addr* address, unsigned int prefix) { - // The prefix cannot be larger than 128 bits - if (prefix > 128) - return 1; - - // For IPv4-mapped addresses the prefix has to be 96 or lager - if (IN6_IS_ADDR_V4MAPPED(address) && prefix <= 96) - return 1; - - return 0; -} - LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network, struct in6_addr* address, unsigned int prefix) { // Validate the prefix - if (valid_prefix(address, prefix) != 0) { + if (!loc_address_valid_prefix(address, prefix)) { ERROR(ctx, "Invalid prefix: %u\n", prefix); errno = EINVAL; return 1; @@ -78,7 +66,10 @@ LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network n->refcount = 1; // Store the prefix - n->prefix = prefix; + if (IN6_IS_ADDR_V4MAPPED(address)) + n->prefix = prefix + 96; + else + n->prefix = prefix; // Convert the prefix into a bitmask struct in6_addr bitmask = loc_prefix_to_bitmask(n->prefix); @@ -129,10 +120,6 @@ LOC_EXPORT int loc_network_new_from_string(struct loc_ctx* ctx, struct loc_netwo DEBUG(ctx, "The prefix was not parsable: %s\n", prefix_string); goto FAIL; } - - // Map the prefix to IPv6 if needed - if (IN6_IS_ADDR_V4MAPPED(&first_address)) - prefix += 96; } FAIL: @@ -425,7 +412,7 @@ LOC_EXPORT int loc_network_subnets(struct loc_network* network, unsigned int prefix = network->prefix + 1; // Check if the new prefix is valid - if (valid_prefix(&network->first_address, prefix)) + if (!loc_address_valid_prefix(&network->first_address, prefix)) return -1; // Create the first half of the network @@ -685,6 +672,10 @@ int loc_network_new_from_database_v1(struct loc_ctx* ctx, struct loc_network** n struct in6_addr* address, unsigned int prefix, const struct loc_database_network_v1* dbobj) { char country_code[3] = "\0\0"; + // Adjust prefix for IPv4 + if (IN6_IS_ADDR_V4MAPPED(address)) + prefix -= 96; + int r = loc_network_new(ctx, network, address, prefix); if (r) { ERROR(ctx, "Could not allocate a new network: %s", strerror(-r)); -- 2.39.2