📄 dns_client_support.c
字号:
/* 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 + -