int main(int argc, char *argv[]) { if (argc < 2) { printf("Usage: prefix-to-mask <prefixlen>\n"); exit(EXIT_FAILURE); } prefix_to_mask(atoi(argv[1])); exit(EXIT_SUCCESS); }
/** * gnutls_x509_cidr_to_rfc5280: * @cidr: CIDR in RFC4632 format (IP/prefix), null-terminated * @cidr_rfc5280: CIDR range converted to RFC5280 format * * This function will convert text CIDR range with prefix (such as '10.0.0.0/8') * to RFC5280 (IP address in network byte order followed by its network mask). * Works for both IPv4 and IPv6. * * The resulting object is directly usable for IP name constraints usage, * for example in functions %gnutls_x509_name_constraints_add_permitted * or %gnutls_x509_name_constraints_add_excluded. * * The data in datum needs to be deallocated using gnutls_free(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value. * * Since: 3.5.4 */ int gnutls_x509_cidr_to_rfc5280(const char *cidr, gnutls_datum_t *cidr_rfc5280) { unsigned iplength, prefix; int ret; char *p; char *p_end = NULL; char *cidr_tmp; p = strchr(cidr, '/'); if (p != NULL) { prefix = strtol(p+1, &p_end, 10); if (prefix == 0 && p_end == p+1) { _gnutls_debug_log("Cannot parse prefix given in CIDR %s\n", cidr); gnutls_assert(); return GNUTLS_E_MALFORMED_CIDR; } unsigned length = p-cidr+1; cidr_tmp = gnutls_malloc(length); if (cidr_tmp == NULL) { return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); } memcpy(cidr_tmp, cidr, length); cidr_tmp[length-1] = 0; } else { _gnutls_debug_log("No prefix given in CIDR %s\n", cidr); gnutls_assert(); return GNUTLS_E_MALFORMED_CIDR; } if (strchr(cidr, ':') != 0) { /* IPv6 */ iplength = 16; } else { /* IPv4 */ iplength = 4; } cidr_rfc5280->size = 2*iplength; if (prefix > iplength*8) { _gnutls_debug_log("Invalid prefix given in CIDR %s (%d)\n", cidr, prefix); ret = gnutls_assert_val(GNUTLS_E_MALFORMED_CIDR); goto cleanup; } cidr_rfc5280->data = gnutls_malloc(cidr_rfc5280->size); if (cidr_rfc5280->data == NULL) { ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); goto cleanup; } ret = inet_pton(iplength == 4 ? AF_INET : AF_INET6, cidr_tmp, cidr_rfc5280->data); if (ret == 0) { _gnutls_debug_log("Cannot parse IP from CIDR %s\n", cidr_tmp); ret = gnutls_assert_val(GNUTLS_E_MALFORMED_CIDR); goto cleanup; } prefix_to_mask(prefix, &cidr_rfc5280->data[iplength], iplength); _gnutls_mask_ip(cidr_rfc5280->data, &cidr_rfc5280->data[iplength], iplength); ret = GNUTLS_E_SUCCESS; cleanup: gnutls_free(cidr_tmp); return ret; }