Ejemplo n.º 1
0
bool HHVM_FUNCTION(checkdnsrr, const String& host,
                   const String& type /* = null_string */) {
    int ntype;
    if (!validate_dns_arguments(host, type, ntype)) {
        return false;
    }

    unsigned char ans[MAXPACKET];
    struct __res_state *res;
    res = ResolverInit::s_res.get()->getResolver();
    if (res == NULL) {
        return false;
    }

    int i = res_nsearch(res, host.data(), C_IN, ntype, ans, sizeof(ans));
    res_nclose(res);
    php_dns_free_res(res);
    return (i >= 0);
}
Ejemplo n.º 2
0
bool HHVM_FUNCTION(checkdnsrr, const String& host,
                   const String& type /* = null_string */) {
    IOStatusHelper io("dns_check_record", host.data());
    const char *stype;
    if (type.empty()) {
        stype = "MX";
    } else {
        stype = type.data();
    }
    if (host.empty()) {
        throw_invalid_argument("host: [empty]");
    }

    int ntype;
    if (!strcasecmp("A", stype)) ntype = DNS_T_A;
    else if (!strcasecmp("NS",    stype)) ntype = DNS_T_NS;
    else if (!strcasecmp("MX",    stype)) ntype = DNS_T_MX;
    else if (!strcasecmp("PTR",   stype)) ntype = DNS_T_PTR;
    else if (!strcasecmp("ANY",   stype)) ntype = DNS_T_ANY;
    else if (!strcasecmp("SOA",   stype)) ntype = DNS_T_SOA;
    else if (!strcasecmp("TXT",   stype)) ntype = DNS_T_TXT;
    else if (!strcasecmp("CNAME", stype)) ntype = DNS_T_CNAME;
    else if (!strcasecmp("AAAA",  stype)) ntype = DNS_T_AAAA;
    else if (!strcasecmp("SRV",   stype)) ntype = DNS_T_SRV;
    else if (!strcasecmp("NAPTR", stype)) ntype = DNS_T_NAPTR;
    else if (!strcasecmp("A6",    stype)) ntype = DNS_T_A6;
    else {
        throw_invalid_argument("type: %s", stype);
        return false;
    }

    unsigned char ans[MAXPACKET];
    struct __res_state *res;
    res = ResolverInit::s_res.get()->getResolver();
    if (res == NULL) {
        return false;
    }
    int i = res_nsearch(res, host.data(), C_IN, ntype, ans, sizeof(ans));
    res_nclose(res);
    php_dns_free_res(res);
    return (i >= 0);
}
Ejemplo n.º 3
0
bool HHVM_FUNCTION(getmxrr, const String& hostname,
                   VRefParam mxhostsRef,
                   VRefParam weightsRef /* = null */) {
    IOStatusHelper io("dns_get_mx", hostname.data());
    int count, qdc;
    unsigned short type, weight;
    unsigned char ans[MAXPACKET];
    char buf[MAXHOSTNAMELEN];
    unsigned char *cp, *end;

    Array mxhosts;
    Array weights;
    SCOPE_EXIT {
        mxhostsRef = mxhosts;
        weightsRef = weights;
    };

    /* Go! */
    struct __res_state *res;
    res = ResolverInit::s_res.get()->getResolver();
    if (res == NULL) {
        return false;
    }

    int i = res_nsearch(res, hostname.data(), C_IN, DNS_T_MX,
                        (unsigned char*)&ans, sizeof(ans));
    if (i < 0) {
        res_nclose(res);
        php_dns_free_res(res);
        return false;
    }
    if (i > (int)sizeof(ans)) {
        i = sizeof(ans);
    }
    HEADER *hp = (HEADER *)&ans;
    cp = (unsigned char *)&ans + HFIXEDSZ;
    end = (unsigned char *)&ans +i;
    for (qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) {
        if ((i = dn_skipname(cp, end)) < 0 ) {
            res_nclose(res);
            php_dns_free_res(res);
            return false;
        }
    }
    count = ntohs((unsigned short)hp->ancount);
    while (--count >= 0 && cp < end) {
        if ((i = dn_skipname(cp, end)) < 0 ) {
            res_nclose(res);
            php_dns_free_res(res);
            return false;
        }
        cp += i;
        GETSHORT(type, cp);
        cp += INT16SZ + INT32SZ;
        GETSHORT(i, cp);
        if (type != DNS_T_MX) {
            cp += i;
            continue;
        }
        GETSHORT(weight, cp);
        if ((i = dn_expand(ans, end, cp, buf, sizeof(buf)-1)) < 0) {
            res_nclose(res);
            php_dns_free_res(res);
            return false;
        }
        cp += i;
        mxhosts.append(String(buf, CopyString));
        weights.append(weight);
    }
    res_nclose(res);
    php_dns_free_res(res);
    return true;
}
Ejemplo n.º 4
0
Variant HHVM_FUNCTION(dns_get_record, const String& hostname, int type /*= -1*/,
                      VRefParam authnsRef /* = null */,
                      VRefParam addtlRef /* = null */) {
    IOStatusHelper io("dns_get_record", hostname.data(), type);
    if (type < 0) type = PHP_DNS_ALL;
    if (type & ~PHP_DNS_ALL && type != PHP_DNS_ANY) {
        raise_warning("Type '%d' not supported", type);
        return false;
    }

    unsigned char *cp = NULL, *end = NULL;
    int qd, an, ns = 0, ar = 0;
    querybuf answer;

    /* - We emulate an or'ed type mask by querying type by type.
     *   (Steps 0 - NUMTYPES-1 )
     *   If additional info is wanted we check again with DNS_T_ANY
     *   (step NUMTYPES / NUMTYPES+1 )
     *   store_results is used to skip storing the results retrieved in step
     *   NUMTYPES+1 when results were already fetched.
     * - In case of PHP_DNS_ANY we use the directly fetch DNS_T_ANY.
     *   (step NUMTYPES+1 )
     */
    Array ret;
    bool first_query = true;
    bool store_results = true;
    for (int t = (type == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0);
            t < PHP_DNS_NUM_TYPES + 2 || first_query; t++) {
        first_query = false;
        int type_to_fetch;
        switch (t) {
        case 0:
            type_to_fetch = type & PHP_DNS_A     ? DNS_T_A     : 0;
            break;
        case 1:
            type_to_fetch = type & PHP_DNS_NS    ? DNS_T_NS    : 0;
            break;
        case 2:
            type_to_fetch = type & PHP_DNS_CNAME ? DNS_T_CNAME : 0;
            break;
        case 3:
            type_to_fetch = type & PHP_DNS_SOA   ? DNS_T_SOA   : 0;
            break;
        case 4:
            type_to_fetch = type & PHP_DNS_PTR   ? DNS_T_PTR   : 0;
            break;
        case 5:
            type_to_fetch = type & PHP_DNS_HINFO ? DNS_T_HINFO : 0;
            break;
        case 6:
            type_to_fetch = type & PHP_DNS_MX    ? DNS_T_MX    : 0;
            break;
        case 7:
            type_to_fetch = type & PHP_DNS_TXT   ? DNS_T_TXT   : 0;
            break;
        case 8:
            type_to_fetch = type & PHP_DNS_AAAA  ? DNS_T_AAAA  : 0;
            break;
        case 9:
            type_to_fetch = type & PHP_DNS_SRV   ? DNS_T_SRV   : 0;
            break;
        case 10:
            type_to_fetch = type & PHP_DNS_NAPTR ? DNS_T_NAPTR : 0;
            break;
        case 11:
            type_to_fetch = type & PHP_DNS_A6    ? DNS_T_A6    : 0;
            break;
        case PHP_DNS_NUM_TYPES:
            store_results = false;
            continue;
        default:
        case (PHP_DNS_NUM_TYPES + 1):
            type_to_fetch = DNS_T_ANY;
            break;
        }
        if (!type_to_fetch) continue;

        struct __res_state *res;
        res = ResolverInit::s_res.get()->getResolver();
        if (res == NULL) {
            return false;
        }

        int n = res_nsearch(res, hostname.data(), C_IN, type_to_fetch,
                            answer.qb2, sizeof answer);
        if (n < 0) {
            res_nclose(res);
            php_dns_free_res(res);
            continue;
        }

        HEADER *hp;
        cp = answer.qb2 + HFIXEDSZ;
        end = answer.qb2 + n;
        hp = (HEADER *)&answer;
        qd = ntohs(hp->qdcount);
        an = ntohs(hp->ancount);
        ns = ntohs(hp->nscount);
        ar = ntohs(hp->arcount);

        /* Skip QD entries, they're only used by dn_expand later on */
        while (qd-- > 0) {
            n = dn_skipname(cp, end);
            if (n < 0) {
                raise_warning("Unable to parse DNS data received");
                res_nclose(res);
                php_dns_free_res(res);
                return false;
            }
            cp += n + QFIXEDSZ;
        }

        /* YAY! Our real answers! */
        while (an-- && cp && cp < end) {
            Array retval;
            cp = php_parserr(cp, end, &answer, type_to_fetch, store_results, retval);
            if (!retval.empty() && store_results) {
                ret.append(retval);
            }
        }
        res_nclose(res);
        php_dns_free_res(res);
    }

    Array authns;
    Array addtl;

    /* List of Authoritative Name Servers */
    while (ns-- > 0 && cp && cp < end) {
        Array retval;
        cp = php_parserr(cp, end, &answer, DNS_T_ANY, true, retval);
        if (!retval.empty()) {
            authns.append(retval);
        }
    }

    /* Additional records associated with authoritative name servers */
    while (ar-- > 0 && cp && cp < end) {
        Array retval;
        cp = php_parserr(cp, end, &answer, DNS_T_ANY, true, retval);
        if (!retval.empty()) {
            addtl.append(retval);
        }
    }

    authnsRef = authns;
    addtlRef = addtl;
    return ret;
}