static int verify_cidr(const char *cidr)
{
	char *address = NULL, *slash = NULL;
	bool has_colon, has_dot;
	int res, ret;
	unsigned long mask;
	uint8_t *address_bytes = NULL;
	char *address_redux = NULL;
	unsigned int address_len;
	TALLOC_CTX *frame = NULL;
	int error = 0;

	DBG_DEBUG("CIDR is %s\n", cidr);
	frame = talloc_stackframe();
	address = talloc_strdup(frame, cidr);
	if (address == NULL){
		goto error;
	}

	/* there must be a '/' */
	slash = strchr(address, '/');
	if (slash == NULL){
		goto error;
	}
	/* terminate the address for strchr, inet_pton */
	*slash = '\0';

	mask = smb_strtoul(slash + 1, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
	if (mask == 0){
		DBG_INFO("Windows does not like the zero mask, "
			 "so nor do we: %s\n", cidr);
		goto error;
	}

	if (error != 0){
		DBG_INFO("CIDR mask is not a proper integer: %s\n", cidr);
		goto error;
	}

	address_bytes = talloc_size(frame, sizeof(struct in6_addr));
	if (address_bytes == NULL){
		goto error;
	}

	address_redux = talloc_size(frame, INET6_ADDRSTRLEN);
	if (address_redux == NULL){
		goto error;
	}

	DBG_INFO("found address %s, mask %lu\n", address, mask);
	has_colon = (strchr(address, ':') == NULL) ? false : true;
	has_dot = (strchr(address, '.') == NULL) ? false : true;
	if (has_dot && has_colon){
		/* This seems to be an IPv4 address embedded in IPv6, which is
		   icky. We don't support it. */
		DBG_INFO("Refusing to consider cidr '%s' with dots and colons\n",
			  cidr);
		goto error;
	} else if (has_colon){	/* looks like IPv6 */
		res = inet_pton(AF_INET6, address, address_bytes);
		if (res != 1) {
			DBG_INFO("Address in %s fails to parse as IPv6\n", cidr);
			goto error;
		}
		address_len = 128;
		if (check_address_roundtrip(address, AF_INET6, address_bytes,
					    address_redux, INET6_ADDRSTRLEN)){
			goto error;
		}
	} else if (has_dot) {
		/* looks like IPv4 */
		if (strcmp(address, "0.0.0.0") == 0){
			DBG_INFO("Windows does not like the zero IPv4 address, "
				 "so nor do we.\n");
			goto error;
		}
		res = inet_pton(AF_INET, address, address_bytes);
		if (res != 1) {
			DBG_INFO("Address in %s fails to parse as IPv4\n", cidr);
			goto error;
		}
		address_len = 32;

		if (check_address_roundtrip(address, AF_INET, address_bytes,
					    address_redux, INET_ADDRSTRLEN)){
			goto error;
		}
	} else {
		/* This doesn't look like an IP address at all. */
		goto error;
	}

	ret = check_cidr_zero_bits(address_bytes, address_len, mask);
	talloc_free(frame);
	return ret;
  error:
	talloc_free(frame);
	return -1;
}
static int verify_cidr(const char *cidr)
{
	char *address = NULL, *slash = NULL;
	bool has_colon, has_dot;
	int res, ret;
	unsigned long mask;
	uint8_t *address_bytes = NULL;
	char *address_redux = NULL;
	unsigned int address_len;
	TALLOC_CTX *frame = NULL;
	int error = 0;

	DBG_DEBUG("CIDR is %s\n", cidr);
	frame = talloc_stackframe();
	address = talloc_strdup(frame, cidr);
	if (address == NULL){
		goto error;
	}

	 
	slash = strchr(address, '/');
	if (slash == NULL){
		goto error;
	}
	 
	*slash = '\0';

	mask = smb_strtoul(slash + 1, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
	if (mask == 0){
		DBG_INFO("Windows does not like the zero mask, "
			 "so nor do we: %s\n", cidr);
		goto error;
	}

	if (error != 0){
		DBG_INFO("CIDR mask is not a proper integer: %s\n", cidr);
		goto error;
	}

	address_bytes = talloc_size(frame, sizeof(struct in6_addr));
	if (address_bytes == NULL){
		goto error;
	}

	address_redux = talloc_size(frame, INET6_ADDRSTRLEN);
	if (address_redux == NULL){
		goto error;
	}

	DBG_INFO("found address %s, mask %lu\n", address, mask);
	has_colon = (strchr(address, ':') == NULL) ? false : true;
	has_dot = (strchr(address, '.') == NULL) ? false : true;
	if (has_dot && has_colon){
		 
		DBG_INFO("Refusing to consider cidr '%s' with dots and colons\n",
			  cidr);
		goto error;
	} else if (has_colon){	 
		res = inet_pton(AF_INET6, address, address_bytes);
		if (res != 1) {
			DBG_INFO("Address in %s fails to parse as IPv6\n", cidr);
			goto error;
		}
		address_len = 128;
		if (check_address_roundtrip(address, AF_INET6, address_bytes,
					    address_redux, INET6_ADDRSTRLEN)){
			goto error;
		}
	} else if (has_dot) {
		 
		if (strcmp(address, "0.0.0.0") == 0){
			DBG_INFO("Windows does not like the zero IPv4 address, "
				 "so nor do we.\n");
			goto error;
		}
		res = inet_pton(AF_INET, address, address_bytes);
		if (res != 1) {
			DBG_INFO("Address in %s fails to parse as IPv4\n", cidr);
			goto error;
		}
		address_len = 32;

		if (check_address_roundtrip(address, AF_INET, address_bytes,
					    address_redux, INET_ADDRSTRLEN)){
			goto error;
		}
	} else {
		 
		goto error;
	}

	ret = check_cidr_zero_bits(address_bytes, address_len, mask);
	talloc_free(frame);
	return ret;
  error:
	talloc_free(frame);
	return -1;
}