43fe83
From 6d4ec90d10bff86d33343551fc99be3fa15189a5 Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <6d4ec90d10bff86d33343551fc99be3fa15189a5.1382534061.git.jdenemar@redhat.com>
43fe83
From: Michal Privoznik <mprivozn@redhat.com>
43fe83
Date: Fri, 11 Oct 2013 11:24:34 +0200
43fe83
Subject: [PATCH] virsocket: Introduce virSocketAddrIsWildcard
43fe83
43fe83
https://bugzilla.redhat.com/show_bug.cgi?id=1015215
43fe83
43fe83
This function takes exactly one argument: an address to check.
43fe83
It returns true, if the address is an IPv4 or IPv6 address in numeric
43fe83
format, false otherwise (e.g. for "examplehost").
43fe83
43fe83
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
43fe83
(cherry picked from commit 1f9546e365e8beab1a4b681cc34105e0ac74be70)
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/libvirt_private.syms |  1 +
43fe83
 src/util/virsocketaddr.c | 72 +++++++++++++++++++++++++++++++++++++-----------
43fe83
 src/util/virsocketaddr.h |  2 ++
43fe83
 tests/sockettest.c       | 29 +++++++++++++++++++
43fe83
 4 files changed, 88 insertions(+), 16 deletions(-)
43fe83
43fe83
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
43fe83
index 9a00dfe..f96f126 100644
43fe83
--- a/src/libvirt_private.syms
43fe83
+++ b/src/libvirt_private.syms
43fe83
@@ -1874,6 +1874,7 @@ virSocketAddrGetIpPrefix;
43fe83
 virSocketAddrGetPort;
43fe83
 virSocketAddrGetRange;
43fe83
 virSocketAddrIsNetmask;
43fe83
+virSocketAddrIsNumeric;
43fe83
 virSocketAddrIsPrivate;
43fe83
 virSocketAddrIsWildcard;
43fe83
 virSocketAddrMask;
43fe83
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
43fe83
index 3e01baf..6df9205 100644
43fe83
--- a/src/util/virsocketaddr.c
43fe83
+++ b/src/util/virsocketaddr.c
43fe83
@@ -71,6 +71,35 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr
43fe83
     return 0;
43fe83
 }
43fe83
 
43fe83
+static int
43fe83
+virSocketAddrParseInternal(struct addrinfo **res,
43fe83
+                           const char *val,
43fe83
+                           int family,
43fe83
+                           bool reportError)
43fe83
+{
43fe83
+    struct addrinfo hints;
43fe83
+    int err;
43fe83
+
43fe83
+    if (val == NULL) {
43fe83
+        virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
43fe83
+        return -1;
43fe83
+    }
43fe83
+
43fe83
+    memset(&hints, 0, sizeof(hints));
43fe83
+    hints.ai_family = family;
43fe83
+    hints.ai_flags = AI_NUMERICHOST;
43fe83
+    if ((err = getaddrinfo(val, NULL, &hints, res)) != 0) {
43fe83
+        if (reportError)
43fe83
+            virReportError(VIR_ERR_SYSTEM_ERROR,
43fe83
+                           _("Cannot parse socket address '%s': %s"),
43fe83
+                           val, gai_strerror(err));
43fe83
+
43fe83
+        return -1;
43fe83
+    }
43fe83
+
43fe83
+    return 0;
43fe83
+}
43fe83
+
43fe83
 /**
43fe83
  * virSocketAddrParse:
43fe83
  * @val: a numeric network address IPv4 or IPv6
43fe83
@@ -84,24 +113,10 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr
43fe83
  */
43fe83
 int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) {
43fe83
     int len;
43fe83
-    struct addrinfo hints;
43fe83
-    struct addrinfo *res = NULL;
43fe83
-    int err;
43fe83
+    struct addrinfo *res;
43fe83
 
43fe83
-    if (val == NULL) {
43fe83
-        virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
43fe83
+    if (virSocketAddrParseInternal(&res, val, family, true) < 0)
43fe83
         return -1;
43fe83
-    }
43fe83
-
43fe83
-    memset(&hints, 0, sizeof(hints));
43fe83
-    hints.ai_family = family;
43fe83
-    hints.ai_flags = AI_NUMERICHOST;
43fe83
-    if ((err = getaddrinfo(val, NULL, &hints, &res)) != 0) {
43fe83
-        virReportError(VIR_ERR_SYSTEM_ERROR,
43fe83
-                       _("Cannot parse socket address '%s': %s"),
43fe83
-                       val, gai_strerror(err));
43fe83
-        return -1;
43fe83
-    }
43fe83
 
43fe83
     if (res == NULL) {
43fe83
         virReportError(VIR_ERR_SYSTEM_ERROR,
43fe83
@@ -824,3 +839,28 @@ virSocketAddrGetIpPrefix(const virSocketAddrPtr address,
43fe83
      */
43fe83
     return 0;
43fe83
 }
43fe83
+
43fe83
+/**
43fe83
+ * virSocketAddrIsNumeric:
43fe83
+ * @address: address to check
43fe83
+ *
43fe83
+ * Check if passed address is an IP address in numeric format. For
43fe83
+ * instance, for 0.0.0.0 true is returned, for 'examplehost"
43fe83
+ * false is returned.
43fe83
+ *
43fe83
+ * Returns: true if @address is an IP address,
43fe83
+ *          false otherwise
43fe83
+ */
43fe83
+bool
43fe83
+virSocketAddrIsNumeric(const char *address)
43fe83
+{
43fe83
+    struct addrinfo *res;
43fe83
+    unsigned short family;
43fe83
+
43fe83
+    if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
43fe83
+        return false;
43fe83
+
43fe83
+    family = res->ai_addr->sa_family;
43fe83
+    freeaddrinfo(res);
43fe83
+    return family == AF_INET || family == AF_INET6;
43fe83
+}
43fe83
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
43fe83
index b28fe6c..d844914 100644
43fe83
--- a/src/util/virsocketaddr.h
43fe83
+++ b/src/util/virsocketaddr.h
43fe83
@@ -124,4 +124,6 @@ bool virSocketAddrEqual(const virSocketAddrPtr s1,
43fe83
 bool virSocketAddrIsPrivate(const virSocketAddrPtr addr);
43fe83
 
43fe83
 bool virSocketAddrIsWildcard(const virSocketAddrPtr addr);
43fe83
+
43fe83
+bool virSocketAddrIsNumeric(const char *address);
43fe83
 #endif /* __VIR_SOCKETADDR_H__ */
43fe83
diff --git a/tests/sockettest.c b/tests/sockettest.c
43fe83
index 092de88..5dcf636 100644
43fe83
--- a/tests/sockettest.c
43fe83
+++ b/tests/sockettest.c
43fe83
@@ -180,6 +180,21 @@ static int testWildcardHelper(const void *opaque)
43fe83
     return testWildcard(data->addr, data->pass);
43fe83
 }
43fe83
 
43fe83
+struct testIsNumericData {
43fe83
+    const char *addr;
43fe83
+    bool pass;
43fe83
+};
43fe83
+
43fe83
+static int
43fe83
+testIsNumericHelper(const void *opaque)
43fe83
+{
43fe83
+    const struct testIsNumericData *data = opaque;
43fe83
+
43fe83
+    if (virSocketAddrIsNumeric(data->addr))
43fe83
+        return data->pass ? 0 : -1;
43fe83
+    return data->pass ? -1 : 0;
43fe83
+}
43fe83
+
43fe83
 static int
43fe83
 mymain(void)
43fe83
 {
43fe83
@@ -253,6 +268,14 @@ mymain(void)
43fe83
             ret = -1;                                                   \
43fe83
     } while (0)
43fe83
 
43fe83
+#define DO_TEST_IS_NUMERIC(addr, pass)                                  \
43fe83
+    do {                                                                \
43fe83
+        struct testIsNumericData data = { addr, pass};                  \
43fe83
+        if (virtTestRun("Test isNumeric " addr, 1,                      \
43fe83
+                        testIsNumericHelper, &data) < 0)                \
43fe83
+            ret = -1;                                                   \
43fe83
+    } while (0)
43fe83
+
43fe83
 
43fe83
     DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true);
43fe83
     DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
43fe83
@@ -314,6 +337,12 @@ mymain(void)
43fe83
     DO_TEST_WILDCARD("1", false);
43fe83
     DO_TEST_WILDCARD("0.1", false);
43fe83
 
43fe83
+    DO_TEST_IS_NUMERIC("0.0.0.0", true);
43fe83
+    DO_TEST_IS_NUMERIC("::", true);
43fe83
+    DO_TEST_IS_NUMERIC("1", true);
43fe83
+    DO_TEST_IS_NUMERIC("::ffff", true);
43fe83
+    DO_TEST_IS_NUMERIC("examplehost", false);
43fe83
+
43fe83
     return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
43fe83
 }
43fe83
 
43fe83
-- 
43fe83
1.8.4
43fe83