diff options
Diffstat (limited to 'net/net.c')
-rw-r--r-- | net/net.c | 99 |
1 files changed, 49 insertions, 50 deletions
@@ -64,55 +64,42 @@ static QTAILQ_HEAD(, NetClientState) net_clients; /***********************************************************/ /* network device redirectors */ -static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) -{ - const char *p, *p1; - int len; - p = *pp; - p1 = strchr(p, sep); - if (!p1) - return -1; - len = p1 - p; - p1++; - if (buf_size > 0) { - if (len > buf_size - 1) - len = buf_size - 1; - memcpy(buf, p, len); - buf[len] = '\0'; - } - *pp = p1; - return 0; -} - int parse_host_port(struct sockaddr_in *saddr, const char *str, Error **errp) { - char buf[512]; + gchar **substrings; struct hostent *he; - const char *p, *r; - int port; + const char *addr, *p, *r; + int port, ret = 0; - p = str; - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + substrings = g_strsplit(str, ":", 2); + if (!substrings || !substrings[0] || !substrings[1]) { error_setg(errp, "host address '%s' doesn't contain ':' " "separating host from port", str); - return -1; + ret = -1; + goto out; } + + addr = substrings[0]; + p = substrings[1]; + saddr->sin_family = AF_INET; - if (buf[0] == '\0') { + if (addr[0] == '\0') { saddr->sin_addr.s_addr = 0; } else { - if (qemu_isdigit(buf[0])) { - if (!inet_aton(buf, &saddr->sin_addr)) { + if (qemu_isdigit(addr[0])) { + if (!inet_aton(addr, &saddr->sin_addr)) { error_setg(errp, "host address '%s' is not a valid " - "IPv4 address", buf); - return -1; + "IPv4 address", addr); + ret = -1; + goto out; } } else { - he = gethostbyname(buf); + he = gethostbyname(addr); if (he == NULL) { - error_setg(errp, "can't resolve host address '%s'", buf); - return - 1; + error_setg(errp, "can't resolve host address '%s'", addr); + ret = -1; + goto out; } saddr->sin_addr = *(struct in_addr *)he->h_addr; } @@ -120,10 +107,14 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str, port = strtol(p, (char **)&r, 0); if (r == p) { error_setg(errp, "port number '%s' is invalid", p); - return -1; + ret = -1; + goto out; } saddr->sin_port = htons(port); - return 0; + +out: + g_strfreev(substrings); + return ret; } char *qemu_mac_strdup_printf(const uint8_t *macaddr) @@ -1105,6 +1096,7 @@ static void show_netdevs(void) static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) { + gchar **substrings = NULL; void *object = NULL; Error *err = NULL; int ret = -1; @@ -1120,28 +1112,33 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) const char *ip6_net = qemu_opt_get(opts, "ipv6-net"); if (ip6_net) { - char buf[strlen(ip6_net) + 1]; + char *prefix_addr; + unsigned long prefix_len = 64; /* Default 64bit prefix length. */ + + substrings = g_strsplit(ip6_net, "/", 2); + if (!substrings || !substrings[0]) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net", + "a valid IPv6 prefix"); + goto out; + } - if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) { - /* Default 64bit prefix length. */ - qemu_opt_set(opts, "ipv6-prefix", ip6_net, &error_abort); - qemu_opt_set_number(opts, "ipv6-prefixlen", 64, &error_abort); - } else { + prefix_addr = substrings[0]; + + if (substrings[1]) { /* User-specified prefix length. */ - unsigned long len; int err; - qemu_opt_set(opts, "ipv6-prefix", buf, &error_abort); - err = qemu_strtoul(ip6_net, NULL, 10, &len); - + err = qemu_strtoul(substrings[1], NULL, 10, &prefix_len); if (err) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "ipv6-prefix", "a number"); - } else { - qemu_opt_set_number(opts, "ipv6-prefixlen", len, - &error_abort); + "ipv6-prefixlen", "a number"); + goto out; } } + + qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort); + qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len, + &error_abort); qemu_opt_unset(opts, "ipv6-net"); } } @@ -1162,7 +1159,9 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) qapi_free_NetLegacy(object); } +out: error_propagate(errp, err); + g_strfreev(substrings); visit_free(v); return ret; } |