From: Martin Schwenke Date: Thu, 7 Jun 2018 21:13:25 +0000 (+1000) Subject: ctdb-protocol: Add function ctdb_sock_addr_mask_from_string() X-Git-Tag: ldb-1.5.0~161 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a1fb7296ca1c32fbb85ade2d5f104690b83929b;p=thirdparty%2Fsamba.git ctdb-protocol: Add function ctdb_sock_addr_mask_from_string() Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c index 1b9a46ef8e2..69bd67bf5c5 100644 --- a/ctdb/protocol/protocol_util.c +++ b/ctdb/protocol/protocol_util.c @@ -298,6 +298,47 @@ int ctdb_sock_addr_from_string(const char *str, return ret; } +int ctdb_sock_addr_mask_from_string(const char *str, + ctdb_sock_addr *addr, + unsigned int *mask) +{ + char *p; + char s[64]; /* Much longer than INET6_ADDRSTRLEN */ + unsigned int m; + char *endp = NULL; + ssize_t len; + bool ret; + + if (addr == NULL || mask == NULL) { + return EINVAL; + } + + len = strlcpy(s, str, sizeof(s)); + if (len >= sizeof(s)) { + return EINVAL; + } + + p = rindex(s, '/'); + if (p == NULL) { + return EINVAL; + } + + m = strtoul(p+1, &endp, 10); + if (endp == p+1 || *endp != '\0') { + /* Empty string or trailing garbage */ + return EINVAL; + } + + *p = '\0'; + ret = ip_from_string(s, addr); + + if (ret == 0) { + *mask = m; + } + + return ret; +} + unsigned int ctdb_sock_addr_port(ctdb_sock_addr *addr) { switch (addr->sa.sa_family) { diff --git a/ctdb/protocol/protocol_util.h b/ctdb/protocol/protocol_util.h index 66a49136576..fa7189c22a4 100644 --- a/ctdb/protocol/protocol_util.h +++ b/ctdb/protocol/protocol_util.h @@ -41,6 +41,9 @@ const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, ctdb_sock_addr *addr, bool with_port); int ctdb_sock_addr_from_string(const char *str, ctdb_sock_addr *addr, bool with_port); +int ctdb_sock_addr_mask_from_string(const char *str, + ctdb_sock_addr *addr, + unsigned int *mask); unsigned int ctdb_sock_addr_port(ctdb_sock_addr *addr); void ctdb_sock_addr_set_port(ctdb_sock_addr *addr, unsigned int port); int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1, diff --git a/ctdb/tests/src/protocol_util_test.c b/ctdb/tests/src/protocol_util_test.c index eb7eb0ff88f..9b4729ec5ee 100644 --- a/ctdb/tests/src/protocol_util_test.c +++ b/ctdb/tests/src/protocol_util_test.c @@ -72,6 +72,36 @@ static void test_sock_addr_cmp(const char *ip1, const char *ip2, assert(ret == res); } +/* + * Test parsing of IP/mask, conversion to string + */ + +static void test_sock_addr_mask_from_string(const char *ip_mask) +{ + ctdb_sock_addr sa; + unsigned mask; + const char *s, *t; + int ret; + + ret = ctdb_sock_addr_mask_from_string(ip_mask, &sa, &mask); + assert(ret == 0); + s = ctdb_sock_addr_to_string(NULL, &sa, false); + assert(s != NULL); + t = talloc_asprintf(s, "%s/%u", s, mask); + assert(strcmp(ip_mask, t) == 0); + talloc_free(discard_const(s)); +} + +static void test_sock_addr_mask_from_string_bad(const char *ip_mask) +{ + ctdb_sock_addr sa; + unsigned mask; + int ret; + + ret = ctdb_sock_addr_mask_from_string(ip_mask, &sa, &mask); + assert(ret == EINVAL); +} + /* * Test parsing of connection, conversion to string */ @@ -324,6 +354,11 @@ int main(int argc, char *argv[]) test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136:123", "fe80::6af7:28ff:fefa:d136:122" , true, 1); + test_sock_addr_mask_from_string("127.0.0.1/8"); + test_sock_addr_mask_from_string("::1/128"); + test_sock_addr_mask_from_string("fe80::6af7:28ff:fefa:d136/64"); + test_sock_addr_mask_from_string_bad("127.0.0.1"); + test_connection_to_string("127.0.0.1:12345 127.0.0.2:54321"); test_connection_to_string("fe80::6af7:28ff:fefa:d137:12345 " "fe80::6af7:28ff:fefa:d138:54321");