Пример #1
0
static int
testGetHostByName(const void *opaque)
{
    const struct testNSSData *data = opaque;
    const bool existent = data->hostname && data->ipAddr && data->ipAddr[0];
    int ret = -1;
    struct hostent resolved;
    char buf[BUF_SIZE] = { 0 };
    char **addrList;
    int rv, tmp_errno = 0, tmp_herrno = 0;
    size_t i = 0, j = 0;

    memset(&resolved, 0, sizeof(resolved));

    rv = NSS_NAME(gethostbyname2)(data->hostname,
                                  data->af,
                                  &resolved,
                                  buf, sizeof(buf),
                                  &tmp_errno,
                                  &tmp_herrno);

    if (rv == NSS_STATUS_TRYAGAIN ||
        rv == NSS_STATUS_UNAVAIL ||
        rv == NSS_STATUS_RETURN) {
        /* Resolving failed in unexpected fashion. */
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "Resolving of %s failed due to internal error",
                       data->hostname);
        goto cleanup;
    } else if (rv == NSS_STATUS_NOTFOUND) {
        /* Resolving failed. Should it? */
        if (!existent)
            ret = 0;
        else
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "Resolving of %s failed",
                           data->hostname);
        goto cleanup;
    }

    /* Resolving succeeded. Should it? */
    if (!existent) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "Resolving of %s succeeded but was expected to fail",
                       data->hostname);
        goto cleanup;
    }

    /* Now lets see if resolved address match our expectations. */

    if (!resolved.h_name) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       "resolved.h_name empty");
        goto cleanup;
    }

    if (data->af != AF_UNSPEC &&
        resolved.h_addrtype != data->af) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "Expected AF_INET (%d) got %d",
                       data->af, resolved.h_addrtype);
        goto cleanup;
    }

    if ((resolved.h_addrtype == AF_INET && resolved.h_length != 4) ||
        (resolved.h_addrtype == AF_INET6 && resolved.h_length != 16)) {
        /* IPv4 addresses are encoded into 4 bytes */
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "Expected %d bytes long address, got %d",
                       resolved.h_addrtype == AF_INET ? 4 : 16,
                       resolved.h_length);
        goto cleanup;
    }

    if (!resolved.h_addr_list) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       "resolved.h_addr_list empty");
        goto cleanup;
    }

    addrList = resolved.h_addr_list;
    while (*addrList) {
        virSocketAddr sa;
        char *ipAddr;
        void *address = *addrList;

        memset(&sa, 0, sizeof(sa));

        if (resolved.h_addrtype == AF_INET) {
            virSocketAddrSetIPv4AddrNetOrder(&sa, *((uint32_t *) address));
        } else {
            virSocketAddrSetIPv6AddrNetOrder(&sa, address);
        }

        if (!(ipAddr = virSocketAddrFormat(&sa))) {
            /* error reported by helper */
            goto cleanup;
        }

        for (j = 0; data->ipAddr[j]; j++) {
            if (STREQ(data->ipAddr[j], ipAddr))
                break;
        }

        if (!data->ipAddr[j]) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "Unexpected address %s", ipAddr);
            VIR_FREE(ipAddr);
            goto cleanup;
        }
        VIR_FREE(ipAddr);

        addrList++;
        i++;
    }

    for (j = 0; data->ipAddr[j]; j++)
        ;

    if (i != j) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "Expected %zu addresses, got %zu", j, i);
        goto cleanup;
    }

    ret = 0;
 cleanup:
    return ret;
}
Пример #2
0
/*
 * virSocketAddrSetIPv4Addr:
 * @addr: the location to store the result
 * @val: the 32bit integer in host byte order representing the IPv4 address
 *
 * Set the IPv4 address given an integer in host order. This function does not
 * touch any previously set port.
 */
void
virSocketAddrSetIPv4Addr(virSocketAddrPtr addr, uint32_t val)
{
    virSocketAddrSetIPv4AddrNetOrder(addr, htonl(val));
}