コード例 #1
0
ファイル: config.c プロジェクト: pickup09/pimd
/**
 * parseBSR - Parse the candidate BSR configured information.
 * @s: String token
 *
 * Syntax:
 * cand_bootstrap_router [address | ifname] [priority <0-255>]
 */
int parseBSR(char *s)
{
    char *w;
    uint32_t local    = INADDR_ANY_N;
    uint32_t priority = PIM_DEFAULT_BSR_PRIORITY;

    cand_bsr_flag = FALSE;
    while (!EQUAL((w = next_word(&s)), "")) {
	if (EQUAL(w, "priority")) {
	    if (EQUAL((w = next_word(&s)), "")) {
		WARN("Missing Cand-BSR priority, defaulting to %u", PIM_DEFAULT_BSR_PRIORITY);
		priority = PIM_DEFAULT_BSR_PRIORITY;
		continue;
	    }

	    if (sscanf(w, "%u", &priority) != 1) {
		WARN("Invalid Cand-BSR priority %s, defaulting to %u", PIM_DEFAULT_BSR_PRIORITY);
		priority = PIM_DEFAULT_BSR_PRIORITY;
		continue;
	    }

	    if (priority > PIM_MAX_CAND_BSR_PRIORITY) {
		WARN("Too high Cand-BSR priority %u, defaulting to %d", priority, PIM_MAX_CAND_BSR_PRIORITY);
		priority = PIM_MAX_CAND_BSR_PRIORITY;
	    }

	    my_bsr_priority = (u_int8)priority;
	    continue;
	}

	/* Cand-BSR interface or address */
	local = ifname2addr(w);
	if (!local)
	    local = inet_parse(w, 4);

	if (!inet_valid_host(local)) {
	    local = max_local_address();
	    WARN("Invalid Cand-BSR address '%s', defaulting to %s", w, inet_fmt(local, s1, sizeof(s1)));
	    continue;
	}

	if (local_address(local) == NO_VIF) {
	    local = max_local_address();
	    WARN("Cand-BSR address '%s' is not local, defaulting to %s", w, inet_fmt(local, s1, sizeof(s1)));
	}
    }

    if (local == INADDR_ANY_N) {
	/* If address not provided, use the max. local */
	local = max_local_address();
    }

    my_bsr_address  = local;
    my_bsr_priority = priority;
    MASKLEN_TO_MASK(RP_DEFAULT_IPV4_HASHMASKLEN, my_bsr_hash_mask);
    cand_bsr_flag   = TRUE;
    logit(LOG_INFO, 0, "Local Cand-BSR address %s, priority %u", inet_fmt(local, s1, sizeof(s1)), priority);

    return TRUE;
}
コード例 #2
0
ファイル: qemu-sockets.c プロジェクト: 01org/qemu-lite
int inet_listen(const char *str, char *ostr, int olen,
                int socktype, int port_offset, Error **errp)
{
    char *optstr;
    int sock = -1;
    InetSocketAddress *addr;

    addr = inet_parse(str, errp);
    if (addr != NULL) {
        sock = inet_listen_saddr(addr, port_offset, true, errp);
        if (sock != -1 && ostr) {
            optstr = strchr(str, ',');
            if (addr->ipv6) {
                snprintf(ostr, olen, "[%s]:%s%s",
                         addr->host,
                         addr->port,
                         optstr ? optstr : "");
            } else {
                snprintf(ostr, olen, "%s:%s%s",
                         addr->host,
                         addr->port,
                         optstr ? optstr : "");
            }
        }
        qapi_free_InetSocketAddress(addr);
    }
    return sock;
}
コード例 #3
0
ファイル: qemu-sockets.c プロジェクト: kashifqazi/qemu
int inet_listen(const char *str, char *ostr, int olen,
                int socktype, int port_offset, Error **errp)
{
    QemuOpts *opts;
    char *optstr;
    int sock = -1;
    InetSocketAddress *addr;

    addr = inet_parse(str, errp);
    if (addr != NULL) {
        opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
        inet_addr_to_opts(opts, addr);
        qapi_free_InetSocketAddress(addr);
        sock = inet_listen_opts(opts, port_offset, errp);
        if (sock != -1 && ostr) {
            optstr = strchr(str, ',');
            if (qemu_opt_get_bool(opts, "ipv6", 0)) {
                snprintf(ostr, olen, "[%s]:%s%s",
                         qemu_opt_get(opts, "host"),
                         qemu_opt_get(opts, "port"),
                         optstr ? optstr : "");
            } else {
                snprintf(ostr, olen, "%s:%s%s",
                         qemu_opt_get(opts, "host"),
                         qemu_opt_get(opts, "port"),
                         optstr ? optstr : "");
            }
        }
        qemu_opts_del(opts);
    }
    return sock;
}
コード例 #4
0
ファイル: qemu-sockets.c プロジェクト: 16aug/nvmeqemu
int inet_listen(const char *str, char *ostr, int olen,
                int socktype, int port_offset)
{
    QemuOpts *opts;
    char *optstr;
    int sock = -1;

    opts = qemu_opts_create(&dummy_opts, NULL, 0);
    if (inet_parse(opts, str) == 0) {
        sock = inet_listen_opts(opts, port_offset);
        if (sock != -1 && ostr) {
            optstr = strchr(str, ',');
            if (qemu_opt_get_bool(opts, "ipv6", 0)) {
                snprintf(ostr, olen, "[%s]:%s%s",
                         qemu_opt_get(opts, "host"),
                         qemu_opt_get(opts, "port"),
                         optstr ? optstr : "");
            } else {
                snprintf(ostr, olen, "%s:%s%s",
                         qemu_opt_get(opts, "host"),
                         qemu_opt_get(opts, "port"),
                         optstr ? optstr : "");
            }
        }
    }
    qemu_opts_del(opts);
    return sock;
}
コード例 #5
0
ファイル: inet_listen.c プロジェクト: TonyChengTW/Rmail
int     inet_listen(const char *addr, int backlog, int block_mode)
{
    struct sockaddr_in sin;
    int     sock;
    int     t = 1;
    char   *buf;
    char   *host;
    char   *port;

    /*
     * Translate address information to internal form.
     */
    buf = inet_parse(addr, &host, &port);
    memset((char *) &sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = find_inet_port(port, "tcp");
    sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
    myfree(buf);

    /*
     * Create a listener socket.
     */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	msg_fatal("socket: %m");
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
	msg_fatal("setsockopt: %m");
    if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
	msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
	       "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
    non_blocking(sock, block_mode);
    if (listen(sock, backlog) < 0)
	msg_fatal("listen: %m");
    return (sock);
}
コード例 #6
0
ファイル: config.c プロジェクト: F0rth/pimd
/*
 * function name: parseBSR
 * input: char *s
 * output: int
 * operation: parse the candidate BSR configured information.
 *	General form:
 *	'cand_bootstrap_router <local-addr> [priority <number>]'.
 */
int parseBSR(char *s)
{
    char *w;
    u_int32 local    = INADDR_ANY_N;
    u_int32 priority = PIM_DEFAULT_BSR_PRIORITY;

    cand_bsr_flag = FALSE;
    while (!EQUAL((w = next_word(&s)), "")) {
        if (EQUAL(w, "priority")) {
            if (EQUAL((w = next_word(&s)), "")) {
                logit(LOG_WARNING, 0,
                      "Missing priority; set to default %u (0 is lowest)\n",
                      PIM_DEFAULT_BSR_PRIORITY);
                priority = PIM_DEFAULT_BSR_PRIORITY;
                continue;
            }
            if (sscanf(w, "%u", &priority) != 1) {
                logit(LOG_WARNING, 0,
                      "invalid priority %s; set to default %u (0 is lowest)",
                      PIM_DEFAULT_BSR_PRIORITY);
                priority = PIM_DEFAULT_BSR_PRIORITY;
                continue;
            }
            if (priority > (my_bsr_priority = ~0))
                priority = my_bsr_priority;
            my_bsr_priority = (u_int8)priority;
            continue;
        }

        /* BSR address */
        local = inet_parse(w, 4);
        if (!inet_valid_host(local)) {
            local = max_local_address();
            logit(LOG_WARNING, 0, "Invalid BSR address provided '%s' in %s. Will use the largest enabled local address.",
                  w, configfilename);
            continue;
        }
        if (local_address(local) == NO_VIF) {
            local = max_local_address();
            logit(LOG_WARNING, 0,
                  "Cand-BSR address is not local '%s' in %s. Will use the largest enabled local address.",
                  w, configfilename);
        }
    }		/* while not empty */

    if (local == INADDR_ANY_N)
        /* If address not provided, use the max. local */
        local = max_local_address();
    my_bsr_address  = local;
    my_bsr_priority = priority;
    MASKLEN_TO_MASK(RP_DEFAULT_IPV4_HASHMASKLEN, my_bsr_hash_mask);
    cand_bsr_flag   = TRUE;
    logit(LOG_INFO, 0, "Local Cand-BSR address is %s", inet_fmt(local, s1, sizeof(s1)));
    logit(LOG_INFO, 0, "Local Cand-BSR priority is %u", priority);

    return TRUE;
}
コード例 #7
0
ファイル: inet_connect.c プロジェクト: TonyChengTW/Rmail
int     inet_connect(const char *addr, int block_mode, int timeout)
{
    char   *buf;
    char   *host;
    char   *port;
    struct sockaddr_in sin;
    int     sock;

    /*
     * Translate address information to internal form. No host defaults to
     * the local host.
     */
    buf = inet_parse(addr, &host, &port);
    if (*host == 0)
	host = "localhost";
    memset((char *) &sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = find_inet_addr(host);
    sin.sin_port = find_inet_port(port, "tcp");
    myfree(buf);

    /*
     * Create a client socket.
     */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	msg_fatal("socket: %m");

    /*
     * Timed connect.
     */
    if (timeout > 0) {
	non_blocking(sock, NON_BLOCKING);
	if (timed_connect(sock, (struct sockaddr *) & sin, sizeof(sin), timeout) < 0) {
	    close(sock);
	    return (-1);
	}
	if (block_mode != NON_BLOCKING)
	    non_blocking(sock, block_mode);
	return (sock);
    }

    /*
     * Maybe block until connected.
     */
    else {
	non_blocking(sock, block_mode);
	if (sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
	    && errno != EINPROGRESS) {
	    close(sock);
	    return (-1);
	}
	return (sock);
    }
}
コード例 #8
0
ファイル: qemu-sockets.c プロジェクト: 16aug/nvmeqemu
int inet_connect(const char *str, int socktype)
{
    QemuOpts *opts;
    int sock = -1;

    opts = qemu_opts_create(&dummy_opts, NULL, 0);
    if (inet_parse(opts, str) == 0)
        sock = inet_connect_opts(opts);
    qemu_opts_del(opts);
    return sock;
}
コード例 #9
0
ファイル: qemu-sockets.c プロジェクト: Marshalzxy/qemu
/**
 * Create a blocking socket and connect it to an address.
 *
 * @str: address string
 * @errp: set in case of an error
 *
 * Returns -1 in case of error, file descriptor on success
 **/
int inet_connect(const char *str, Error **errp)
{
    int sock = -1;
    InetSocketAddress *addr = g_new(InetSocketAddress, 1);

    if (!inet_parse(addr, str, errp)) {
        sock = inet_connect_saddr(addr, errp);
    }
    qapi_free_InetSocketAddress(addr);
    return sock;
}
コード例 #10
0
ファイル: qemu-sockets.c プロジェクト: m000/panda
/**
 * Create a blocking socket and connect it to an address.
 *
 * @str: address string
 * @errp: set in case of an error
 *
 * Returns -1 in case of error, file descriptor on success
 **/
int inet_connect(const char *str, Error **errp)
{
    int sock = -1;
    InetSocketAddress *addr;

    addr = inet_parse(str, errp);
    if (addr != NULL) {
        sock = inet_connect_saddr(addr, errp, NULL, NULL);
        qapi_free_InetSocketAddress(addr);
    }
    return sock;
}
コード例 #11
0
ファイル: config.c プロジェクト: F0rth/pimd
/*
 * function name: parse_group_prefix
 * input: char *s
 * output: int
 * operation: parse group_prefix configured information.
 *	General form: 'group_prefix <group-addr> [masklen <masklen>]'.
 */
int parse_group_prefix(char *s)
{
    char *w;
    u_int32 group_addr;
    u_int32  masklen;

    w = next_word(&s);
    if (EQUAL(w, "")) {
        logit(LOG_WARNING, 0,
              "Configuration error for 'group_prefix' in %s: no group_addr. Ignoring...", configfilename);
        return FALSE;
    }
    group_addr = inet_parse(w, 4);
    if (!IN_MULTICAST(ntohl(group_addr))) {
        logit(LOG_WARNING, 0,
              "Config error for 'group_prefix' in %s: %s is not a mcast addr. Ignoring...", configfilename, inet_fmt(group_addr, s1, sizeof(s1)));
        return FALSE;
    }

    /* Was if (!(~(*cand_rp_adv_message.prefix_cnt_ptr))) which Arm GCC 4.4.2 dislikes:
     *  --> "config.c:693: warning: promoted ~unsigned is always non-zero"
     * The prefix_cnt_ptr is a u_int8 so it seems this check was to prevent overruns.
     * I've changed the check to see if we've already read 255 entries, if so the cnt
     * is maximized and we need to tell the user. --Joachim Nilsson 2010-01-16 */
    if (*cand_rp_adv_message.prefix_cnt_ptr == 255) {
        logit(LOG_WARNING, 0,
              "Too many group_prefix configured. Truncating...");
        return FALSE;
    }

    if (EQUAL((w = next_word(&s)), "masklen")) {
        w = next_word(&s);
        if (sscanf(w, "%u", &masklen) == 1) {
            if (masklen > (sizeof(group_addr)*8))
                masklen = (sizeof(group_addr)*8);
            else if (masklen < 4)
                masklen = 4;
        }
        else
            masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
    }
    else
        masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;

    PUT_EGADDR(group_addr, (u_int8)masklen, 0,
               cand_rp_adv_message.insert_data_ptr);
    (*cand_rp_adv_message.prefix_cnt_ptr)++;

    logit(LOG_INFO, 0, "Adding prefix %s/%d", inet_fmt(group_addr, s1, sizeof(s1)), masklen);

    return TRUE;
}
コード例 #12
0
ファイル: qemu-sockets.c プロジェクト: RafaelRMachado/qemu
/**
 * Create a blocking socket and connect it to an address.
 *
 * @str: address string
 * @errp: set in case of an error
 *
 * Returns -1 in case of error, file descriptor on success
 **/
int inet_connect(const char *str, Error **errp)
{
    QemuOpts *opts;
    int sock = -1;

    opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
    if (inet_parse(opts, str) == 0) {
        sock = inet_connect_opts(opts, errp, NULL, NULL);
    } else {
        error_set(errp, QERR_SOCKET_CREATE_FAILED);
    }
    qemu_opts_del(opts);
    return sock;
}
コード例 #13
0
ファイル: socket.c プロジェクト: Icenowy/qemu
static SocketAddress *tcp_build_address(const char *host_port, Error **errp)
{
    InetSocketAddress *iaddr = inet_parse(host_port, errp);
    SocketAddress *saddr;

    if (!iaddr) {
        return NULL;
    }

    saddr = g_new0(SocketAddress, 1);
    saddr->type = SOCKET_ADDRESS_KIND_INET;
    saddr->u.inet.data = iaddr;

    return saddr;
}
コード例 #14
0
ファイル: qemu-sockets.c プロジェクト: kashifqazi/qemu
/**
 * Create a blocking socket and connect it to an address.
 *
 * @str: address string
 * @errp: set in case of an error
 *
 * Returns -1 in case of error, file descriptor on success
 **/
int inet_connect(const char *str, Error **errp)
{
    QemuOpts *opts;
    int sock = -1;
    InetSocketAddress *addr;

    addr = inet_parse(str, errp);
    if (addr != NULL) {
        opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
        inet_addr_to_opts(opts, addr);
        qapi_free_InetSocketAddress(addr);
        sock = inet_connect_opts(opts, errp, NULL, NULL);
        qemu_opts_del(opts);
    }
    return sock;
}
コード例 #15
0
ファイル: qemu-sockets.c プロジェクト: 01org/qemu-lite
/**
 * Create a non-blocking socket and connect it to an address.
 * Calls the callback function with fd in case of success or -1 in case of
 * error.
 *
 * @str: address string
 * @callback: callback function that is called when connect completes,
 *            cannot be NULL.
 * @opaque: opaque for callback function
 * @errp: set in case of an error
 *
 * Returns: -1 on immediate error, file descriptor on success.
 **/
int inet_nonblocking_connect(const char *str,
                             NonBlockingConnectHandler *callback,
                             void *opaque, Error **errp)
{
    int sock = -1;
    InetSocketAddress *addr;

    g_assert(callback != NULL);

    addr = inet_parse(str, errp);
    if (addr != NULL) {
        sock = inet_connect_saddr(addr, errp, callback, opaque);
        qapi_free_InetSocketAddress(addr);
    }
    return sock;
}
コード例 #16
0
ファイル: config.c プロジェクト: pickup09/pimd
/**
 * parse_group_prefix - Parse group_prefix configured information.
 * @s: String token

 * Syntax:
 * group_prefix <group-addr>[/<masklen>]
 *              <group-addr> [masklen <masklen>]
 *
 * Returns:
 * %TRUE if the parsing was successful, o.w. %FALSE
 */
int parse_group_prefix(char *s)
{
    char *w;
    uint32_t group_addr;
    uint32_t  masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;

    w = next_word(&s);
    if (EQUAL(w, "")) {
	WARN("Missing group_prefix address");
	return FALSE;
    }

    parse_prefix_len (w, &masklen);

    group_addr = inet_parse(w, 4);
    if (!IN_MULTICAST(ntohl(group_addr))) {
	WARN("Group address '%s' is not a valid multicast address", inet_fmt(group_addr, s1, sizeof(s1)));
	return FALSE;
    }

    /* Was if (!(~(*cand_rp_adv_message.prefix_cnt_ptr))) which Arm GCC 4.4.2 dislikes:
     *  --> "config.c:693: warning: promoted ~unsigned is always non-zero"
     * The prefix_cnt_ptr is a u_int8 so it seems this check was to prevent overruns.
     * I've changed the check to see if we've already read 255 entries, if so the cnt
     * is maximized and we need to tell the user. --Joachim Nilsson 2010-01-16 */
    if (*cand_rp_adv_message.prefix_cnt_ptr == 255) {
	WARN("Too many multicast groups configured!");
	return FALSE;
    }

    if (EQUAL((w = next_word(&s)), "masklen")) {
	w = next_word(&s);
	if (!sscanf(w, "%u", &masklen))
	    masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
    }

    validate_prefix_len(&masklen);

    PUT_EGADDR(group_addr, (u_int8)masklen, 0, cand_rp_adv_message.insert_data_ptr);
    (*cand_rp_adv_message.prefix_cnt_ptr)++;

    logit(LOG_INFO, 0, "Adding Cand-RP group prefix %s/%d", inet_fmt(group_addr, s1, sizeof(s1)), masklen);

    return TRUE;
}
コード例 #17
0
ファイル: qemu-sockets.c プロジェクト: RafaelRMachado/qemu
/**
 * Create a non-blocking socket and connect it to an address.
 * Calls the callback function with fd in case of success or -1 in case of
 * error.
 *
 * @str: address string
 * @callback: callback function that is called when connect completes,
 *            cannot be NULL.
 * @opaque: opaque for callback function
 * @errp: set in case of an error
 *
 * Returns: -1 on immediate error, file descriptor on success.
 **/
int inet_nonblocking_connect(const char *str,
                             NonBlockingConnectHandler *callback,
                             void *opaque, Error **errp)
{
    QemuOpts *opts;
    int sock = -1;

    g_assert(callback != NULL);

    opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
    if (inet_parse(opts, str) == 0) {
        sock = inet_connect_opts(opts, errp, callback, opaque);
    } else {
        error_set(errp, QERR_SOCKET_CREATE_FAILED);
    }
    qemu_opts_del(opts);
    return sock;
}
コード例 #18
0
ファイル: qemu-sockets.c プロジェクト: m000/panda
SocketAddress *socket_parse(const char *str, Error **errp)
{
    SocketAddress *addr;

    addr = g_new0(SocketAddress, 1);
    if (strstart(str, "unix:", NULL)) {
        if (str[5] == '\0') {
            error_setg(errp, "invalid Unix socket address");
            goto fail;
        } else {
            addr->type = SOCKET_ADDRESS_KIND_UNIX;
            addr->u.q_unix.data = g_new(UnixSocketAddress, 1);
            addr->u.q_unix.data->path = g_strdup(str + 5);
        }
    } else if (strstart(str, "fd:", NULL)) {
        if (str[3] == '\0') {
            error_setg(errp, "invalid file descriptor address");
            goto fail;
        } else {
            addr->type = SOCKET_ADDRESS_KIND_FD;
            addr->u.fd.data = g_new(String, 1);
            addr->u.fd.data->str = g_strdup(str + 3);
        }
    } else if (strstart(str, "vsock:", NULL)) {
        addr->type = SOCKET_ADDRESS_KIND_VSOCK;
        addr->u.vsock.data = vsock_parse(str + strlen("vsock:"), errp);
        if (addr->u.vsock.data == NULL) {
            goto fail;
        }
    } else {
        addr->type = SOCKET_ADDRESS_KIND_INET;
        addr->u.inet.data = inet_parse(str, errp);
        if (addr->u.inet.data == NULL) {
            goto fail;
        }
    }
    return addr;

fail:
    qapi_free_SocketAddress(addr);
    return NULL;
}
コード例 #19
0
ファイル: qemu-sockets.c プロジェクト: kashifqazi/qemu
/**
 * Create a non-blocking socket and connect it to an address.
 * Calls the callback function with fd in case of success or -1 in case of
 * error.
 *
 * @str: address string
 * @callback: callback function that is called when connect completes,
 *            cannot be NULL.
 * @opaque: opaque for callback function
 * @errp: set in case of an error
 *
 * Returns: -1 on immediate error, file descriptor on success.
 **/
int inet_nonblocking_connect(const char *str,
                             NonBlockingConnectHandler *callback,
                             void *opaque, Error **errp)
{
    QemuOpts *opts;
    int sock = -1;
    InetSocketAddress *addr;

    g_assert(callback != NULL);

    addr = inet_parse(str, errp);
    if (addr != NULL) {
        opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
        inet_addr_to_opts(opts, addr);
        qapi_free_InetSocketAddress(addr);
        sock = inet_connect_opts(opts, errp, callback, opaque);
        qemu_opts_del(opts);
    }
    return sock;
}
コード例 #20
0
ファイル: qemu-sockets.c プロジェクト: Marshalzxy/qemu
SocketAddress *socket_parse(const char *str, Error **errp)
{
    SocketAddress *addr;

    addr = g_new0(SocketAddress, 1);
    if (strstart(str, "unix:", NULL)) {
        if (str[5] == '\0') {
            error_setg(errp, "invalid Unix socket address");
            goto fail;
        } else {
            addr->type = SOCKET_ADDRESS_TYPE_UNIX;
            addr->u.q_unix.path = g_strdup(str + 5);
        }
    } else if (strstart(str, "fd:", NULL)) {
        if (str[3] == '\0') {
            error_setg(errp, "invalid file descriptor address");
            goto fail;
        } else {
            addr->type = SOCKET_ADDRESS_TYPE_FD;
            addr->u.fd.str = g_strdup(str + 3);
        }
    } else if (strstart(str, "vsock:", NULL)) {
        addr->type = SOCKET_ADDRESS_TYPE_VSOCK;
        if (vsock_parse(&addr->u.vsock, str + strlen("vsock:"), errp)) {
            goto fail;
        }
    } else {
        addr->type = SOCKET_ADDRESS_TYPE_INET;
        if (inet_parse(&addr->u.inet, str, errp)) {
            goto fail;
        }
    }
    return addr;

fail:
    qapi_free_SocketAddress(addr);
    return NULL;
}
コード例 #21
0
ファイル: qemu-sockets.c プロジェクト: evanchueng/qemu
SocketAddress *socket_parse(const char *str, Error **errp)
{
    SocketAddress *addr = NULL;

    addr = g_new(SocketAddress, 1);
    if (strstart(str, "unix:", NULL)) {
        if (str[5] == '\0') {
            error_setg(errp, "invalid Unix socket address\n");
            goto fail;
        } else {
            addr->kind = SOCKET_ADDRESS_KIND_UNIX;
            addr->q_unix = g_new(UnixSocketAddress, 1);
            addr->q_unix->path = g_strdup(str + 5);
        }
    } else if (strstart(str, "fd:", NULL)) {
        if (str[3] == '\0') {
            error_setg(errp, "invalid file descriptor address\n");
            goto fail;
        } else {
            addr->kind = SOCKET_ADDRESS_KIND_FD;
            addr->fd = g_new(String, 1);
            addr->fd->str = g_strdup(str + 3);
        }
    } else {
        addr->kind = SOCKET_ADDRESS_KIND_INET;
        addr->inet = g_new(InetSocketAddress, 1);
        addr->inet = inet_parse(str, errp);
        if (addr->inet == NULL) {
            goto fail;
        }
    }
    return addr;

fail:
    qapi_free_SocketAddress(addr);
    return NULL;
}
コード例 #22
0
ファイル: nbd.c プロジェクト: Isaac-Lozano/qemu
static void nbd_parse_filename(const char *filename, QDict *options,
                               Error **errp)
{
    char *file;
    char *export_name;
    const char *host_spec;
    const char *unixpath;

    if (qdict_haskey(options, "host")
        || qdict_haskey(options, "port")
        || qdict_haskey(options, "path"))
    {
        error_setg(errp, "host/port/path and a file name may not be specified "
                         "at the same time");
        return;
    }

    if (strstr(filename, "://")) {
        int ret = nbd_parse_uri(filename, options);
        if (ret < 0) {
            error_setg(errp, "No valid URL specified");
        }
        return;
    }

    file = g_strdup(filename);

    export_name = strstr(file, EN_OPTSTR);
    if (export_name) {
        if (export_name[strlen(EN_OPTSTR)] == 0) {
            goto out;
        }
        export_name[0] = 0; /* truncate 'file' */
        export_name += strlen(EN_OPTSTR);

        qdict_put(options, "export", qstring_from_str(export_name));
    }

    /* extract the host_spec - fail if it's not nbd:... */
    if (!strstart(file, "nbd:", &host_spec)) {
        error_setg(errp, "File name string for NBD must start with 'nbd:'");
        goto out;
    }

    if (!*host_spec) {
        goto out;
    }

    /* are we a UNIX or TCP socket? */
    if (strstart(host_spec, "unix:", &unixpath)) {
        qdict_put(options, "path", qstring_from_str(unixpath));
    } else {
        InetSocketAddress *addr = NULL;

        addr = inet_parse(host_spec, errp);
        if (!addr) {
            goto out;
        }

        qdict_put(options, "host", qstring_from_str(addr->host));
        qdict_put(options, "port", qstring_from_str(addr->port));
        qapi_free_InetSocketAddress(addr);
    }

out:
    g_free(file);
}
コード例 #23
0
ファイル: config.c プロジェクト: F0rth/pimd
/*
 * function name: parse_candidateRP
 * input: char *s
 * output: int (TRUE if the parsing was successful, o.w. FALSE)
 * operation: parses the candidate RP information.
 *	The general form is:
 *      'cand_rp <local-addr> [priority <number>] [time <number>]'.
 */
int parse_candidateRP(char *s)
{
    u_int time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
    u_int priority = PIM_DEFAULT_CAND_RP_PRIORITY;
    char *w;
    u_int32 local = INADDR_ANY_N;

    cand_rp_flag = FALSE;
    my_cand_rp_adv_period = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
    while (!EQUAL((w = next_word(&s)), "")) {
        if (EQUAL(w, "priority")) {
            if (EQUAL((w = next_word(&s)), "")) {
                logit(LOG_WARNING, 0,
                      "Missing priority; set to default %u (0 is highest)",
                      PIM_DEFAULT_CAND_RP_PRIORITY);
                priority = PIM_DEFAULT_CAND_RP_PRIORITY;
                continue;
            }
            if (sscanf(w, "%u", &priority) != 1) {
                logit(LOG_WARNING, 0,
                      "invalid priority %s; set to default %u (0 is highest)",
                      PIM_DEFAULT_CAND_RP_PRIORITY);
                priority = PIM_DEFAULT_CAND_RP_PRIORITY;
            }
            continue;
        }
        if (EQUAL(w, "time")) {
            if (EQUAL((w = next_word(&s)), "")) {
                logit(LOG_WARNING, 0,
                      "Missing cand_rp_adv_period value; set to default %u",
                      PIM_DEFAULT_CAND_RP_ADV_PERIOD);
                time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
                continue;
            }
            if (sscanf(w, "%u", &time) != 1) {
                logit(LOG_WARNING, 0,
                      "Invalid cand_rp_adv_period value; set to default %u",
                      PIM_DEFAULT_CAND_RP_ADV_PERIOD);
                time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
                continue;
            }
            if (time > (my_cand_rp_adv_period = ~0))
                time = my_cand_rp_adv_period;
            /* TODO: XXX: cannot be shorter than 10 seconds (not in the spec)*/
            if (time < 10)
                time = 10;
#if 0
            if (time > PIM_DEFAULT_CAND_RP_ADV_PERIOD)
                time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
#endif /* 0 */
            my_cand_rp_adv_period = time;
            continue;
        }
        /* Cand-RP address */
        local = inet_parse(w, 4);
        if (!inet_valid_host(local)) {
            local = max_local_address();
            logit(LOG_WARNING, 0,
                  "Invalid Cand-RP address provided '%s' in %s. Will use the largest enabled local address.",
                  w, configfilename);
        } else if (local_address(local) == NO_VIF) {
            local = max_local_address();
            logit(LOG_WARNING, 0, "Cand-RP address is not local '%s' in %s. Will use the largest enabled local address.",
                  w, configfilename);
        }
    }           /* while not empty */

    if (local == INADDR_ANY_N) {
        /* If address not provided, use the max. local */
        local = max_local_address();
    }

    my_cand_rp_address = local;
    my_cand_rp_priority = priority;
    my_cand_rp_adv_period = time;
    cand_rp_flag = TRUE;

    logit(LOG_INFO, 0, "Local Cand-RP address is %s", inet_fmt(local, s1, sizeof(s1)));
    logit(LOG_INFO, 0, "Local Cand-RP priority is %u", priority);
    logit(LOG_INFO, 0, "Local Cand-RP advertisement period is %u sec.", time);

    return TRUE;
}
コード例 #24
0
ファイル: config.c プロジェクト: F0rth/pimd
/**
 * parse_rp_address - Parse rp_address config option.
 * @s: String token.
 *
 * This is an extension to the original pimd to add pimd.conf support for static
 * Rendez-Vous Point addresses.
 *
 * The function has been extended by [email protected], of Lintrack, to allow specifying
 * multicast group addresses as well.
 *
 * Format:
 * rp_address <rp-address>
 *
 * Returns:
 * When parsing @s is successful this function returns %TRUE, otherwise %FALSE.
 */
int parse_rp_address(char *s)
{
    char *w;
    u_int32 local = 0xffffff;
    u_int32 group_addr;
    u_int32 masklen;
    struct rp_hold * rph;

    w = next_word(&s);
    if (EQUAL(w, "")) {
        logit(LOG_WARNING, 0, "'rp_address' in %s: no <rp-addr> - ignoring", configfilename);
        return FALSE;
    }

    local = inet_parse(w, 4);
    if (local == 0xffffff) {
        logit(LOG_WARNING, 0, "'rp_address' in %s: invalid <rp-addr> provided: '%s'", configfilename, w);
        return FALSE;
    }

    w = next_word(&s);
    if (!EQUAL(w, "")) {
        group_addr = inet_parse(w, 4);
        if (!IN_MULTICAST(ntohl(group_addr))) {
            logit(LOG_WARNING, 0, "'rp_address' in %s: %s is not a multicast addr", configfilename, inet_fmt(group_addr, s1, sizeof(s1)));
            return FALSE;
        }

        if (EQUAL((w = next_word(&s)), "masklen")) {
            w = next_word(&s);
            if (sscanf(w, "%u", &masklen) == 1) {
                if (masklen > (sizeof(group_addr) * 8))
                    masklen = (sizeof(group_addr) * 8);
                else if (masklen < 4)
                    masklen = 4;
            }
            else
                masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
        }
        else
            masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
    }
    else {
        group_addr = htonl(224 << 24);
        masklen = 4;
    }

    /* save */
    rph = malloc(sizeof(*rph));
    rph->address = local;
    rph->group = group_addr;
    VAL_TO_MASK(rph->mask, masklen);

    /* attach at the beginning */
    rph->next = g_rp_hold;
    g_rp_hold = rph;

    logit(LOG_INFO, 0, "Added static RP: %s, group %s/%d", inet_fmt(local, s1, sizeof(s1)), inet_fmt(group_addr, s2, sizeof(s2)), masklen);

    return TRUE;
}
コード例 #25
0
ファイル: config.c プロジェクト: pickup09/pimd
/**
 * parse_phyint - Parse physical interface configuration, if any.
 * @s: String token
 *
 * Syntax:
 * phyint <local-addr | ifname> [disable|enable]
 *                              [threshold <t>] [preference <p>] [metric <m>]
 *                              [altnet <net-addr>/<masklen>]
 *                              [altnet <net-addr> masklen <masklen>]
 *                              [scoped <net-addr>/<masklen>]
 *                              [scoped <net-addr> masklen <masklen>]
 *
 * Returns:
 * %TRUE if the parsing was successful, o.w. %FALSE
 */
static int parse_phyint(char *s)
{
    char *w, c;
    uint32_t local, altnet_addr, scoped_addr;
    vifi_t vifi;
    struct uvif *v;
    u_int n, altnet_masklen = 0, scoped_masklen = 0;
    struct phaddr *ph;
    struct vif_acl *v_acl;

    if (EQUAL((w = next_word(&s)), "")) {
	WARN("Missing phyint address");
	return FALSE;
    }

    local = ifname2addr(w);
    if (!local) {
	local = inet_parse(w, 4);
	if (!inet_valid_host(local)) {
	    WARN("Invalid phyint address '%s'", w);
	    return FALSE;
	}
    }

    for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
	if (vifi == numvifs) {
	    WARN("phyint %s is not a valid interface", inet_fmt(local, s1, sizeof(s1)));
	    return FALSE;
	}

	if (local != v->uv_lcl_addr)
	    continue;

	while (!EQUAL((w = next_word(&s)), "")) {
	    if (EQUAL(w, "disable")) {
		v->uv_flags |= VIFF_DISABLED;
		continue;
	    }

	    if (EQUAL(w, "enable")) {
		v->uv_flags &= ~VIFF_DISABLED;
		continue;
	    }

	    if (EQUAL(w, "altnet")) {
		if (EQUAL((w = next_word(&s)), "")) {
		    WARN("Missing ALTNET for phyint %s", inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		parse_prefix_len (w, &altnet_masklen);

		altnet_addr = ifname2addr(w);
		if (!altnet_addr) {
		    altnet_addr = inet_parse(w, 4);
		    if (!inet_valid_host(altnet_addr)) {
			WARN("Invalid altnet address '%s'", w);
			return FALSE;
		    }
		}

		if (EQUAL((w = next_word(&s)), "masklen")) {
		    if (EQUAL((w = next_word(&s)), "")) {
			WARN("Missing ALTNET masklen for phyint %s", inet_fmt(local, s1, sizeof (s1)));
			continue;
		    }

		    if (!sscanf(w, "%u", &altnet_masklen)) {
			WARN("Invalid altnet masklen '%s' for phyint %s", w, inet_fmt(local, s1, sizeof(s1)));
			continue;
		    }
		}

		ph = (struct phaddr *)calloc(1, sizeof(struct phaddr));
		if (!ph)
		    return FALSE;

		if (altnet_masklen) {
		    VAL_TO_MASK(ph->pa_subnetmask, altnet_masklen);
		} else {
		    ph->pa_subnetmask = v->uv_subnetmask;
		}

		ph->pa_subnet = altnet_addr & ph->pa_subnetmask;
		ph->pa_subnetbcast = ph->pa_subnet | ~ph->pa_subnetmask;
		if (altnet_addr & ~ph->pa_subnetmask)
		    WARN("Extra subnet %s/%d has host bits set", inet_fmt(altnet_addr, s1, sizeof(s1)), altnet_masklen);

		ph->pa_next = v->uv_addrs;
		v->uv_addrs = ph;
		logit(LOG_DEBUG, 0, "ALTNET: %s/%d", inet_fmt(altnet_addr, s1, sizeof(s1)), altnet_masklen);
	    } /* altnet */

	    /* scoped mcast groups/masklen */
	    if (EQUAL(w, "scoped")) {
		if (EQUAL((w = next_word(&s)), "")) {
		    WARN("Missing SCOPED for phyint %s", inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		parse_prefix_len (w, &scoped_masklen);

		scoped_addr = ifname2addr(w);
		if (!scoped_addr) {
		    scoped_addr = inet_parse(w, 4);
		    if (!IN_MULTICAST(ntohl(scoped_addr))) {
			WARN("Invalid scoped address '%s'", w);
			return FALSE;
		    }
		}

		if (EQUAL((w = next_word(&s)), "masklen")) {
		    if (EQUAL((w = next_word(&s)), "")) {
			WARN("Missing SCOPED masklen for phyint %s", inet_fmt(local, s1, sizeof(s1)));
			continue;
		    }
		    if (sscanf(w, "%u", &scoped_masklen) != 1) {
			WARN("Invalid scoped masklen '%s' for phyint %s", w, inet_fmt(local, s1, sizeof(s1)));
			continue;
		    }
		}

		v_acl = (struct vif_acl *)calloc(1, sizeof(struct vif_acl));
		if (!v_acl)
		    return FALSE;

		VAL_TO_MASK(v_acl->acl_mask, scoped_masklen);
		v_acl->acl_addr = scoped_addr & v_acl->acl_mask;
		if (scoped_addr & ~v_acl->acl_mask)
		    WARN("Boundary spec %s/%d has host bits set", inet_fmt(scoped_addr, s1, sizeof(s1)),scoped_masklen);

		v_acl->acl_next = v->uv_acl;
		v->uv_acl = v_acl;
		logit(LOG_DEBUG, 0, "SCOPED %s/%x", inet_fmt(v_acl->acl_addr, s1, sizeof(s1)), v_acl->acl_mask);
	    } /* scoped */

	    if (EQUAL(w, "threshold")) {
		if (EQUAL((w = next_word(&s)), "")) {
		    WARN("Missing threshold for phyint %s", inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		if (sscanf(w, "%u%c", &n, &c) != 1 || n < 1 || n > 255 ) {
		    WARN("Invalid threshold '%s' for phyint %s", w, inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		v->uv_threshold = n;
		continue;
	    } /* threshold */

	    if (EQUAL(w, "preference")) {
		if (EQUAL((w = next_word(&s)), "")) {
		    WARN("Missing preference for phyint %s", inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		if (sscanf(w, "%u%c", &n, &c) != 1 || n < 1 || n > 255 ) {
		    WARN("Invalid preference '%s' for phyint %s", w, inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		IF_DEBUG(DEBUG_ASSERT) {
		    logit(LOG_DEBUG, 0, "Config setting default local preference on %s to %d", inet_fmt(local, s1, sizeof(s1)), n);
		}

		v->uv_local_pref = n;
		continue;
	    }
	    if (EQUAL(w, "metric")) {
		if (EQUAL((w = next_word(&s)), "")) {
		    WARN("Missing metric for phyint %s", inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		if (sscanf(w, "%u%c", &n, &c) != 1 || n < 1 || n > 1024 ) {
		    WARN("Invalid metric '%s' for phyint %s", w, inet_fmt(local, s1, sizeof(s1)));
		    continue;
		}

		IF_DEBUG(DEBUG_ASSERT) {
		    logit(LOG_DEBUG, 0, "Setting default local metric on %s to %d", inet_fmt(local, s1, sizeof(s1)), n);
		}

		v->uv_local_metric = n;
		continue;
	    }
	} /* if not empty */

	break;
    }

    return TRUE;
}
コード例 #26
0
ファイル: qemu-sockets.c プロジェクト: AsherBond/qemu-kvm-mq
int inet_connect_opts(QemuOpts *opts, Error **errp)
{
    struct addrinfo ai,*res,*e;
    const char *addr;
    const char *port;
    char uaddr[INET6_ADDRSTRLEN+1];
    char uport[33];
    int sock,rc;
    bool block;

    memset(&ai,0, sizeof(ai));
    ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
    ai.ai_family = PF_UNSPEC;
    ai.ai_socktype = SOCK_STREAM;

    addr = qemu_opt_get(opts, "host");
    port = qemu_opt_get(opts, "port");
    block = qemu_opt_get_bool(opts, "block", 0);
    if (addr == NULL || port == NULL) {
        fprintf(stderr, "inet_connect: host and/or port not specified\n");
        error_set(errp, QERR_SOCKET_CREATE_FAILED);
        return -1;
    }

    if (qemu_opt_get_bool(opts, "ipv4", 0))
        ai.ai_family = PF_INET;
    if (qemu_opt_get_bool(opts, "ipv6", 0))
        ai.ai_family = PF_INET6;

    /* lookup */
    if (0 != (rc = getaddrinfo(addr, port, &ai, &res))) {
        fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
                gai_strerror(rc));
        error_set(errp, QERR_SOCKET_CREATE_FAILED);
	return -1;
    }

    for (e = res; e != NULL; e = e->ai_next) {
        if (getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
                            uaddr,INET6_ADDRSTRLEN,uport,32,
                            NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
            fprintf(stderr,"%s: getnameinfo: oops\n", __FUNCTION__);
            continue;
        }
        sock = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
        if (sock < 0) {
            fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
            inet_strfamily(e->ai_family), strerror(errno));
            continue;
        }
        setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
        if (!block) {
            socket_set_nonblock(sock);
        }
        /* connect to peer */
        do {
            rc = 0;
            if (connect(sock, e->ai_addr, e->ai_addrlen) < 0) {
                rc = -socket_error();
            }
        } while (rc == -EINTR);

  #ifdef _WIN32
        if (!block && (rc == -EINPROGRESS || rc == -EWOULDBLOCK
                       || rc == -WSAEALREADY)) {
  #else
        if (!block && (rc == -EINPROGRESS)) {
  #endif
            error_set(errp, QERR_SOCKET_CONNECT_IN_PROGRESS);
        } else if (rc < 0) {
            if (NULL == e->ai_next)
                fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__,
                        inet_strfamily(e->ai_family),
                        e->ai_canonname, uaddr, uport, strerror(errno));
            closesocket(sock);
            sock = -1;
            continue;
        }
        freeaddrinfo(res);
        return sock;
    }
    error_set(errp, QERR_SOCKET_CONNECT_FAILED);
    freeaddrinfo(res);
    return -1;
}

int inet_dgram_opts(QemuOpts *opts)
{
    struct addrinfo ai, *peer = NULL, *local = NULL;
    const char *addr;
    const char *port;
    char uaddr[INET6_ADDRSTRLEN+1];
    char uport[33];
    int sock = -1, rc;

    /* lookup peer addr */
    memset(&ai,0, sizeof(ai));
    ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
    ai.ai_family = PF_UNSPEC;
    ai.ai_socktype = SOCK_DGRAM;

    addr = qemu_opt_get(opts, "host");
    port = qemu_opt_get(opts, "port");
    if (addr == NULL || strlen(addr) == 0) {
        addr = "localhost";
    }
    if (port == NULL || strlen(port) == 0) {
        fprintf(stderr, "inet_dgram: port not specified\n");
        return -1;
    }

    if (qemu_opt_get_bool(opts, "ipv4", 0))
        ai.ai_family = PF_INET;
    if (qemu_opt_get_bool(opts, "ipv6", 0))
        ai.ai_family = PF_INET6;

    if (0 != (rc = getaddrinfo(addr, port, &ai, &peer))) {
        fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
                gai_strerror(rc));
	return -1;
    }

    /* lookup local addr */
    memset(&ai,0, sizeof(ai));
    ai.ai_flags = AI_PASSIVE;
    ai.ai_family = peer->ai_family;
    ai.ai_socktype = SOCK_DGRAM;

    addr = qemu_opt_get(opts, "localaddr");
    port = qemu_opt_get(opts, "localport");
    if (addr == NULL || strlen(addr) == 0) {
        addr = NULL;
    }
    if (!port || strlen(port) == 0)
        port = "0";

    if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
        fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
                gai_strerror(rc));
        return -1;
    }

    /* create socket */
    sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
    if (sock < 0) {
        fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
                inet_strfamily(peer->ai_family), strerror(errno));
        goto err;
    }
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));

    /* bind socket */
    if (getnameinfo((struct sockaddr*)local->ai_addr,local->ai_addrlen,
                    uaddr,INET6_ADDRSTRLEN,uport,32,
                    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
        fprintf(stderr, "%s: getnameinfo: oops\n", __FUNCTION__);
        goto err;
    }
    if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
        fprintf(stderr,"%s: bind(%s,%s,%d): OK\n", __FUNCTION__,
                inet_strfamily(local->ai_family), uaddr, inet_getport(local));
        goto err;
    }

    /* connect to peer */
    if (getnameinfo((struct sockaddr*)peer->ai_addr, peer->ai_addrlen,
                    uaddr, INET6_ADDRSTRLEN, uport, 32,
                    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
        fprintf(stderr, "%s: getnameinfo: oops\n", __FUNCTION__);
        goto err;
    }
    if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
        fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__,
                inet_strfamily(peer->ai_family),
                peer->ai_canonname, uaddr, uport, strerror(errno));
        goto err;
    }

    freeaddrinfo(local);
    freeaddrinfo(peer);
    return sock;

err:
    if (-1 != sock)
        closesocket(sock);
    if (local)
        freeaddrinfo(local);
    if (peer)
        freeaddrinfo(peer);
    return -1;
}

/* compatibility wrapper */
static int inet_parse(QemuOpts *opts, const char *str)
{
    const char *optstr, *h;
    char addr[64];
    char port[33];
    int pos;

    /* parse address */
    if (str[0] == ':') {
        /* no host given */
        addr[0] = '\0';
        if (1 != sscanf(str,":%32[^,]%n",port,&pos)) {
            fprintf(stderr, "%s: portonly parse error (%s)\n",
                    __FUNCTION__, str);
            return -1;
        }
    } else if (str[0] == '[') {
        /* IPv6 addr */
        if (2 != sscanf(str,"[%64[^]]]:%32[^,]%n",addr,port,&pos)) {
            fprintf(stderr, "%s: ipv6 parse error (%s)\n",
                    __FUNCTION__, str);
            return -1;
        }
        qemu_opt_set(opts, "ipv6", "on");
    } else if (qemu_isdigit(str[0])) {
        /* IPv4 addr */
        if (2 != sscanf(str,"%64[0-9.]:%32[^,]%n",addr,port,&pos)) {
            fprintf(stderr, "%s: ipv4 parse error (%s)\n",
                    __FUNCTION__, str);
            return -1;
        }
        qemu_opt_set(opts, "ipv4", "on");
    } else {
        /* hostname */
        if (2 != sscanf(str,"%64[^:]:%32[^,]%n",addr,port,&pos)) {
            fprintf(stderr, "%s: hostname parse error (%s)\n",
                    __FUNCTION__, str);
            return -1;
        }
    }
    qemu_opt_set(opts, "host", addr);
    qemu_opt_set(opts, "port", port);

    /* parse options */
    optstr = str + pos;
    h = strstr(optstr, ",to=");
    if (h)
        qemu_opt_set(opts, "to", h+4);
    if (strstr(optstr, ",ipv4"))
        qemu_opt_set(opts, "ipv4", "on");
    if (strstr(optstr, ",ipv6"))
        qemu_opt_set(opts, "ipv6", "on");
    return 0;
}

int inet_listen(const char *str, char *ostr, int olen,
                int socktype, int port_offset, Error **errp)
{
    QemuOpts *opts;
    char *optstr;
    int sock = -1;

    opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
    if (inet_parse(opts, str) == 0) {
        sock = inet_listen_opts(opts, port_offset, errp);
        if (sock != -1 && ostr) {
            optstr = strchr(str, ',');
            if (qemu_opt_get_bool(opts, "ipv6", 0)) {
                snprintf(ostr, olen, "[%s]:%s%s",
                         qemu_opt_get(opts, "host"),
                         qemu_opt_get(opts, "port"),
                         optstr ? optstr : "");
            } else {
                snprintf(ostr, olen, "%s:%s%s",
                         qemu_opt_get(opts, "host"),
                         qemu_opt_get(opts, "port"),
                         optstr ? optstr : "");
            }
        }
    } else {
        error_set(errp, QERR_SOCKET_CREATE_FAILED);
    }
    qemu_opts_del(opts);
    return sock;
}
コード例 #27
0
ファイル: config.c プロジェクト: pickup09/pimd
/**
 * parse_rp_address - Parse rp_address config option.
 * @s: String token.
 *
 * This is an extension to the original pimd to add pimd.conf support for static
 * Rendez-Vous Point addresses.
 *
 * The function has been extended by [email protected], of Lintrack, to allow specifying
 * multicast group addresses as well.
 *
 * Syntax:
 * rp_address <ADDRESS> [<GROUP>[</LENGTH> masklen <LENGTH>]
 *
 * Returns:
 * When parsing @s is successful this function returns %TRUE, otherwise %FALSE.
 */
int parse_rp_address(char *s)
{
    char *w;
    uint32_t local = 0xffffff;
    uint32_t group_addr = htonl(INADDR_UNSPEC_GROUP);
    uint32_t masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
    u_int dummy;
    struct rp_hold *rph;

    /* next is RP addr */
    w = next_word(&s);
    if (EQUAL(w, "")) {
	logit(LOG_WARNING, 0, "Missing rp_address argument");
	return FALSE;
    }

    local = inet_parse(w, 4);
    if (local == 0xffffff) {
	WARN("Invalid rp_address %s", w);
	return FALSE;
    }

    /* next is group addr if exist */
    w = next_word(&s);
    if (!EQUAL(w, "")) {
	parse_prefix_len (w, &masklen);

	group_addr = inet_parse(w, 4);
	if (!IN_MULTICAST(ntohl(group_addr))) {
	    WARN("%s is not a valid multicast address", inet_fmt(group_addr, s1, sizeof(s1)));
	    return FALSE;
	}

	/* next is prefix or priority if exist */
	while (!EQUAL((w = next_word(&s)), "")) {
	    if (EQUAL(w, "masklen")) {
		w = next_word(&s);
		if (!sscanf(w, "%u", &masklen)) {
		    WARN("Invalid masklen %s. Defaulting to %d)", w, PIM_GROUP_PREFIX_DEFAULT_MASKLEN);
		    masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
		}
	    }

	    /* Unused, but keeping for backwards compatibility for people who
	     * may still have this option in their pimd.conf
	     * The priority of a static RP is hardcoded to always be 1, see Juniper's
	     * configuration or similar sources for reference. */
	    if (EQUAL(w, "priority")) {
		w = next_word(&s);
		sscanf(w, "%u", &dummy);
		WARN("The priority of static RP's is, as of pimd 2.2.0, always 1.");
	    }
	}
    } else {
	group_addr = htonl(INADDR_UNSPEC_GROUP);
	masklen = PIM_GROUP_PREFIX_MIN_MASKLEN;
    }

    validate_prefix_len(&masklen);

    rph = calloc(1, sizeof(*rph));
    if (!rph) {
	logit(LOG_WARNING, 0, "Out of memory when parsing rp-address %s",
	      inet_fmt(local, s1, sizeof(s1)));
	return FALSE;
    }

    rph->address = local;
    rph->group = group_addr;
    VAL_TO_MASK(rph->mask, masklen);

    /* attach at the beginning */
    rph->next = g_rp_hold;
    g_rp_hold = rph;

    logit(LOG_INFO, 0, "Local static RP: %s, group %s/%d",
	  inet_fmt(local, s1, sizeof(s1)), inet_fmt(group_addr, s2, sizeof(s2)), masklen);

    return TRUE;
}
コード例 #28
0
ファイル: config.c プロジェクト: pickup09/pimd
/**
 * parse_candidateRP - Parse candidate Rendez-Vous Point information.
 * @s: String token
 *
 * Syntax:
 * cand_rp [address | ifname] [priority <0-255>] [time <10-16383>]
 *
 * Returns:
 * %TRUE if the parsing was successful, o.w. %FALSE
 */
int parse_candidateRP(char *s)
{
    u_int time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
    u_int priority = PIM_DEFAULT_CAND_RP_PRIORITY;
    char *w;
    uint32_t local = INADDR_ANY_N;

    cand_rp_flag = FALSE;
    my_cand_rp_adv_period = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
    while (!EQUAL((w = next_word(&s)), "")) {
	if (EQUAL(w, "priority")) {
	    if (EQUAL((w = next_word(&s)), "")) {
		WARN("Missing priority, defaulting to %u", w, PIM_DEFAULT_CAND_RP_PRIORITY);
		priority = PIM_DEFAULT_CAND_RP_PRIORITY;
		continue;
	    }

	    if (sscanf(w, "%u", &priority) != 1) {
		WARN("Invalid priority %s, defaulting to %u", w, PIM_DEFAULT_CAND_RP_PRIORITY);
		priority = PIM_DEFAULT_CAND_RP_PRIORITY;
	    }

	    if (priority > PIM_MAX_CAND_RP_PRIORITY) {
		WARN("Too high Cand-RP priority %u, defaulting to %d", priority, PIM_MAX_CAND_RP_PRIORITY);
		priority = PIM_MAX_CAND_RP_PRIORITY;
	    }

	    continue;
	}

	if (EQUAL(w, "time")) {
	    if (EQUAL((w = next_word(&s)), "")) {
		WARN("Missing Cand-RP announce interval, defaulting to %u", PIM_DEFAULT_CAND_RP_ADV_PERIOD);
		time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
		continue;
	    }

	    if (sscanf(w, "%u", &time) != 1) {
		WARN("Invalid Cand-RP announce interval, defaulting to %u", PIM_DEFAULT_CAND_RP_ADV_PERIOD);
		time = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
		continue;
	    }

	    if (time < PIM_MIN_CAND_RP_ADV_PERIOD)
		time = PIM_MIN_CAND_RP_ADV_PERIOD;

	    if (time > PIM_MAX_CAND_RP_ADV_PERIOD)
		time = PIM_MAX_CAND_RP_ADV_PERIOD;

	    my_cand_rp_adv_period = time;
	    continue;
	}

	/* Cand-RP interface or address */
	local = ifname2addr(w);
	if (!local)
	    local = inet_parse(w, 4);

	if (!inet_valid_host(local)) {
	    local = max_local_address();
	    WARN("Invalid Cand-RP address '%s', defaulting to %s", w, inet_fmt(local, s1, sizeof(s1)));
	} else if (local_address(local) == NO_VIF) {
	    local = max_local_address();
	    WARN("Cand-RP address '%s' is not local, defaulting to %s", w, inet_fmt(local, s1, sizeof(s1)));
	}
    }

    if (local == INADDR_ANY_N) {
	/* If address not provided, use the max. local */
	local = max_local_address();
    }

    my_cand_rp_address = local;
    my_cand_rp_priority = priority;
    my_cand_rp_adv_period = time;
    cand_rp_flag = TRUE;

    logit(LOG_INFO, 0, "Local Cand-RP address %s, priority %u, interval %u sec",
	  inet_fmt(local, s1, sizeof(s1)), priority, time);

    return TRUE;
}
コード例 #29
0
ファイル: config.c プロジェクト: michfine/pimd
/**
 * parse_rp_address - Parse rp_address config option.
 * @s: String token.
 *
 * This is an extension to the original pimd to add pimd.conf support for static
 * Rendez-Vous Point addresses.
 *
 * The function has been extended by [email protected], of Lintrack, to allow specifying
 * multicast group addresses as well.
 *
 * Syntax:
 * rp_address <rp-address> [<group-addr>[/masklen>]          [priority <number>]]
 *                         [<group-addr> [masklen <masklen>] [priority <number>]]
 *
 * Returns:
 * When parsing @s is successful this function returns %TRUE, otherwise %FALSE.
 */
int parse_rp_address(char *s)
{
    char *w;
    uint32_t local = 0xffffff;
    uint32_t group_addr = htonl(INADDR_UNSPEC_GROUP);
    uint32_t masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
    u_int priority = PIM_DEFAULT_CAND_RP_PRIORITY;
    struct rp_hold *rph;

    /* next is RP addr */
    w = next_word(&s);
    if (EQUAL(w, "")) {
	logit(LOG_WARNING, 0, "Missing rp_address argument");
	return FALSE;
    }

    local = inet_parse(w, 4);
    if (local == 0xffffff) {
	WARN("Invalid rp_address %s", w);
	return FALSE;
    }

    /* next is group addr if exist */
    w = next_word(&s);
    if (!EQUAL(w, "")) {
	parse_prefix_len (w, &masklen);

	group_addr = inet_parse(w, 4);
	if (!IN_MULTICAST(ntohl(group_addr))) {
	    WARN("%s is not a valid multicast address", inet_fmt(group_addr, s1, sizeof(s1)));
	    return FALSE;
	}

	/* next is prefix or priority if exist */
	while (!EQUAL((w = next_word(&s)), "")) {
	    if (EQUAL(w, "masklen")) {
		w = next_word(&s);
		if (!sscanf(w, "%u", &masklen)) {
		    WARN("Invalid masklen %s. Defaulting to %d)", w, PIM_GROUP_PREFIX_DEFAULT_MASKLEN);
		    masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
		}
	    }

	    if (EQUAL(w, "priority")) {
		w = next_word(&s);
		if (sscanf(w, "%u", &priority) == 1) {
		    if (priority > PIM_MAX_CAND_RP_PRIORITY) {
			WARN("Too large priority %s. Defaulting to %d", w, PIM_MAX_CAND_RP_PRIORITY);
			priority = PIM_MAX_CAND_RP_PRIORITY;
		    }
		} else {
		    WARN("Invalid priority %s. Defaulting to %d", w, PIM_DEFAULT_CAND_RP_PRIORITY);
		    priority = PIM_DEFAULT_CAND_RP_PRIORITY;
		}
	    }
	}
    } else {
	group_addr = htonl(INADDR_UNSPEC_GROUP);
	masklen = PIM_GROUP_PREFIX_MIN_MASKLEN;
	priority = 1;
    }

    validate_prefix_len (&masklen);

    rph = calloc(1, sizeof(*rph));
    if (!rph) {
	logit(LOG_WARNING, 0, "Ran out of memory in parse_rp_address()");
	return FALSE;
    }

    rph->address = local;
    rph->group = group_addr;
    VAL_TO_MASK(rph->mask, masklen);
    rph->priority = priority;

    /* attach at the beginning */
    rph->next = g_rp_hold;
    g_rp_hold = rph;

    logit(LOG_INFO, 0, "Added static RP: %s, group %s/%d, priority %d",
	  inet_fmt(local, s1, sizeof(s1)), inet_fmt(group_addr, s2, sizeof(s2)), masklen, priority);

    return TRUE;
}