⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns_client_util6.c

📁 DNS 的实现代码
💻 C
字号:
/* * DNS Resolver * IPv6 Resolver Utility Routines * * Author: Pavel A. Bolokhov   <Pavel.Bolokhov@oktet.ru> * * External API: *     dns_fmt_ip6_answer() *     dns_fmt_cname6_answer() *     dns_fmt_cache6_answer() *     dns_fmt_ptr6_answer() */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include "messages.h"#include "dns_client.h"#include "dns_client_query.h"#include "dns_client_util6.h"#include "dns_client_resource.h"/* dns_fmt_ip6_answer -- *     Puts the answer with address into message. * * PARAMETERS *     query  - query state structure *     dnsmsg - dns message with results * * RETURNS: *      0 - for success, or *     -1 - for an error condition. */intdns_fmt_ip6_answer(IN QueryState *query, IN DnsMsg *dnsmsg){    struct hostent  *hent;    DnsRRec         *RR;    int              nanswers, i;    MSG_D_DNS_GET_NODEBYNAME(dmsg, query->reply);    DNSC_DEBUG("entry\n");    if ((hent = dns_alloc_struct_hostent()) == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_struct_hostent failed\n");        return -1;    }        if (strlen(query->cname) > 0)    {        if (dns_alloc_aliases(hent, 1) == NULL)        {            dmsg->error = ENOMEM;            return -1;        }        if ((hent->h_aliases[0] = malloc(strlen(query->cname) + 1)) == NULL)        {            dns_freehostent(hent);            dmsg->error = ENOMEM;            return -1;        }        strcpy(hent->h_aliases[0], query->cname);    }    nanswers = find_num_match(query->domain, dnsmsg->m_answers, QT_AAAA) +               find_num_match(query->domain, dnsmsg->m_answers, QT_A6);    if (nanswers == 0)    {        DNSC_TRACE("unexpected format error no addresses for %s\n",                   query->domain);#ifdef DNS_DEBUG        print_dns_message(dnsmsg);#endif        dns_freehostent(hent);        dmsg->error = ETRYAGAIN;        return -1;    }    if (dns_alloc_hostname(hent, query->domain) == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_hostname failed\n");        return -1;    }    hent->h_addr_list = dns_alloc_addrlist(hent, nanswers, AF_INET6);    if (hent->h_addr_list == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_addrlist failed\n");        return -1;    }        hent->h_addrtype = AF_INET6;    hent->h_length = sizeof(struct in6_addr);    RR = find_match_rrecord(query->domain, dnsmsg->m_answers, QT_AAAA);    for (i = 0; i < nanswers && RR != NULL; i++)    {        memcpy(hent->h_addr_list[i], RR->r_data, sizeof(struct in6_addr));        RR = find_match_rrecord(query->domain, RR->r_next, QT_AAAA);    }    RR = find_match_rrecord(query->domain, dnsmsg->m_answers, QT_A6);    for (; i < nanswers && RR != NULL; i++)    {        memcpy(hent->h_addr_list[i], RR->r_data, sizeof(struct in6_addr));        RR = find_match_rrecord(query->domain, RR->r_next, QT_A6);    }    /*     * If we've not filled all the addresses, release the reserved     * by 'dns_alloc_addrlist()' space     */    if (i < nanswers)    {        int k;        for (k = i; k < nanswers; k++)        {            free(hent->h_addr_list[k]);            hent->h_addr_list[k] = NULL;        }    }        dmsg->hent = hent;    dmsg->error = ESUCCESS;    DNSC_DEBUG("exit - success\n");    return 0;} /* dns_fmt_ip6_answer *//* dns_fmt_cname6_answer -- *     This one is a little more complicated than the IP and PTR formatters. *     Here it could be the case that the query already had known it was *     looking for a CNAME which is indicated by a query type of ac_type or *     the query received a DNS response and it told us then which is *     indicated by a query type of aaaa_type;  we handle both cases. *     Then we need to locate the AAAA records for the CNAME.  Note that it *     is unlikely that there would be AAAA records for the CNAME in both *     the answer records and additional records both we handle that situation. *     We get up to the limit indicated by the user. * * PARAMETERS: *     query  - query state structure *     dnsmsg - dns message with results * * RETURNS: *      0 - for success, and *     -1 - indicates an error condition. */intdns_fmt_cname6_answer(IN QueryState *query, IN DnsMsg *dnsmsg){    struct hostent  *hent;    DnsRRec         *RR;    int              cnt;    int              num_answ;    MSG_D_DNS_GET_NODEBYNAME(dmsg, query->reply);    DNSC_DEBUG("entry\n");    if ((hent = dns_alloc_struct_hostent()) == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_struct_hostent failed\n");        return -1;    }    hent->h_addrtype = AF_INET6;    hent->h_length = sizeof(struct in6_addr);    switch(query->qtype)    {        case a6_type:        case aaaa_type:            if ((RR = find_match_rrecord(query->domain, dnsmsg->m_answers,                                         QT_CNAME)) == NULL)            {                DNSC_TRACE("unexpect format error, no CNAME record for %s\n",                           query->domain);    #ifdef DNS_DEBUG                print_dns_message(dnsmsg);    #endif                dmsg->error = ETRYAGAIN;                return -1;            }            if (dns_alloc_aliases(hent, 1) == NULL)            {                dmsg->error = ENOMEM;                return -1;            }            if ((hent->h_aliases[0] = malloc(strlen(query->domain) + 1))                == NULL)            {                dns_freehostent(hent);                dmsg->error = ENOMEM;                return -1;            }            strcpy(hent->h_aliases[0], query->domain);            if (dns_alloc_hostname(hent, RR->r_data) == NULL)            {                dmsg->error = ENOMEM;                return -1;            }            break;        case ac_type:            if (dns_alloc_hostname(hent, query->domain) == NULL)            {                dmsg->error = ENOMEM;                return -1;            }            if (dns_alloc_aliases(hent, 1) == NULL)            {                dmsg->error = ENOMEM;                return -1;            }            if ((hent->h_aliases[0] = malloc(strlen(query->cname) + 1))                == NULL)            {                dns_freehostent(hent);                dmsg->error = ENOMEM;                return -1;            }            strcpy(hent->h_aliases[0], query->cname);            break;        default:            DNSC_TRACE("unrecognized query type: %d\n", query->qtype);            dmsg->error = ETRYAGAIN;            return -1;    }    cnt = 0;    num_answ =        find_num_match(hent->h_name, dnsmsg->m_answers, QT_AAAA) +        find_num_match(hent->h_name, dnsmsg->m_answers, QT_A6) +        find_num_match(hent->h_name, dnsmsg->m_additionals, QT_AAAA) +        find_num_match(hent->h_name, dnsmsg->m_additionals, QT_A6);	    /* Allocate memory for addresses */    if (dns_alloc_addrlist(hent, num_answ, AF_INET6) == NULL)    {        dmsg->error = ENOMEM;        return -1;    }    RR = find_match_rrecord(hent->h_name, dnsmsg->m_answers, QT_AAAA);    while ( RR != NULL && cnt < num_answ ) {        memcpy(hent->h_addr_list[cnt++], RR->r_data,               sizeof(struct in6_addr));        RR = find_match_rrecord(hent->h_name, RR->r_next, QT_AAAA);    }    RR = find_match_rrecord(hent->h_name, dnsmsg->m_answers, QT_A6);    while ( RR != NULL && cnt < num_answ ) {        memcpy(hent->h_addr_list[cnt++], RR->r_data,               sizeof(struct in6_addr));        RR = find_match_rrecord(hent->h_name, RR->r_next, QT_A6);    }    RR = find_match_rrecord(hent->h_name, dnsmsg->m_additionals, QT_AAAA);    while ( RR != NULL && cnt < num_answ ) {        memcpy(hent->h_addr_list[cnt++], RR->r_data,               sizeof(struct in6_addr));        RR = find_match_rrecord(hent->h_name, RR->r_next, QT_AAAA);    }    RR = find_match_rrecord(hent->h_name, dnsmsg->m_additionals, QT_A6);    while ( RR != NULL && cnt < num_answ ) {        memcpy(hent->h_addr_list[cnt++], RR->r_data,               sizeof(struct in6_addr));        RR = find_match_rrecord(hent->h_name, RR->r_next, QT_A6);    }    /*     * If we've not filled all the addresses, release the reserved     * by 'dns_alloc_addrlist()' space     */    if (cnt < num_answ)    {        int k;        for (k = cnt; k < num_answ; k++)        {            free(hent->h_addr_list[k]);            hent->h_addr_list[k] = NULL;        }    }    dmsg->hent = hent;    dmsg->error = ESUCCESS;    DNSC_DEBUG("exit - success\n");    return 0;} /* dns_fmt_cname6_answer *//* dns_fmt_cache6_answer -- *     This routine is called when the cache returned a result and we don't *     know if it is just the addresses or a CNAME.  The results are expected *     to have the the AAAA records for the CNAME if that is there. * * PARAMETERS: *     query  - query state structure *     dnsmsg - dns message with results * * RETURNS: *      0 - for success, or *     -1 - to incidate an error condition. */intdns_fmt_cache6_answer(IN QueryState *query, IN DnsMsg *dnsmsg){    DnsRRec *RR = dnsmsg->m_answers;    char     tmpName[NAMEMAX+1];    DNSC_DEBUG("entry\n");    /*     * Note that all the names coming out of the cache are in all lower     * case.  So we have to convert the domain name in the query to lower     * case so that the search for matching records in the formatting     * routines will work.     */    strcpy(tmpName, query->domain);    lowercase_copy(query->domain, tmpName);    if (RR->r_type == QT_CNAME)    {        query->qtype = aaaa_type;        return dns_fmt_cname6_answer(query, dnsmsg);    }    DNSC_DEBUG("exit - call dns_fmt_ip6_answer\n");    return dns_fmt_ip6_answer(query, dnsmsg);} /* dns_fmt_cache6_answer *//* dns_fmt_ptr6_answer -- *     This routine is called to format the response to a PTR query. *     It should only be called for PTR queries since it makes an *     assumption on the message type. * * PARAMETERS: *     query  - query state structure *     dnsmsg - dns message with results * * RETURNS: *      0 - for success, or *     -1 - to incidate an error condition. */intdns_fmt_ptr6_answer(IN QueryState *query, IN DnsMsg *dnsmsg){    DnsRRec         *RR;    struct hostent  *hent;    struct sockaddr_storage tmp;    MSG_D_DNS_GET_HOSTBYADDR6(dmsg, query->reply);    DNSC_DEBUG("entry\n");    if ((hent = dns_alloc_struct_hostent()) == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_struct_hostent failed\n");        return -1;    }    hent->h_addrtype = AF_INET6;    hent->h_length = sizeof(struct in6_addr);    RR = find_match_rrecord(query->domain, dnsmsg->m_answers, QT_PTR);    if (RR == NULL)    {#ifdef DNS_DEBUG        print_dns_message(dnsmsg);#endif        dmsg->error = ETRYAGAIN;        dns_freehostent(hent);        DNSC_DEBUG("exit - unexpected formating error, no pointer "                   "answer for %s\n", query->domain);        return -1;    }    if (dns_alloc_hostname(hent, RR->r_data) == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_hostname failed\n");        return -1;    }    if (dns_alloc_addrlist(hent, 1, AF_INET6) == NULL)    {        dmsg->error = ENOMEM;        DNSC_DEBUG("exit - dns_alloc_addrlist failed\n");        return -1;    }    /*     * All our macros and functions assume we submit sockaddr_storage     * structure, so we use this even though we know here we need     * struct sockaddr_in6 only.     */    convert_addr_arpa(query->domain, &tmp);    memcpy(hent->h_addr_list[0],           &((struct sockaddr_in6 *)&tmp)->sin6_addr,           sizeof(struct in6_addr));    dmsg->hent = hent;    dmsg->error = ESUCCESS;    DNSC_DEBUG("exit - success\n");    return 0;} /* dns_fmt_ptr6_answer */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -