]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsocket: Introduce virSocketAddrIsWildcard
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 9 Oct 2013 13:10:02 +0000 (15:10 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 11 Oct 2013 09:05:06 +0000 (11:05 +0200)
This function takes exactly one argument: an address to check.
It returns true, if the address is an IPv4 or IPv6 address in numeric
format, false otherwise (e.g. for "examplehost").

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/libvirt_private.syms
src/util/virsocketaddr.c
src/util/virsocketaddr.h
tests/sockettest.c

index cdeb8e06e6de672a1ae8450518f99ba4853faf5e..844ca29d7abeee99047cd2b015768b4b212a9f5e 100644 (file)
@@ -1683,6 +1683,7 @@ virSocketAddrGetIpPrefix;
 virSocketAddrGetPort;
 virSocketAddrGetRange;
 virSocketAddrIsNetmask;
+virSocketAddrIsNumeric;
 virSocketAddrIsPrivate;
 virSocketAddrIsWildcard;
 virSocketAddrMask;
index 3e01baf1907031871f7bdbe2f6188855d92f0d6a..6df9205976b8a70870b5fa515f2cc4d7e73ffae4 100644 (file)
@@ -71,6 +71,35 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr
     return 0;
 }
 
+static int
+virSocketAddrParseInternal(struct addrinfo **res,
+                           const char *val,
+                           int family,
+                           bool reportError)
+{
+    struct addrinfo hints;
+    int err;
+
+    if (val == NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
+        return -1;
+    }
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = family;
+    hints.ai_flags = AI_NUMERICHOST;
+    if ((err = getaddrinfo(val, NULL, &hints, res)) != 0) {
+        if (reportError)
+            virReportError(VIR_ERR_SYSTEM_ERROR,
+                           _("Cannot parse socket address '%s': %s"),
+                           val, gai_strerror(err));
+
+        return -1;
+    }
+
+    return 0;
+}
+
 /**
  * virSocketAddrParse:
  * @val: a numeric network address IPv4 or IPv6
@@ -84,24 +113,10 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr
  */
 int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) {
     int len;
-    struct addrinfo hints;
-    struct addrinfo *res = NULL;
-    int err;
+    struct addrinfo *res;
 
-    if (val == NULL) {
-        virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
+    if (virSocketAddrParseInternal(&res, val, family, true) < 0)
         return -1;
-    }
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = family;
-    hints.ai_flags = AI_NUMERICHOST;
-    if ((err = getaddrinfo(val, NULL, &hints, &res)) != 0) {
-        virReportError(VIR_ERR_SYSTEM_ERROR,
-                       _("Cannot parse socket address '%s': %s"),
-                       val, gai_strerror(err));
-        return -1;
-    }
 
     if (res == NULL) {
         virReportError(VIR_ERR_SYSTEM_ERROR,
@@ -824,3 +839,28 @@ virSocketAddrGetIpPrefix(const virSocketAddrPtr address,
      */
     return 0;
 }
+
+/**
+ * virSocketAddrIsNumeric:
+ * @address: address to check
+ *
+ * Check if passed address is an IP address in numeric format. For
+ * instance, for 0.0.0.0 true is returned, for 'examplehost"
+ * false is returned.
+ *
+ * Returns: true if @address is an IP address,
+ *          false otherwise
+ */
+bool
+virSocketAddrIsNumeric(const char *address)
+{
+    struct addrinfo *res;
+    unsigned short family;
+
+    if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
+        return false;
+
+    family = res->ai_addr->sa_family;
+    freeaddrinfo(res);
+    return family == AF_INET || family == AF_INET6;
+}
index b28fe6c7d5fd0ad5b0fbbc15a95b05669655a54d..d844914657082a9296cb960669343e88c59d4f4b 100644 (file)
@@ -124,4 +124,6 @@ bool virSocketAddrEqual(const virSocketAddrPtr s1,
 bool virSocketAddrIsPrivate(const virSocketAddrPtr addr);
 
 bool virSocketAddrIsWildcard(const virSocketAddrPtr addr);
+
+bool virSocketAddrIsNumeric(const char *address);
 #endif /* __VIR_SOCKETADDR_H__ */
index 4b38cdf016dee570d967610d6844ca48025458d1..f98955d6f0c1bd9959f9b00a485b282ed2ed4660 100644 (file)
@@ -174,6 +174,21 @@ static int testWildcardHelper(const void *opaque)
     return testWildcard(data->addr, data->pass);
 }
 
+struct testIsNumericData {
+    const char *addr;
+    bool pass;
+};
+
+static int
+testIsNumericHelper(const void *opaque)
+{
+    const struct testIsNumericData *data = opaque;
+
+    if (virSocketAddrIsNumeric(data->addr))
+        return data->pass ? 0 : -1;
+    return data->pass ? -1 : 0;
+}
+
 static int
 mymain(void)
 {
@@ -246,6 +261,14 @@ mymain(void)
             ret = -1;                                                   \
     } while (0)
 
+#define DO_TEST_IS_NUMERIC(addr, pass)                                  \
+    do {                                                                \
+        struct testIsNumericData data = { addr, pass};                  \
+        if (virtTestRun("Test isNumeric " addr,                         \
+                       testIsNumericHelper, &data) < 0)                 \
+            ret = -1;                                                   \
+    } while (0)
+
 
     DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true);
     DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
@@ -307,6 +330,12 @@ mymain(void)
     DO_TEST_WILDCARD("1", false);
     DO_TEST_WILDCARD("0.1", false);
 
+    DO_TEST_IS_NUMERIC("0.0.0.0", true);
+    DO_TEST_IS_NUMERIC("::", true);
+    DO_TEST_IS_NUMERIC("1", true);
+    DO_TEST_IS_NUMERIC("::ffff", true);
+    DO_TEST_IS_NUMERIC("examplehost", false);
+
     return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }