summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-06-03 16:37:38 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-06-06 09:52:52 +0200
commitc71384a9ee73c1488d831b09f5ee88a804e1ddcd (patch)
tree13116e7a71d9607f4506a9499e3c427215b0fe84 /src/basic
parentbasic/in-addr-util: drop check for prefix length in formatting function (diff)
downloadsystemd-c71384a9ee73c1488d831b09f5ee88a804e1ddcd.tar.xz
systemd-c71384a9ee73c1488d831b09f5ee88a804e1ddcd.zip
basic/in-addr-util: add IN_ADDR_PREFIX_TO_STRING
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/in-addr-util.c35
-rw-r--r--src/basic/in-addr-util.h34
2 files changed, 45 insertions, 24 deletions
diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c
index 6bf017260b..6f8ffaf259 100644
--- a/src/basic/in-addr-util.c
+++ b/src/basic/in-addr-util.c
@@ -14,6 +14,7 @@
#include "macro.h"
#include "parse-util.h"
#include "random-util.h"
+#include "stdio-util.h"
#include "string-util.h"
#include "strxcpyx.h"
#include "util.h"
@@ -451,34 +452,26 @@ 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;
+int in_addr_prefix_to_string(
+ int family,
+ const union in_addr_union *u,
+ unsigned prefixlen,
+ char *buf,
+ size_t buf_len) {
assert(u);
- assert(ret);
+ assert(buf);
- if (family == AF_INET)
- l = INET_ADDRSTRLEN + 1 + DECIMAL_STR_MAX(unsigned);
- else if (family == AF_INET6)
- l = INET6_ADDRSTRLEN + 1 + DECIMAL_STR_MAX(unsigned);
- else
+ if (!IN_SET(family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
- x = new(char, l);
- if (!x)
- return -ENOMEM;
-
errno = 0;
- if (!inet_ntop(family, u, x, l))
- return errno_or_else(EINVAL);
+ if (!typesafe_inet_ntop(family, u, buf, buf_len))
+ return errno_or_else(ENOSPC);
- p = x + strlen(x);
- l -= strlen(x);
- (void) strpcpyf(&p, l, "/%u", prefixlen);
-
- *ret = TAKE_PTR(x);
+ size_t l = strlen(buf);
+ if (!snprintf_ok(buf + l, buf_len - l, "/%u", prefixlen))
+ return -ENOSPC;
return 0;
}
diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h
index 89d0505c13..c1e7ef965d 100644
--- a/src/basic/in-addr-util.h
+++ b/src/basic/in-addr-util.h
@@ -93,10 +93,38 @@ static inline const char* typesafe_inet_ntop6(const struct in6_addr *a, char *bu
#define IN4_ADDR_TO_STRING(addr) typesafe_inet_ntop4(addr, (char[INET_ADDRSTRLEN]){}, INET_ADDRSTRLEN)
#define IN6_ADDR_TO_STRING(addr) typesafe_inet_ntop6(addr, (char[INET6_ADDRSTRLEN]){}, INET6_ADDRSTRLEN)
-int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret);
-static inline int in6_addr_prefix_to_string(const struct in6_addr *u, unsigned prefixlen, char **ret) {
- return in_addr_prefix_to_string(AF_INET6, (const union in_addr_union*) u, prefixlen, ret);
+int in_addr_prefix_to_string(
+ int family,
+ const union in_addr_union *u,
+ unsigned prefixlen,
+ char *buf,
+ size_t buf_len);
+
+static inline const char* _in_addr_prefix_to_string(
+ int family,
+ const union in_addr_union *u,
+ unsigned prefixlen,
+ char *buf,
+ size_t buf_len) {
+ /* We assume that this is called with an appropriately sized buffer and can never fail. */
+ assert_se(in_addr_prefix_to_string(family, u, prefixlen, buf, buf_len) == 0);
+ return buf;
}
+static inline const char* _in4_addr_prefix_to_string(const struct in_addr *a, unsigned prefixlen, char *buf, size_t buf_len) {
+ return _in_addr_prefix_to_string(AF_INET, (const union in_addr_union *) a, prefixlen, buf, buf_len);
+}
+static inline const char* _in6_addr_prefix_to_string(const struct in6_addr *a, unsigned prefixlen, char *buf, size_t buf_len) {
+ return _in_addr_prefix_to_string(AF_INET6, (const union in_addr_union *) a, prefixlen, buf, buf_len);
+}
+
+#define PREFIX_SUFFIX_MAX (1 + DECIMAL_STR_MAX(unsigned))
+#define IN_ADDR_PREFIX_TO_STRING(family, addr, prefixlen) \
+ _in_addr_prefix_to_string(family, addr, prefixlen, (char[IN_ADDR_MAX + PREFIX_SUFFIX_MAX]){}, IN_ADDR_MAX + PREFIX_SUFFIX_MAX)
+#define IN4_ADDR_PREFIX_TO_STRING(addr, prefixlen) \
+ _in4_addr_prefix_to_string(addr, prefixlen, (char[INET_ADDRSTRLEN + PREFIX_SUFFIX_MAX]){}, INET_ADDRSTRLEN + PREFIX_SUFFIX_MAX)
+#define IN6_ADDR_PREFIX_TO_STRING(addr, prefixlen) \
+ _in6_addr_prefix_to_string(addr, prefixlen, (char[INET6_ADDRSTRLEN + PREFIX_SUFFIX_MAX]){}, INET6_ADDRSTRLEN + PREFIX_SUFFIX_MAX)
+
int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret);
static inline int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) {
return in_addr_port_ifindex_name_to_string(family, u, 0, ifindex, NULL, ret);