summaryrefslogtreecommitdiff
path: root/src/basic/in-addr-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/in-addr-util.c')
-rw-r--r--src/basic/in-addr-util.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c
index 3927df2955..d52fdad3ac 100644
--- a/src/basic/in-addr-util.c
+++ b/src/basic/in-addr-util.c
@@ -464,3 +464,45 @@ int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen)
return -EAFNOSUPPORT;
}
+
+int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, uint8_t *ret_prefixlen) {
+ union in_addr_union buffer;
+ const char *e, *l;
+ uint8_t k;
+ int r;
+
+ assert(p);
+
+ if (!IN_SET(family, AF_INET, AF_INET6))
+ return -EAFNOSUPPORT;
+
+ e = strchr(p, '/');
+ if (e)
+ l = strndupa(p, e - p);
+ else
+ l = p;
+
+ r = in_addr_from_string(family, l, &buffer);
+ if (r < 0)
+ return r;
+
+ k = FAMILY_ADDRESS_SIZE(family) * 8;
+
+ if (e) {
+ uint8_t n;
+
+ r = safe_atou8(e + 1, &n);
+ if (r < 0)
+ return r;
+
+ if (n > k)
+ return -ERANGE;
+
+ k = n;
+ }
+
+ *ret_prefix = buffer;
+ *ret_prefixlen = k;
+
+ return 0;
+}