X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fnetwork.c;h=0266ebf3edc0fd63e159b0faa9a785e87a2654f6;hb=5559e08681b0a78118d6ee1671213693625e4e0a;hp=4b2b279c76e357daf36295b7fbb2c799491739c7;hpb=0258d3c9eb6e32991b3c9f498ccc109d4cdae591;p=people%2Fms%2Flibloc.git diff --git a/src/network.c b/src/network.c index 4b2b279..0266ebf 100644 --- a/src/network.c +++ b/src/network.c @@ -51,10 +51,6 @@ static int valid_prefix(struct in6_addr* address, unsigned int prefix) { if (prefix > 128) return 1; - // And the prefix cannot be zero - if (prefix == 0) - return 1; - // For IPv4-mapped addresses the prefix has to be 96 or lager if (IN6_IS_ADDR_V4MAPPED(address) && prefix <= 96) return 1; @@ -62,77 +58,20 @@ static int valid_prefix(struct in6_addr* address, unsigned int prefix) { return 0; } -static struct in6_addr prefix_to_bitmask(unsigned int prefix) { - struct in6_addr bitmask; - - for (unsigned int i = 0; i < 16; i++) - bitmask.s6_addr[i] = 0; - - for (int i = prefix, j = 0; i > 0; i -= 8, j++) { - if (i >= 8) - bitmask.s6_addr[j] = 0xff; - else - bitmask.s6_addr[j] = 0xff << (8 - i); - } - - return bitmask; -} - -static struct in6_addr make_first_address(const struct in6_addr* address, const struct in6_addr* bitmask) { - struct in6_addr a; - - // Perform bitwise AND - for (unsigned int i = 0; i < 4; i++) - a.s6_addr32[i] = address->s6_addr32[i] & bitmask->s6_addr32[i]; - - return a; -} - -static struct in6_addr make_last_address(const struct in6_addr* address, const struct in6_addr* bitmask) { - struct in6_addr a; - - // Perform bitwise OR - for (unsigned int i = 0; i < 4; i++) - a.s6_addr32[i] = address->s6_addr32[i] | ~bitmask->s6_addr32[i]; - - return a; -} - LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network, struct in6_addr* address, unsigned int prefix) { - // Address cannot be unspecified - if (IN6_IS_ADDR_UNSPECIFIED(address)) { - DEBUG(ctx, "Start address is unspecified\n"); - return -EINVAL; - } - - // Address cannot be loopback - if (IN6_IS_ADDR_LOOPBACK(address)) { - DEBUG(ctx, "Start address is loopback address\n"); - return -EINVAL; - } - - // Address cannot be link-local - if (IN6_IS_ADDR_LINKLOCAL(address)) { - DEBUG(ctx, "Start address cannot be link-local\n"); - return -EINVAL; - } - - // Address cannot be site-local - if (IN6_IS_ADDR_SITELOCAL(address)) { - DEBUG(ctx, "Start address cannot be site-local\n"); - return -EINVAL; - } - // Validate the prefix if (valid_prefix(address, prefix) != 0) { - DEBUG(ctx, "Invalid prefix: %u\n", prefix); - return -EINVAL; + ERROR(ctx, "Invalid prefix: %u\n", prefix); + errno = EINVAL; + return 1; } struct loc_network* n = calloc(1, sizeof(*n)); - if (!n) - return -ENOMEM; + if (!n) { + errno = ENOMEM; + return 1; + } n->ctx = loc_ref(ctx); n->refcount = 1; @@ -141,11 +80,11 @@ LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network n->prefix = prefix; // Convert the prefix into a bitmask - struct in6_addr bitmask = prefix_to_bitmask(n->prefix); + struct in6_addr bitmask = loc_prefix_to_bitmask(n->prefix); // Store the first and last address in the network - n->first_address = make_first_address(address, &bitmask); - n->last_address = make_last_address(&n->first_address, &bitmask); + n->first_address = loc_address_and(address, &bitmask); + n->last_address = loc_address_or(&n->first_address, &bitmask); // Set family n->family = loc_address_family(&n->first_address);