/* * virSocketAddrFormatFull: * @addr: an initialized virSocketAddrPtr * @withService: if true, then service info is appended * @separator: separator between hostname & service. * * Returns a string representation of the given address * Returns NULL on any error * Caller must free the returned string */ char * virSocketAddrFormatFull(virSocketAddrPtr addr, bool withService, const char *separator) { char host[NI_MAXHOST], port[NI_MAXSERV]; char *addrstr; int err; if (addr == NULL) { virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing address")); return NULL; } /* Short-circuit since getnameinfo doesn't work * nicely for UNIX sockets */ if (addr->data.sa.sa_family == AF_UNIX) { if (withService) { if (virAsprintf(&addrstr, "127.0.0.1%s0", separator ? separator : ":") < 0) goto no_memory; } else { if (!(addrstr = strdup("127.0.0.1"))) goto no_memory; } return addrstr; } if ((err = getnameinfo(&addr->data.sa, addr->len, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { virSocketError(VIR_ERR_SYSTEM_ERROR, _("Cannot convert socket address to string: %s"), gai_strerror(err)); return NULL; } if (withService) { if (virAsprintf(&addrstr, "%s%s%s", host, separator, port) == -1) goto no_memory; } else { if (!(addrstr = strdup(host))) goto no_memory; } return addrstr; no_memory: virReportOOMError(); return NULL; }
/** * virSocketParseAddr: * @val: a numeric network address IPv4 or IPv6 * @addr: where to store the return value, optional. * @family: address family to pass down to getaddrinfo * * Mostly a wrapper for getaddrinfo() extracting the address storage * from the numeric string like 1.2.3.4 or 2001:db8:85a3:0:0:8a2e:370:7334 * * Returns the length of the network address or -1 in case of error. */ int virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { int len; struct addrinfo hints; struct addrinfo *res = NULL; int err; if (val == NULL) { virSocketError(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) { virSocketError(VIR_ERR_SYSTEM_ERROR, _("Cannot parse socket address '%s': %s"), val, gai_strerror(err)); return -1; } if (res == NULL) { virSocketError(VIR_ERR_SYSTEM_ERROR, _("No socket addresses found for '%s'"), val); return -1; } len = res->ai_addrlen; if (addr != NULL) { memcpy(&addr->data.stor, res->ai_addr, len); addr->len = res->ai_addrlen; } freeaddrinfo(res); return(len); }