diff options
author | Susant Sahani <ssahani@users.noreply.github.com> | 2017-05-06 00:04:07 +0000 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-05-05 20:04:07 -0400 |
commit | f7bf1abef9b4db7ffe18a6cf84db2aaef7d908d3 (patch) | |
tree | 76375c21a042debd6c1fe92de593eadc03f3cc88 /src/basic | |
parent | 192fa38bef60ecb7916145a050a683d7fced6915 (diff) |
socket-util: add parse_ip_prefix (#5867)systemd/master
networkd: replace parse prefix with generic in_addr_prefix_from_string
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/in-addr-util.c | 42 | ||||
-rw-r--r-- | src/basic/in-addr-util.h | 1 |
2 files changed, 43 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; +} diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 51a5aa67e4..14e27246b5 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -60,6 +60,7 @@ struct in_addr* in_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask); int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen); +int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, uint8_t *ret_prefixlen); static inline size_t FAMILY_ADDRESS_SIZE(int family) { assert(family == AF_INET || family == AF_INET6); |