struct loc_ctx* ctx;
int refcount;
+ int family;
struct in6_addr first_address;
struct in6_addr last_address;
unsigned int prefix;
n->first_address = make_first_address(address, &bitmask);
n->last_address = make_last_address(&n->first_address, &bitmask);
+ // Set family
+ if (IN6_IS_ADDR_V4MAPPED(&n->first_address))
+ n->family = AF_INET;
+ else
+ n->family = AF_INET6;
+
DEBUG(n->ctx, "Network allocated at %p\n", n);
*network = n;
return 0;
LOC_EXPORT int loc_network_new_from_string(struct loc_ctx* ctx, struct loc_network** network,
const char* address_string) {
struct in6_addr first_address;
- unsigned int prefix = 0;
char* prefix_string;
- int r = 1;
+ int r = -EINVAL;
+
+ DEBUG(ctx, "Attempting to parse network %s\n", address_string);
// Make a copy of the string to work on it
char* buffer = strdup(address_string);
// Split address and prefix
address_string = strsep(&prefix_string, "/");
- // Did we find a prefix?
- if (prefix_string) {
- // Convert prefix to integer
- prefix = strtol(prefix_string, NULL, 10);
+ DEBUG(ctx, " Split into address = %s, prefix = %s\n", address_string, prefix_string);
- if (prefix) {
- // Parse the address
- r = loc_parse_address(ctx, address_string, &first_address);
+ // We need to have a prefix
+ if (!prefix_string) {
+ DEBUG(ctx, "No prefix set\n");
+ goto FAIL;
+ }
- // Map the prefix to IPv6 if needed
- if (IN6_IS_ADDR_V4MAPPED(&first_address))
- prefix += 96;
- }
+ // Convert prefix to integer
+ unsigned int prefix = strtol(prefix_string, NULL, 10);
+
+ // End if the prefix was invalid
+ if (!prefix) {
+ DEBUG(ctx, "The prefix is zero or not a number\n");
+ goto FAIL;
}
+ // Parse the address
+ r = loc_parse_address(ctx, address_string, &first_address);
+ if (r) {
+ DEBUG(ctx, "The address could not be parsed\n");
+ goto FAIL;
+ }
+
+ // Map the prefix to IPv6 if needed
+ if (IN6_IS_ADDR_V4MAPPED(&first_address))
+ prefix += 96;
+
+FAIL:
// Free temporary buffer
free(buffer);
- if (r == 0) {
- r = loc_network_new(ctx, network, &first_address, prefix);
- }
+ // Exit if the parsing was unsuccessful
+ if (r)
+ return r;
+
+ DEBUG(ctx, "GOT HERE\n");
- return r;
+ // Create a new network
+ return loc_network_new(ctx, network, &first_address, prefix);
}
LOC_EXPORT struct loc_network* loc_network_ref(struct loc_network* network) {
unsigned int prefix = network->prefix;
- int family = loc_network_address_family(network);
- switch (family) {
+ switch (network->family) {
case AF_INET6:
r = format_ipv6_address(&network->first_address, string, length);
break;
}
LOC_EXPORT int loc_network_address_family(struct loc_network* network) {
- if (IN6_IS_ADDR_V4MAPPED(&network->first_address))
- return AF_INET;
+ return network->family;
+}
+
+static char* loc_network_format_address(struct loc_network* network, const struct in6_addr* address) {
+ const size_t length = INET6_ADDRSTRLEN;
+
+ char* string = malloc(length);
+ if (!string)
+ return NULL;
+
+ int r = 0;
+
+ switch (network->family) {
+ case AF_INET6:
+ r = format_ipv6_address(address, string, length);
+ break;
+
+ case AF_INET:
+ r = format_ipv4_address(address, string, length);
+ break;
+
+ default:
+ r = -1;
+ break;
+ }
+
+ if (r) {
+ ERROR(network->ctx, "Could not format IP address to string: %s\n", strerror(errno));
+ free(string);
+
+ return NULL;
+ }
+
+ return string;
+}
+
+LOC_EXPORT char* loc_network_format_first_address(struct loc_network* network) {
+ return loc_network_format_address(network, &network->first_address);
+}
- return AF_INET6;
+LOC_EXPORT char* loc_network_format_last_address(struct loc_network* network) {
+ return loc_network_format_address(network, &network->last_address);
}
LOC_EXPORT int loc_network_match_address(struct loc_network* network, const struct in6_addr* address) {