📄 dns_client_util.c
字号:
/* ############################################################################ (c) Copyright Virata Limited 2001## Virata Limited Confidential and Proprietary## The following software source code ("Software") is strictly confidential and# is proprietary to Virata Limited ("Virata"). It may only be read, used,# copied, adapted, modified or otherwise dealt with by you if you have# entered into a confidentiality agreement with Virata and then subject to the# terms of that confidentiality agreement and any other applicable agreement# between you and Virata. If you are in any doubt as to whether you are# entitled to access, read, use, copy, adapt, modify or otherwise deal with# the Software or whether you are entitled to disclose the Software to any# other person you should contact Virata. If you have not entered into a# confidentiality agreement with Virata granting access to this Software you# should forthwith return all media, copies and printed listings containing# the Software to Virata.## Virata reserves the right to take legal action against you should you breach# the above provisions.## If you are unsure, or to report violations, please contact# support@virata.com# ##########################################################################*//* * file: dns_client_util.c * * description: routines used by the DNS resolver code for utility * purposes. */#include <stdio.h>#include <string.h>#include <errno.h>#include "messages.h"#include "dns_client.h"#include "dns_client_query.h"extern U8 dns_client_recvbuf[BUFLEN];/* * domain_compare() * * this routine determines which NS domain is the best match with our domain. * we determine the number of matching domain parts for both the first, fns, * and the second, sns, NS domain. which ever has the most is considered the * best match. * * return: -1 - the first NS domain, fns, is the best. * 0 - the two have the same number of matching domain parts. * 1 - the second NS domain, sns, is the better, * -2 - indicates there was an error condition. */intdomain_compare(Dcmp *domain, Dcmp *fns, Dcmp *sns){ int fmatch, smatch; if ((fmatch = count_match(domain, fns)) < 0) { dprintf("%C error counting matching parts\n"); return -2; } if ((smatch = count_match(domain, sns)) < 0) { dprintf("%C error counting matching parts\n"); return -2; } if ( fmatch > smatch ) return -1; else if ( fmatch == smatch ) return 0; else return 1;} /* end domain_compare() *//* * count_match() * * this routine will count the number of domain parts that match. to be robust, * we don't assume both strings have or don't have the trailing dot. and so that * we don't mess with the existing name, we have to get a duplicate string. * * return: the number of domain part matches, or * -1 to indicate an error. */intcount_match(Dcmp *domain, Dcmp *ns){ int i, limit, cnt = 0; const char *dptr, *nsptr; char dupd[NAMEMAX+1]; char dupns[NAMEMAX+1]; /* they either both need to have a trailing dot, or both not have it. * I choose that they won't have it */ strcpy(dupd, domain->dname); if ( dupd[strlen(dupd)-1] == DOT ) dupd[strlen(dupd)-1] = '\0'; strcpy(dupns, ns->dname); if ( dupns[strlen(dupns)-1] == DOT ) dupns[strlen(dupns)-1] = '\0'; limit = MIN(domain->dparts, ns->dparts); for ( i = 1; i < limit; i++ ) { if ((dptr = get_last_domain_parts(dupd, domain->dparts, i)) == NULL) { dprintf("%C domain format error %s\n", dupd); return -1; } if ((nsptr = get_last_domain_parts(dupns, ns->dparts, i)) == NULL) { dprintf("%C domain format error %s\n", dupns); return -1; } if ( strcmp(dptr, nsptr) == 0 ) ++cnt; else break; } return cnt;} /* end count_match() *//* * start_new_query() * * this routine will set up the message and send it off to start another * query. * * return: 0 for success, or * -1 to indicate an error */intstart_new_query(Qinfo_t *nquery){ ATMOS_MQID qid; int rc = 0; /* sendmessge() return code */ DNSC_DEBUG("entry - count: %d, name: %s\n", nquery->qcnt, nquery->hostname); if ((qid = findqueue(atmos_pcb_current_get_name())) == 0) { dprintf("%C: internal query, could not acquire dns_client queur handle\n"); return -1; } switch(nquery->qtype) { case aaaa_t: { MSG_D_DNS_GET_NODEBYNAME(amsg, nquery->amsg); amsg->hostname = nquery->hostname; amsg->error = ESUCCESS; amsg->hent = NULL; amsg->qcnt = nquery->qcnt; if (sendmessage(nquery->amsg, MSG_N_DNS_GET_NODEBYNAME, qid) != ESUCCESS) rc = -1; break; } case addr_t: { MSG_D_DNS_GET_ADDRBYNAME(amsg, nquery->amsg); amsg->hostname = (char *)nquery->hostname; amsg->use_cache = nquery->cache_flag; amsg->hptr = nquery->hptr; amsg->error = ESUCCESS; amsg->qcnt = nquery->qcnt; if ( sendmessage(nquery->amsg, MSG_N_DNS_GET_ADDRBYNAME, qid) != ESUCCESS ) rc = -1; break; } case ptr_t: { MSG_D_DNS_GET_HOSTBYADDR(pmsg, nquery->amsg); pmsg->ipaddr = nquery->ipaddr; pmsg->use_cache = nquery->cache_flag; pmsg->hptr = nquery->hptr; pmsg->error = ESUCCESS; pmsg->qcnt = nquery->qcnt; if ( sendmessage(nquery->amsg, MSG_N_DNS_GET_HOSTBYADDR, qid) != ESUCCESS ) rc = -1; break; } default: dprintf("%C: internal query, unrecognized query type %d\n", nquery->qtype); rc = -1; } DNSC_DEBUG("exit\n"); return rc;} /* end start_query() *//* * fmt_ptr_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. * * return: 0 for success, or * -1 to indicate an error. */intfmt_ptr_answer(QueryState *query, DnsMsg *dnsmsg){ DnsRRec *RR; struct dns_hostent *hptr; MSG_D_DNS_GET_HOSTBYADDR(dmsg, query->reply); hptr = dmsg->hptr; if ((RR = find_match_rrecord(query->domain, dnsmsg->m_answers, QT_PTR)) == NULL) { dprintf("%C unexpected formating error, no pointer answer for %s\n", query->domain);#ifdef DNS_DEBUG print_dns_message(dnsmsg);#endif dmsg->error = ETRYAGAIN; return -1; } strcpy(hptr->h_name, RR->r_data); if ( hptr->h_numaddrs > 0 ) { /* * here we replaced convert_addr_arpa with convert_addr_ipv4 * since we know here we expect only IPv4 addresses */ hptr->h_addr_list[0] = convert_addr_ipv4(query->domain); hptr->h_numaddrs = 1; } dmsg->error = ESUCCESS; return 0;} /* end fmt_ptr_answer() *//* * fmt_ip_answer() * * this routine will construct the response for an address record. we only * return as many addresses as requested. * * return: 0 for success, or * -1 for an error condition. */intfmt_ip_answer(QueryState *query, DnsMsg *dnsmsg){ struct dns_hostent *hptr; DnsRRec *RR; int nanswers; MSG_D_DNS_GET_ADDRBYNAME(dmsg, query->reply); DNSC_DEBUG("entry\n"); hptr = dmsg->hptr; if (strlen(query->cname) > 0) strcpy(hptr->h_alias, query->cname); if ((nanswers = find_num_match(query->domain, dnsmsg->m_answers, QT_A)) == 0) { dprintf("%C: unexpected format error no addresses for %s\n", query->domain);#ifdef DNS_DEBUG print_dns_message(dnsmsg);#endif dmsg->error = ETRYAGAIN; DNSC_DEBUG("exit - unexpected format error no addresses\n"); return -1; } strcpy(hptr->h_name, query->domain); if ( hptr->h_numaddrs > nanswers ) hptr->h_numaddrs = nanswers; RR = find_match_rrecord(query->domain, dnsmsg->m_answers, QT_A); nanswers = 0; DNSC_DEBUG("number of addresses %d\n", hptr->h_numaddrs); while ( RR != NULL && nanswers < hptr->h_numaddrs ) { DNSC_DEBUG("%x\n", *(U32 *)(RR->r_data)); hptr->h_addr_list[nanswers++] = *(U32 *)RR->r_data; RR = find_match_rrecord(query->domain, RR->r_next, QT_A); } dmsg->error = ESUCCESS; DNSC_DEBUG("exit\n"); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -