static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,

                          int legacy_format)

{

    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 < 1 || 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) {

        config_error(mon, "could not set up host forwarding rule '%s'\n",

                     redir_str);

    }

    return;



 fail_syntax:

    config_error(mon, "invalid host forwarding rule '%s'\n", redir_str);

}
