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

📄 dns_client_util.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}   /* end fmt_ip_answer() *//* * fmt_cname_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 a_type;  we handle * both cases.  then we need to locate the A records for the CNAME.  note that it * is unlikely that there would be A 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. * * return:  0 for success, and *         -1 indicates an error condition. */intfmt_cname_answer(QueryState *query, DnsMsg *dnsmsg){    struct dns_hostent  *hptr;    DnsRRec             *RR;    int                 cnt;    MSG_D_DNS_GET_ADDRBYNAME(dmsg, query->reply);    DNSC_DEBUG("entry\n");    hptr = dmsg->hptr;    switch(query->qtype) {    case a_type:        if ((RR = find_match_rrecord(query->domain, dnsmsg->m_answers, QT_CNAME)) == NULL) {	    dprintf("%C: unexpect format error, no CNAME record for %s\n", query->domain);#ifdef DNS_DEBUG	    print_dns_message(dnsmsg);#endif	    dmsg->error = ETRYAGAIN;	    return -1;	}        strcpy(hptr->h_alias, query->domain);	strcpy(hptr->h_name, RR->r_data);	break;    case ac_type:        strcpy(hptr->h_name, query->domain);	strcpy(hptr->h_alias, query->cname);	break;    default:        dprintf("%C: unrecognized query type: %d\n", query->qtype);	dmsg->error = ETRYAGAIN;        return -1;    }    cnt = 0;    if ( find_num_match(hptr->h_name, dnsmsg->m_answers, QT_A) > 0 ) {	RR = find_match_rrecord(hptr->h_name, dnsmsg->m_answers, QT_A);	while ( RR != NULL && cnt < hptr->h_numaddrs ) {	    hptr->h_addr_list[cnt++] = *(U32 *)RR->r_data;	    RR = find_match_rrecord(hptr->h_name, RR->r_next, QT_A);	}    }    if ( find_num_match(hptr->h_name, dnsmsg->m_additionals, QT_A) > 0 ) {	RR = find_match_rrecord(hptr->h_name, dnsmsg->m_additionals, QT_A);	while ( RR != NULL && cnt < hptr->h_numaddrs ) {	    hptr->h_addr_list[cnt++] = *(U32 *)RR->r_data;	    RR = find_match_rrecord(hptr->h_name, RR->r_next, QT_A);	}    }    hptr->h_numaddrs = cnt;    dmsg->error = ESUCCESS;    return 0;}   /* end fmt_cname_answer() *//* * fmt_cache_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 * A records for the CNAME if that is there.  also note that the cache puts the * A records for the CNAME in the additional section.  this routine looks at the * first record of the answer section and if its a CNAME sets the query type so * that fmt_cname_answer() will handle things correctly. otherwise fmt_ip_answer() * is used. * * return:  0 for success, or *         -1 to incidate an error condition. */intfmt_cache_answer(QueryState *query, DnsMsg *dnsmsg){    DnsRRec  *RR = dnsmsg->m_answers;    char     tmpname[NAMEMAX+1];    /*     * 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 = a_type;	return fmt_cname_answer(query, dnsmsg);    }    return fmt_ip_answer(query, dnsmsg);}   /* end fmt_cache_answer() *//* * print_dns_error() * * this routine will print a message describing the error indicated by the * value given by error. */voidprint_dns_error(int error){    switch(error) {    case EHOSTNOTFOUND:        printf("Specified host is unknown.\n");	break;    case ENOADDRESS:        printf("Name is valid but does not have an IP address.\n");	break;    case ENORECOVERY:        printf("Non-recoverable name server error occurred.\n");	break;    case ETRYAGAIN:        printf("Temporary error occurred - try again later.\n");	break;    case ENOMEM:        printf("Error attempting to allocate memory.\n");	break;    case ENONSADDRESS:        printf("No name server addresses provided, configuration error.\n");	break;    case ENOSEARCHLIST:        printf("No search list provided (when using relative host name).\n");	break;    }}   /* end print_dns_error() *//* * dns_validate_hostname() * * this routine is used to verify a hostname entered by a user is at least * reasonable.  that is, we check that the name doesn't start with a '.', * (it can end in a dot).  it has no white space, (no spaces or tabs).  we * also check that the characters are alpha numeric.  we check that the name * isn't over the max name length and we check that individual labels are * not over their max either.  (see RFC 1034 section 3.5) * * return:  0 for okay, and *         -1 to indicate an error. */intdns_validate_hostname(const char *name){    char   dname[NAMEMAX+1];    char   *dup, *tok;    int    len;    if ( name == NULL )    /* make sure there is a name */        return -1;    len = strlen(name);    if ( len > NAMEMAX || len == 0 )        return -1;    /* first character not allowed to be a dot and must be a character     * ending character must be alphanumeric.     */    if ( !isalpha(*name) )        return -1;    if ( name[strlen(name) - 1] != '.' && !isalnum(name[strlen(name) - 1]) )        return -1;    strcpy(dname, name);    dup = dname;    /* check that no white space and that all characters are dots or     * at least alpha numeric.  internal characters can be a hyphen.     */    while ( *dup != '\0' ) {        if ( !isalnum(*dup) && *dup != '.' && *dup != '-' )            return -1;        dup++;    }    /*     * alright, everything is okay.  if there are individual labels,     * for exampe www.hostname.com the we need to verify they are not     * over the max label size.     */    dup = dname;    while ((tok = strchr(dup, '.')) != NULL) {        *tok++ = '\0';        len = strlen(dup);        if ( len > LABELMAX || len == 0 )            return -1;        /* labels must start with a letter and end with an alphanumer value */        if ( !isalpha(*dup) || !isalnum(dup[len - 1]) )            return -1;        dup = tok;    }    return 0;}   /* end dns_validate_hostname() *//* * fmt_XX_answer() * * this routine formats the RRS in the user supplied buffer. * * return:  None */voidfmt_XX_answer(QueryState *query, DnsRRec *answers){    DnsRRec             *RR;    U32                 orig_len, copy_len;    U8                  *ptr;    MSG_D_DNS_GET_RR(dmsg, query->reply);    DNSC_DEBUG("entry\n");    ptr = dmsg->rrptr;    RR = answers;    orig_len = *(dmsg->len);    copy_len = 0;    while ( (RR != NULL) && ((copy_len+RR->r_datalen+sizeof(RR->r_datalen)) <= orig_len) )    {		memcpy(ptr, (U8 *)(&(RR->r_datalen)), sizeof(U16));        ptr += sizeof(U16);        memcpy(ptr, RR->r_data, RR->r_datalen);        ptr +=  RR->r_datalen;        copy_len += (RR->r_datalen+sizeof(RR->r_datalen));        RR = RR->r_next;    }    /* If RR == NULL we have copied all RRs to the user buffer */    if (RR == NULL)    {        /* Indicate the user about the actual length of data */        *(dmsg->len) = copy_len;        dmsg->error = ESUCCESS;        if (query->qtype == srv_type)        {             memcpy (dmsg->dnsMsg, dns_client_recvbuf, BUFLEN);        }    }    else    {        /* user supplied buffer is less to copy all RRs */        dmsg->error = EMORE; /* shd be EMORE */        /* calculate the length of buffer needed to accomodate all RRs */        while (RR != NULL)        {            copy_len += (RR->r_datalen+sizeof(RR->r_datalen));            RR = RR->r_next;        }        /* Indicate the user about the actual length of buffer needed */        *(dmsg->len) = copy_len;    }    DNSC_DEBUG("exit\n");    return ;}   /* end fmt_XX_answer() */

⌨️ 快捷键说明

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