diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index 122bb17a95..f5cabc6534 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -12,6 +12,7 @@ #include "macro.h" #include "parse-util.h" #include "random-util.h" +#include "strxcpyx.h" #include "util.h" bool in4_addr_is_null(const struct in_addr *a) { @@ -319,6 +320,40 @@ int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { return 0; } +int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret) { + _cleanup_free_ char *x = NULL; + char *p; + size_t l; + + assert(u); + assert(ret); + + if (family == AF_INET) + l = INET_ADDRSTRLEN + 3; + else if (family == AF_INET6) + l = INET6_ADDRSTRLEN + 4; + else + return -EAFNOSUPPORT; + + if (prefixlen > FAMILY_ADDRESS_SIZE(family) * 8) + return -EINVAL; + + x = new(char, l); + if (!x) + return -ENOMEM; + + errno = 0; + if (!inet_ntop(family, u, x, l)) + return errno > 0 ? -errno : -EINVAL; + + p = x + strlen(x); + l -= strlen(x); + (void) strpcpyf(&p, l, "/%u", prefixlen); + + *ret = TAKE_PTR(x); + return 0; +} + int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) { _cleanup_free_ char *x = NULL; size_t l; diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 3517fe1ea3..a6a685b918 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -37,6 +37,7 @@ int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen); int in_addr_to_string(int family, const union in_addr_union *u, char **ret); +int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret); int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret); int in_addr_from_string(int family, const char *s, union in_addr_union *ret); int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret);