static int slirp_hostfwd(SlirpState *s, const char *redir_str,

                         int legacy_format, Error **errp)

{

    struct in_addr host_addr = { .s_addr = INADDR_ANY };

    struct in_addr guest_addr = { .s_addr = 0 };

    int host_port, guest_port;

    const char *p;

    char buf[256];

    int is_udp;

    char *end;



    p = redir_str;

    if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

        goto fail_syntax;

    }

    if (!strcmp(buf, "tcp") || buf[0] == '\0') {

        is_udp = 0;

    } else if (!strcmp(buf, "udp")) {

        is_udp = 1;

    } else {

        goto fail_syntax;

    }



    if (!legacy_format) {

        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

            goto fail_syntax;

        }

        if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {

            goto fail_syntax;

        }

    }



    if (get_str_sep(buf, sizeof(buf), &p, legacy_format ? ':' : '-') < 0) {

        goto fail_syntax;

    }

    host_port = strtol(buf, &end, 0);

    if (*end != '\0' || host_port < 0 || host_port > 65535) {

        goto fail_syntax;

    }



    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

        goto fail_syntax;

    }

    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {

        goto fail_syntax;

    }



    guest_port = strtol(p, &end, 0);

    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {

        goto fail_syntax;

    }



    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,

                          guest_port) < 0) {

        error_setg(errp, "Could not set up host forwarding rule '%s'",

                   redir_str);

        return -1;

    }

    return 0;



 fail_syntax:

    error_setg(errp, "Invalid host forwarding rule '%s'", redir_str);

    return -1;

}
