提交 1f9546e3 编写于 作者: M Michal Privoznik

virsocket: Introduce virSocketAddrIsWildcard

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: NMichal Privoznik <mprivozn@redhat.com>
上级 72aafe9c
...@@ -1683,6 +1683,7 @@ virSocketAddrGetIpPrefix; ...@@ -1683,6 +1683,7 @@ virSocketAddrGetIpPrefix;
virSocketAddrGetPort; virSocketAddrGetPort;
virSocketAddrGetRange; virSocketAddrGetRange;
virSocketAddrIsNetmask; virSocketAddrIsNetmask;
virSocketAddrIsNumeric;
virSocketAddrIsPrivate; virSocketAddrIsPrivate;
virSocketAddrIsWildcard; virSocketAddrIsWildcard;
virSocketAddrMask; virSocketAddrMask;
......
...@@ -71,6 +71,35 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr ...@@ -71,6 +71,35 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr
return 0; 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: * virSocketAddrParse:
* @val: a numeric network address IPv4 or IPv6 * @val: a numeric network address IPv4 or IPv6
...@@ -84,24 +113,10 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr ...@@ -84,24 +113,10 @@ static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr
*/ */
int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) { int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) {
int len; int len;
struct addrinfo hints; struct addrinfo *res;
struct addrinfo *res = NULL;
int err;
if (val == NULL) { if (virSocketAddrParseInternal(&res, val, family, true) < 0)
virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
return -1; 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) { if (res == NULL) {
virReportError(VIR_ERR_SYSTEM_ERROR, virReportError(VIR_ERR_SYSTEM_ERROR,
...@@ -824,3 +839,28 @@ virSocketAddrGetIpPrefix(const virSocketAddrPtr address, ...@@ -824,3 +839,28 @@ virSocketAddrGetIpPrefix(const virSocketAddrPtr address,
*/ */
return 0; 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;
}
...@@ -124,4 +124,6 @@ bool virSocketAddrEqual(const virSocketAddrPtr s1, ...@@ -124,4 +124,6 @@ bool virSocketAddrEqual(const virSocketAddrPtr s1,
bool virSocketAddrIsPrivate(const virSocketAddrPtr addr); bool virSocketAddrIsPrivate(const virSocketAddrPtr addr);
bool virSocketAddrIsWildcard(const virSocketAddrPtr addr); bool virSocketAddrIsWildcard(const virSocketAddrPtr addr);
bool virSocketAddrIsNumeric(const char *address);
#endif /* __VIR_SOCKETADDR_H__ */ #endif /* __VIR_SOCKETADDR_H__ */
...@@ -174,6 +174,21 @@ static int testWildcardHelper(const void *opaque) ...@@ -174,6 +174,21 @@ static int testWildcardHelper(const void *opaque)
return testWildcard(data->addr, data->pass); 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 static int
mymain(void) mymain(void)
{ {
...@@ -246,6 +261,14 @@ mymain(void) ...@@ -246,6 +261,14 @@ mymain(void)
ret = -1; \ ret = -1; \
} while (0) } 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_UNSPEC, true);
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true); DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
...@@ -307,6 +330,12 @@ mymain(void) ...@@ -307,6 +330,12 @@ mymain(void)
DO_TEST_WILDCARD("1", false); DO_TEST_WILDCARD("1", false);
DO_TEST_WILDCARD("0.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; return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册