]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-protocol: Add function ctdb_sock_addr_mask_from_string()
authorMartin Schwenke <martin@meltin.net>
Thu, 7 Jun 2018 21:13:25 +0000 (07:13 +1000)
committerAmitay Isaacs <amitay@samba.org>
Fri, 27 Jul 2018 03:45:20 +0000 (05:45 +0200)
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/protocol/protocol_util.c
ctdb/protocol/protocol_util.h
ctdb/tests/src/protocol_util_test.c

index 1b9a46ef8e2c0b13685f83847b98d73c451d85e5..69bd67bf5c5a39eed1c4ab8edbfbbef8b0885d0b 100644 (file)
@@ -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) {
index 66a491365764ac76529f34abd6cd2d85730fb854..fa7189c22a45805f007224298400c45fce54d77e 100644 (file)
@@ -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,
index eb7eb0ff88f17a8b01cdeeecbd374aaad359ed22..9b4729ec5eea52aa6c3e21b4ada4ef659294ce16 100644 (file)
@@ -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");