InetSocketAddress *inet_parse(const char *str, Error **errp) { InetSocketAddress *addr; const char *optstr, *h; char host[64]; char port[33]; int to; int pos; addr = g_new0(InetSocketAddress, 1); /* parse address */ if (str[0] == ':') { /* no host given */ host[0] = '\0'; if (1 != sscanf(str, ":%32[^,]%n", port, &pos)) { error_setg(errp, "error parsing port in address '%s'", str); goto fail; } } else if (str[0] == '[') { /* IPv6 addr */ if (2 != sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos)) { error_setg(errp, "error parsing IPv6 address '%s'", str); goto fail; } addr->ipv6 = addr->has_ipv6 = true; } else { /* hostname or IPv4 addr */ if (2 != sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos)) { error_setg(errp, "error parsing address '%s'", str); goto fail; } if (host[strspn(host, "0123456789.")] == '\0') { addr->ipv4 = addr->has_ipv4 = true; } } addr->host = g_strdup(host); addr->port = g_strdup(port); /* parse options */ optstr = str + pos; h = strstr(optstr, ",to="); if (h) { h += 4; if (sscanf(h, "%d%n", &to, &pos) != 1 || (h[pos] != '\0' && h[pos] != ',')) { error_setg(errp, "error parsing to= argument"); goto fail; } addr->has_to = true; addr->to = to; } if (strstr(optstr, ",ipv4")) { addr->ipv4 = addr->has_ipv4 = true; } if (strstr(optstr, ",ipv6")) { addr->ipv6 = addr->has_ipv6 = true; } return addr; fail: qapi_free_InetSocketAddress(addr); return NULL; }