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

📄 dns_client_support.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* First verify there is a search list, if not return an error */    if (query->dm.num_search <= 0)     {        dprintf("%C NO search list, can't use relative host names\n");        dmsg->error = ENOSEARCHLIST;        sendreply(query->reply);        free_querystate(query);        DNSC_DEBUG("exit - NO search list, can't use relative host names\n");        return;    }       strcpy(query->domain, dmsg->hostname);     strcat(query->domain, SDOT);    strcat(query->domain, query->dm.search[query->next_srch]);    if (query->domain[strlen(query->domain) - 1] != DOT)        strcat(query->domain, SDOT); #ifdef DNS_DEBUG    if (!query->use_cache)    {        dprintf("dns_start_next_search6: must be allowed to use cache\n");    }#endif    if (query->use_cache)     {        DnsQuestion  question;    /* cache API expects a DnsQuestion structure */	DnsMsg       dnsmsg;      /* responses are returned in a DNS message */        int          rc;                memset(&dnsmsg, 0, sizeof(DnsMsg));	strcpy(question.q_name, query->domain);	question.q_type = QT_AAAA;	question.q_class = QC_IN;        rc = dns_query_cache_byname6(&question, &dnsmsg);        if (rc >= 0)        {            /*              * We cache name errors, so the cache could tell us this domain	     * does not exit. If this is the last of the search list we return	     * the name doesn't exist, otherwise we try another element of the	     * search list.	     */	    if ((dnsmsg.m_dnshdr.flags & DNS_RCODE) == DNS_NAMEERR)             {	        if ( ++query->next_srch >= query->dm.num_search )                 {		    dmsg->error = EHOSTNOTFOUND;		    sendreply(query->reply);		    free_querystate(query);                    DNSC_DEBUG("exit - 1\n");		    return;		}		else		    return dns_start_next_search6(query);	    }            if (rc == DNS_ANSWER || rc == DNS_CNAMEANSWER)             { /* We got a direct answer */	        dns_fmt_cache6_answer(query, &dnsmsg);		dnsmsg_cleanup(&dnsmsg);		sendreply(query->reply);		free_querystate(query);                DNSC_DEBUG("exit - 2\n");		return;            }		    /* 	     * The response could be a CNAME without the address for it, if thats	     * the case we have to construct a DNS query for the new name. Otherwise	     * we have an answer then we format and return to the user.  The cache	     * places AAAA records for CNAMEs in the additional section.  So if we have	     * a CNAME record and no additional records then we do a query for the	     * new host name.	     */	    if (QT_CNAME == dnsmsg.m_answers->r_type && 0 == dnsmsg.m_dnshdr.naddrr)             {	        strcpy(query->cname, query->domain);		strcpy(query->domain, dnsmsg.m_answers->r_data);		query->qtype = ac_type;		query->qstate = wf_caddr;	    }	} /* if (rc >= 0) */    } /* if ( query->use_cache) */    else     {        query->qtype = aaaa_type;	query->qstate = wf_aaaa;    }    /*      * Reset the name server counters, construct the DNS message and send      * off the UDP message, (UDP messsage sent by dns_query()).     */    for ( i = 0; i < query->dm.num_svr; i++ )        query->ns_addrs[i].ns_try = 0;    if ( dns_query(query) < 0 )     {	terminate_query(query);        DNSC_DEBUG("exit - dns_query failed\n");	return;    }    if (++query->next_srch >= query->dm.num_search)   /* if this was the last search */        query->next_srch = -1;                          /* mark it done */    DNSC_DEBUG("exit\n");    }   /* end dns_start_next_search6() *//* * dns_start_next_search() * * this routine sets up for the next attempt using a constructed name from search list. * if okay by the user we first check the cache for the answer. if there, we format it * and return the information to the user.  if not, we set up for the next query attempt * using the new name. */voiddns_start_next_search(QueryState *query){    int   i;    MSG_D_DNS_GET_ADDRBYNAME(dmsg, query->reply);     DNSC_DEBUG("entry\n");    /* first verify there is a search list, if not return an error */    if ( query->dm.num_search <= 0 ) {        dprintf("%C NO search list, can't use relative host names\n");        dmsg->error = ENOSEARCHLIST;        sendreply(query->reply);        free_querystate(query);        DNSC_DEBUG("exit - NO search list, can't use relative host names\n");        return;    }       strcpy(query->domain, dmsg->hostname);     strcat(query->domain, SDOT);    strcat(query->domain, query->dm.search[query->next_srch]);    if ( query->domain[strlen(query->domain)-1] != DOT )        strcat(query->domain, SDOT);     /* if okay by the user, try the cache first */    if ( query->use_cache ) {        DnsQuestion  question;    /* cache API expects a DnsQuestion structure */	DnsMsg       dnsmsg;      /* responses are returned in a DNS message */                memset(&dnsmsg, 0, sizeof(DnsMsg));	strcpy(question.q_name, query->domain);	question.q_type = QT_A;	question.q_class = QC_IN;	if ( query_cache(&question, &dnsmsg) == 0 ) {            /* we cache name errors, so the cache could tell us this domain	     * does not exit. if this is the last of the search list we return	     * the name doesn't exist, otherwise we try another element of the	     * search list.	     */	    if ((dnsmsg.m_dnshdr.flags & DNS_RCODE) == DNS_NAMEERR) {	        if ( ++query->next_srch >= query->dm.num_search ) {		    dmsg->error = EHOSTNOTFOUND;		    sendreply(query->reply);		    free_querystate(query);		    return;		}		else		    return dns_start_next_search(query);	    }		    /* 	     * the response could be a CNAME without the address for it, if thats	     * the case we have to construct a DNS query for the new name. otherwise	     * we have an answer then we format and return to the user.  the cache	     * places A records for CNAMEs in the additional section.  so if we have	     * a CNAME record and no additional records then we do a query for the	     * new host name.	     */	    if ( QT_CNAME == dnsmsg.m_answers->r_type && 0 == dnsmsg.m_dnshdr.naddrr ) {	        strcpy(query->cname, query->domain);		strcpy(query->domain, dnsmsg.m_answers->r_data);		query->qtype = ac_type;		query->qstate = wf_caddr;	    }	    else {	        fmt_cache_answer(query, &dnsmsg);		dnsmsg_cleanup(&dnsmsg);		sendreply(query->reply);		free_querystate(query);            DNSC_DEBUG("exit - 3\n");		return;	    }	}    }    else {        query->qtype = a_type;	query->qstate = wf_addr;    }    /* reset the name server counters, construct the DNS message and send      * off the UDP message, (UDP messsage sent by dns_query()).     */    for ( i = 0; i < query->dm.num_svr; i++ )        query->ns_addrs[i].ns_try = 0;    if ( dns_query(query) < 0 ) {	terminate_query(query);        DNSC_DEBUG("exit - dns_query failed\n");	return;    }    if ( ++query->next_srch >= query->dm.num_search )   /* if this was the last search */        query->next_srch = -1;                          /* mark it done */    DNSC_DEBUG("exit\n");}   /* end dns_start_next_search() *//* * terminate_query() * * this routine will force an end to the DNS query.  typically this is called if * we have exceeded limits on the number of DNS request messages or the number of * queries that have been generated. */static voidterminate_query(QueryState *query){    DNSC_DEBUG("entry\n");    switch(query->qtype) {                  /* set the error and send the reply */    case aaaa_type:    case a6_type: {        MSG_D_DNS_GET_NODEBYNAME(dmsg, query->reply);        dmsg->error = ETRYAGAIN;        sendreply(query->reply);        break;    }    case a_type:    case ac_type: {        MSG_D_DNS_GET_ADDRBYNAME(dmsg, query->reply);	dmsg->error = ETRYAGAIN;	sendreply(query->reply);	break;    }    case ptr_type: {        MSG_D_DNS_GET_HOSTBYADDR(dmsg, query->reply);	dmsg->error = ETRYAGAIN;	sendreply(query->reply);	break;    }    case ptr6_type: {        MSG_D_DNS_GET_HOSTBYADDR6(dmsg, query->reply);        dmsg->error = ETRYAGAIN;        sendreply(query->reply);        break;    }    case naptr_type:     case srv_type:     {        MSG_D_DNS_GET_RR(dmsg, query->reply);        dmsg->error = ETRYAGAIN;        sendreply(query->reply);        break;    }    default:        dprintf("%C Error: unrecognized query type: %d\n", query->qtype);    }    free_querystate(query);    DNSC_DEBUG("exit\n");    }   /* end terminate_query() *//* * display_node_reply -- *     This routine is called to print out the results of a host name query.   *     We print out all IPv6 addresses. * * PARAMETERS *     msg - DNS_GET_NODEBYNAME message * * RETURNS *     n/a */static voiddisplay_node_reply(IN ATMOS_MESSAGE *msg){    struct hostent  *hent;    int              i;    char             ipstr[INET6_ADDRSTRLEN];    MSG_D_DNS_GET_NODEBYNAME(dmsg, msg);    DNSC_DEBUG("entry\n");    if ( ESUCCESS == dmsg->error ) {        hent = dmsg->hent;	printf("\nName:   %s\n", hent->h_name);        /* print out addresses */        if (hent->h_addr_list != NULL)        {            char **list = hent->h_addr_list;            if (*list != NULL)            {                /* more than one address? */                if (list[1] != NULL)                {                    char *tmp;                    for (tmp = *list, i = 0; tmp; tmp = list[++i])                    {                        inet_ntop(AF_INET6, tmp, ipstr, sizeof(ipstr));                        printf("Address[%d]: %s\n", i, ipstr);                    }                }                else /* no just only one */                {                    inet_ntop(AF_INET6, *list, ipstr, sizeof(ipstr));                    printf("Address: %s\n", ipstr);                }            }        }        /* print out aliases */        if (hent->h_aliases != NULL)        {            char **list = hent->h_aliases;            if (*list != NULL)            {                /* more than one alias? */                if (list[1] != NULL)                {                    char *tmp;                    for (tmp = *list, i = 0; tmp; tmp = list[++i])                    {                        printf("Alias[%d]: %s\n", i, tmp);                    }                }                else /* no just only one */                {                    printf("Alias: %s\n", *list);                }            }        }        	printf("\n");    }    else        print_dns_error(dmsg->error);    dns_nslkup_msg_free(msg);   /* free up our resources */    DNSC_DEBUG("exit\n");}   /* end display_node_reply() *//* * display_host_reply() * * this routine is called to print out the results of a host name query.  we print * out all IP addresses. */static voiddisplay_host_reply(ATMOS_MESSAGE *msg){    struct dns_hostent  *hptr;    int                 i;    char                ipstr[INET6_ADDRSTRLEN];    MSG_D_DNS_GET_ADDRBYNAME(dmsg, msg);    DNSC_DEBUG("entry\n");    if ( ESUCCESS == dmsg->error ) {        hptr = dmsg->hptr;	printf("\nName:   %s\n", hptr->h_name);	if ( hptr->h_numaddrs > 1 ) {	    for ( i = 0; i < hptr->h_numaddrs; i++ ) {                inet_ntop(AF_INET, hptr->h_addr_list + i,                           ipstr, sizeof(ipstr)); 	        printf("Address[%d]: %s\n", i, ipstr);	    }	}	else {            inet_ntop(AF_INET, hptr->h_addr_list + 0, ipstr, sizeof(ipstr));	    printf("Address:  %s\n", ipstr);	}        if ( hptr->h_alias[0] != '\0' )            printf("Alias: %s\n", hptr->h_alias);	printf("\n");    }    else        print_dns_error(dmsg->error);    dns_nslkup_msg_free(msg);   /* free up our resources */    DNSC_DEBUG("exit\n");}   /* end display_host_reply() */#ifdef DNS_DEBUGvoiddisplay_dnsmsghdr(U8 *pkt){    U16       flag;    DnsHdr    *hdr = (DnsHdr *)pkt;    DNSC_DEBUG("entry\n");    dprintf("DNS message ID: %d\n", ntohs(hdr->id));    dprintf("flags 0x%X\n", ntohs(hdr->flags));    flag = ntohs(hdr->flags);    if ((flag & DNS_QR) == DNS_QR)        dprintf("message is a response\n");    else        dprintf("message is a query\n");    if ((flag & DNS_OPCODE) == DNS_STDQUERY)        dprintf("message is a standard query\n");    else if ((flag & DNS_OPCODE) == DNS_INVQUERY)        dprintf("message is an inverse query\n");    else if ((flag & DNS_OPCODE) == DNS_STATUS)        dprintf("message is server status requesst\n");    if ((flag & DNS_AUTHANS) == DNS_AUTHANS)        dprintf("message is an authoritive answer\n");    else        dprintf("message is not an authoritive answer\n");    if ((flag & DNS_TRUNC) == DNS_TRUNC)        dprintf("message is truncated\n");    else        dprintf("message not truncated\n");    if ((flag & DNS_RECURDD) == DNS_RECURDD)        dprintf("message asked for recursion\n");    else        dprintf("message did not ask for recursion\n");    if ((flag & DNS_RECURAV) == DNS_RECURAV)        dprintf("message indicates recursion available from server\n");    else        dprintf("message does not indicate recursion available\n");    if ((flag & DNS_RCODE) == DNS_NOERROR)        dprintf("no errors\n");    else if ((flag & DNS_RCODE) == DNS_NAMEERR)        dprintf("domain does not exist\n");    dprintf("\n");    DNSC_DEBUG("exit\n");}#endif

⌨️ 快捷键说明

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