WINAPI hes_resolve(LPSTR HesiodName, LPSTR HesiodNameType) { register char *cp; LPSTR* retvec; DNS_STATUS status; PDNS_RECORD pDnsRecord; PDNS_RECORD pR; DNS_FREE_TYPE freetype ; int i = 0; freetype = DnsFreeRecordListDeep; cp = hes_to_bind(HesiodName, HesiodNameType); if (cp == NULL) return(NULL); errno = 0; status = DnsQuery_A(cp, //pointer to OwnerName DNS_TYPE_TEXT, //Type of the record to be queried DNS_QUERY_STANDARD, // Bypasses the resolver cache on the lookup. NULL, //contains DNS server IP address &pDnsRecord, //Resource record comprising the response NULL); //reserved for future use if (status) { errno = status; Hes_Errno = HES_ER_NOTFOUND; return NULL; } pR = pDnsRecord; while (pR) { if (pR->wType == DNS_TYPE_TEXT) i++; pR = pR->pNext; } i++; retvec = LocalAlloc(LPTR, i*sizeof(LPSTR)); pR = pDnsRecord; i = 0; while (pR) { if (pR->wType == DNS_TYPE_TEXT){ SIZE_T l = strlen(((pR->Data).Txt.pStringArray)[0]); retvec[i] = LocalAlloc(LPTR, l+1); strcpy(retvec[i], ((pR->Data).Txt.pStringArray)[0]); i++; } pR = pR->pNext; } retvec[i] = NULL; DnsRecordListFree(pDnsRecord, freetype); return retvec; }
static void do_lookup_records (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { LookupRecordsData *lrd = task_data; GList *records; GError *error = NULL; #if defined(G_OS_UNIX) gint len = 512; gint herr; GByteArray *answer; gint rrtype; rrtype = g_resolver_record_type_to_rrtype (lrd->record_type); answer = g_byte_array_new (); for (;;) { g_byte_array_set_size (answer, len * 2); len = res_query (lrd->rrname, C_IN, rrtype, answer->data, answer->len); /* If answer fit in the buffer then we're done */ if (len < 0 || len < (gint)answer->len) break; /* * On overflow some res_query's return the length needed, others * return the full length entered. This code works in either case. */ } herr = h_errno; records = g_resolver_records_from_res_query (lrd->rrname, rrtype, answer->data, len, herr, &error); g_byte_array_free (answer, TRUE); #else DNS_STATUS status; DNS_RECORD *results = NULL; WORD dnstype; dnstype = g_resolver_record_type_to_dnstype (lrd->record_type); status = DnsQuery_A (lrd->rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL); records = g_resolver_records_from_DnsQuery (lrd->rrname, dnstype, status, results, &error); if (results != NULL) DnsRecordListFree (results, DnsFreeRecordList); #endif if (records) g_task_return_pointer (task, records, (GDestroyNotify) free_records); else g_task_return_error (task, error); }
static DWORD WINAPI lookup_service_in_thread (LPVOID data) { GWin32ResolverRequest *req = data; req->u.service.retval = DnsQuery_A (req->u.service.rrname, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &req->u.service.results, NULL); SetEvent (req->event); return 0; }
int net_reQueryMxRecord(char * domain, struct in_addr * mxIP) { DNS_STATUS dns_rc = 0; DNS_RECORD * pQueryResultsSet; char smtp_fqdn[SMTP_MAX_FQDN+1] = {0}; debug_log(LOG_DBG, "net_reQueryMxRecord(): querying mx records for email domain: \'%s\'", domain); dns_rc = DnsQuery_A(domain, DNS_TYPE_MX, DNS_QUERY_STANDARD, NULL, &pQueryResultsSet, NULL); if (dns_rc == 0) { strncpy_s(smtp_fqdn, sizeof(smtp_fqdn), pQueryResultsSet->Data.MX.pNameExchange, strlen(pQueryResultsSet->Data.MX.pNameExchange)); debug_log(LOG_DBG, "net_reQueryMxRecord(): email domain: \'%s\', mail server: \'%s\'", domain, smtp_fqdn); DnsRecordListFree(pQueryResultsSet, DnsFreeRecordList); debug_log(LOG_DBG, "net_reQueryMxRecord(): looking up an IP for \'%s\'", smtp_fqdn); dns_rc = DnsQuery_A(smtp_fqdn, DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pQueryResultsSet, NULL); if (dns_rc == 0) { mxIP->S_un.S_addr = pQueryResultsSet->Data.A.IpAddress; debug_log(LOG_DBG, "net_reQueryMxRecord(): mail exchanger: \'%s\', ip: %s", smtp_fqdn, inet_ntoa(*mxIP)); DnsRecordListFree(pQueryResultsSet, DnsFreeRecordList); } else { debug_log(LOG_ERR, "net_reQueryMxRecord(): failed to resolve ip for mail exchanger: \'%s\', rc: %d)", smtp_fqdn, dns_rc); debug_log(LOG_SVR, "net_reQueryMxRecord(): sending of email notifications will be disabled."); return SOCK_DNS_ERROR; } } else { debug_log(LOG_ERR, "net_reQueryMxRecord(): failed to resolve mx record for domain: \'%s\', rc: %d)", domain, dns_rc); debug_log(LOG_SVR, "net_reQueryMxRecord(): sending of email notifications will be disabled."); return SOCK_DNS_ERROR; } return SOCK_NO_ERROR; } // end of net_reQueryMxRecord()
/* Gets the machine's domain name \param[in, out] name pointer to a buffer that receives a null-terminated string containing the domain name \param[in] size specifies the size of the buffer, in chars (must be large enough to hold NULL-terminated domain name) \retval return 0 ifsuccess, -1 on error. */ int WINAPI wsh_getdomainname(char* name, int size) { DNS_STATUS status; PDNS_RECORD pDnsRecord; DNS_FREE_TYPE freetype ; DWORD length; char hostName[BUFSIZ]; length = BUFSIZ; freetype = DnsFreeRecordListDeep; // Get and display the name of the computer. if( GetComputerName(hostName, &length) ) { status = DnsQuery_A(hostName, //pointer to OwnerName DNS_TYPE_A, //Type of the record to be queried DNS_QUERY_BYPASS_CACHE|DNS_QUERY_NO_LOCAL_NAME, // Bypasses the resolver cache on the lookup. NULL, //contains DNS server IP address &pDnsRecord, //Resource record comprising the response NULL); //reserved for future use if (status) return -1; else { char* cp; cp = index(pDnsRecord->pName, '.'); if (cp) { cp++; strncpy(name, cp, size); name[size-1] = '\0'; DnsRecordListFree(pDnsRecord, freetype); return(0); } DnsRecordListFree(pDnsRecord, freetype); } } /* try to get local domain from the registry */ if (_getdomainname(name, size)) return 0; else return -1; }
/* an internal function used by rgethostbyname that does the actual DnsQuery call and populates the hostent structure. \param[in] Name of the owner of the record set being queried \param[in, out] populated hostent structure \retval DNS_STATUS value returned by DnsQuery */ DNS_STATUS doquery(const char* queryname, struct hostent* host) { DNS_STATUS status; PDNS_RECORD pDnsRecord, pDnsIter; DNS_FREE_TYPE freetype ; struct in_addr host_addr; char querynamecp[DNS_MAX_NAME_BUFFER_LENGTH]; size_t len; freetype = DnsFreeRecordListDeep; strcpy(querynamecp, queryname); status = DnsQuery_A(queryname, //pointer to OwnerName DNS_TYPE_A, //Type of the record to be queried DNS_QUERY_STANDARD, NULL, //contains DNS server IP address &pDnsRecord, //Resource record comprising the response NULL); //reserved for future use if (status) return status; /* If the query name includes a trailing separator in order to prevent * a local domain search, remove the separator during the file name * comparisons. */ len = strlen(querynamecp); if (querynamecp[len-1] == '.') querynamecp[len-1] = '\0'; for (pDnsIter = pDnsRecord; pDnsIter; pDnsIter=pDnsIter->pNext) { /* if we get an A record, keep it */ if (pDnsIter->wType == DNS_TYPE_A && stricmp(querynamecp, pDnsIter->pName)==0) break; /* if we get a CNAME, look for a corresponding A record */ if (pDnsIter->wType == DNS_TYPE_CNAME && stricmp(queryname, pDnsIter->pName)==0) { strcpy(querynamecp, pDnsIter->Data.CNAME.pNameHost); } } if (pDnsIter == NULL) return DNS_ERROR_RCODE_NAME_ERROR; strcpy(host->h_name, pDnsIter->pName); host->h_addrtype = AF_INET; host->h_length = sizeof(u_long); host->h_aliases[0] = NULL; host_addr.S_un.S_addr = (pDnsIter->Data.A.IpAddress); memcpy(host->h_addr_list[0], (char*)&host_addr, sizeof(pDnsIter->Data.A.IpAddress)); host->h_addr_list[1] = NULL; DnsRecordListFree(pDnsRecord, freetype); return 0; }
ToxHexAddress ResolveToxAddressFromDns(const char *dnsQuery) { ToxHexAddress address = ToxHexAddress::Empty(); DNS_RECORDA *record = NULL; DNS_STATUS status = DnsQuery_A(dnsQuery, DNS_TYPE_TEXT, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD*)&record, NULL); while (status == ERROR_SUCCESS && record) { DNS_TXT_DATAA *txt = &record->Data.Txt; if (record->wType == DNS_TYPE_TEXT && txt->dwStringCount) { address = ResolveToxAddressFromDnsRecordV1(txt->pStringArray[0]); break; } record = record->pNext; } DnsRecordListFree((PDNS_RECORD*)record, DnsFreeRecordList); return address; }
int DnsNameToIp(std::string name, std::string* ipv4) { if (name.empty() || name == "") { return -1; } DNS_A_DATA dnsRet; PDNS_RECORD pDnsRecord; DNS_STATUS status = DnsQuery_A((PCSTR)name.c_str(), DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pDnsRecord, NULL); if (status == 0) { IN_ADDR ipaddr; if (pDnsRecord) ipaddr.S_un.S_addr = (pDnsRecord->Data.A.IpAddress); *ipv4 = inet_ntoa(ipaddr); } return status; }
DNS_STATUS do_res_search(const char *queryname, int qclass, int type, u_char *retanswer, int retanswerlen, int* anslen) { PDNS_RECORD pDnsRecord; PDNS_RECORD ptr; DNS_STATUS status; DNS_FREE_TYPE freetype ; HEADER *hp; char *cp; int n; int i; u_char answer[MAX_MSG_SIZE]; DWORD options = DNS_QUERY_STANDARD; freetype = DnsFreeRecordListDeep; memset(answer, 0, MAX_MSG_SIZE); if (!(_res.options & RES_RECURSE)) options = options | DNS_QUERY_NO_RECURSION; if (_res.options & RES_USEVC) options = options | DNS_QUERY_USE_TCP_ONLY; if (_res.options & RES_IGNTC) options = options | DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE; status = DnsQuery_A(queryname, //pointer to OwnerName type, //Type of the record to be queried options, NULL, //contains DNS server IP address &pDnsRecord, //Resource record comprising the response NULL); //reserved for future use if (status) return status; hp = (HEADER *) answer; cp = answer + sizeof(HEADER); // populating the header hp->id = htons(++_res.id); // query id hp->qr = 1; // 0 for query 1 for response hp->opcode = 0; // standard query hp->aa = 1; // authoritative answer hp->tc = 0; // no truncation hp->rd = (_res.options & RES_RECURSE) != 0; // resursion desired hp->ra = 1; // recursion available hp->pr = (_res.options & RES_PRIMARY) != 0; // primary server required hp->rcode = NOERROR; hp->qdcount = htons(1); // number of question entries i = put_qname(cp, (char*)queryname); cp = cp + i; __putshort(type, (u_char *)cp); cp += sizeof(u_short); __putshort(qclass, (u_char *)cp); cp += sizeof(u_short); // get the answer for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext) { if ((ptr->Flags).S.Section == DNSREC_ANSWER || (type == DNS_TYPE_PTR && (ptr->Flags).S.Section==DNSREC_QUESTION)) { i = build_rr(cp, ptr, qclass); cp = cp + i; //strcpy(cp, pDnsRecord->pName); //cp += strlen(pDnsRecord->pName); //cp++; n++; } } hp->ancount = htons(n); // get the authority for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext) { if ((ptr->Flags).S.Section == DNSREC_AUTHORITY ) { i = build_rr(cp, ptr, qclass); cp = cp + i; n++; } } hp->nscount = htons(n); // get the additional resource for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext) { if ((ptr->Flags).S.Section == DNSREC_ADDITIONAL) { i = build_rr(cp, ptr, qclass); cp = cp + i; n++; } } hp->arcount = htons(n); *anslen = (int)(cp - answer); if (*anslen > retanswerlen) memcpy(retanswer, answer, retanswerlen); // partial copy else memcpy(retanswer, answer, *anslen); DnsRecordListFree(pDnsRecord, freetype); return status; }
// the main function void __cdecl main(int argc, char *argv[]) { DNS_STATUS status; // return value of DnsQuery_A() function. PDNS_RECORD pDnsRecord; //pointer to DNS_RECORD structure PIP4_ARRAY pSrvList = NULL; //pinter to IP4_ARRAY structure LPTSTR pOwnerName = NULL; //owner name to be queried WORD wType; //Type of the record to be queried char DnsServIp[BUFFER_LEN]; //DNS server ip address DNS_FREE_TYPE freetype ; freetype = DnsFreeRecordListDeep; IN_ADDR ipaddr; if (argc > 4) { for (int i = 1; i < argc ; i++) { if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) { switch (tolower(argv[i][1])) { case 'n': pOwnerName = argv[++i]; break; case 't': if (!_stricmp(argv[i+1], "A") ) wType = DNS_TYPE_A; //Query host records to resolve a name else if (!_stricmp(argv[i+1], "PTR") ) wType = DNS_TYPE_PTR; //Query PTR records to resovle an IP address else Usage(argv[0]); i++; break; case 's': // Allocate memory for IP4_ARRAY structure pSrvList = (PIP4_ARRAY) LocalAlloc(LPTR,sizeof(IP4_ARRAY)); if (!pSrvList) { printf("Memory allocation failed \n"); exit(1); } if (argv[++i]) { strncpy_s(DnsServIp, _countof(DnsServIp), argv[i], _TRUNCATE); DnsServIp[sizeof(DnsServIp)-1] = '\0'; pSrvList->AddrCount = 1; pSrvList->AddrArray[0] = inet_addr(DnsServIp); //DNS server IP address if ( pSrvList->AddrArray[0] == INADDR_NONE ) { printf("Invalid DNS server IP address \n"); Usage( argv[0] ); } break; } default: Usage(argv[0]); break; } } else Usage(argv[0]); } } else Usage(argv[0]); // Calling function DnsQuery_A() to query Host or PTR records status = DnsQuery_A(pOwnerName, //pointer to OwnerName wType, //Type of the record to be queried DNS_QUERY_BYPASS_CACHE, // Bypasses the resolver cache on the lookup. pSrvList, //contains DNS server IP address &pDnsRecord, //Resource record comprising the response NULL); //reserved for future use if (status) { if (wType == DNS_TYPE_A) printf("Failed to query the host record for %s and the error is %d \n", pOwnerName, status); else printf("Failed to query the PTR record and the error is %d \n", status); } else { if (wType == DNS_TYPE_A) { //convert the Internet network address into a string //in Internet standard dotted format. ipaddr.S_un.S_addr = (pDnsRecord->Data.A.IpAddress); printf("The IP address of the host %s is %s \n", pOwnerName,inet_ntoa(ipaddr)); // Free memory allocated for DNS records DnsRecordListFree(pDnsRecord, freetype); } else { printf("The host name is %s \n",(pDnsRecord->Data.PTR.pNameHost)); // Free memory allocated for DNS records DnsRecordListFree(pDnsRecord, freetype); } } LocalFree(pSrvList); }
/*********************************************************************** * cygwin_query: implements res_nquery by calling DnsQuery ***********************************************************************/ static int cygwin_query(res_state statp, const char * DomName, int Class, int Type, unsigned char * AnsPtr, int AnsLength) { DNS_STATUS res; PDNS_RECORD pQueryResultsSet, rr; int section, len, counts[4] = {0, 0, 0, 0}, debug = statp->options & RES_DEBUG; unsigned char * dnptrs[256], * ptr; dnptrs[0] = AnsPtr; dnptrs[1] = NULL; if (Class != ns_c_in) { errno = ENOSYS; statp->res_h_errno = NETDB_INTERNAL; return -1; } res = DnsQuery_A(DomName, Type, DNS_QUERY_TREAT_AS_FQDN, NULL, &pQueryResultsSet, NULL); #if 0 #define NETDB_INTERNAL -1 /* see errno */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #endif DPRINTF(debug, "DnsQuery: %lu (Windows)\n", res); if (res) { switch (res) { case ERROR_INVALID_NAME: errno = EINVAL; statp->res_h_errno = NETDB_INTERNAL;; break; case ERROR_TIMEOUT: statp->res_h_errno = TRY_AGAIN; break; case DNS_ERROR_RCODE_NAME_ERROR: statp->res_h_errno = HOST_NOT_FOUND; break; case DNS_ERROR_RCODE_SERVER_FAILURE: statp->res_h_errno = TRY_AGAIN; break; case DNS_ERROR_NO_DNS_SERVERS: case DNS_ERROR_RCODE_FORMAT_ERROR: case DNS_ERROR_RCODE_NOT_IMPLEMENTED: case DNS_ERROR_RCODE_REFUSED: statp->res_h_errno = NO_RECOVERY; break; case DNS_INFO_NO_RECORDS: /* May be returned even if the host doesn't exist */ statp->res_h_errno = NO_DATA; break; default: DPRINTF(debug, "Unknown code %lu for %s %d\n", res, DomName, Type); statp->res_h_errno = NO_RECOVERY; break; } len = -1; goto done; } ptr = AnsPtr + HFIXEDSZ; /* Skip header */ rr = pQueryResultsSet; section = 0; while (rr) { if (!counts[0] && (rr->Flags.DW & 0x3)) { /* No question. Adopt the first name as the name in the question */ if ((len = dn_comp(rr->pName, ptr, AnsLength - 4, dnptrs, &dnptrs[DIM(dnptrs) - 1])) < 0) { ptr = NULL; break; } ptr += len; PUTSHORT(Type, ptr); PUTSHORT(ns_c_in, ptr); counts[0] = 1; } DPRINTF(debug, "%s Section %d Type %u Windows Record Length %u\n", rr->pName, rr->Flags.DW & 0x3, rr->wType, rr->wDataLength); /* Check the records are in correct section order */ if ((rr->Flags.DW & 0x3) < section) { DPRINTF(debug, "Unexpected section order %s %d\n", DomName, Type); continue; } section = rr->Flags.DW & 0x3; ptr = write_record(ptr, rr, AnsPtr + AnsLength, dnptrs, &dnptrs[DIM(dnptrs) - 1], debug); counts[section]++; rr = rr->pNext; } DnsRecordListFree(pQueryResultsSet, DnsFreeRecordList); len = ptr - AnsPtr; done: ptr = AnsPtr; PUTSHORT(0, ptr); /* Id */ PUTSHORT((QR << 8) + RA + RD, ptr); for (section = 0; section < DIM(counts); section++) { PUTSHORT(counts[section], ptr); } return len; }
/*********************************************************************** * get_dns_info: Get the search list or the domain name and the dns server addresses in Network Byte Order Set statp->os_query if DnsQuery is available. ***********************************************************************/ void get_dns_info(res_state statp) { #if MAX_HOSTNAME_LEN > MAXHOSTNAMELEN #define MAX_HOSTNAME_SIZE (MAX_HOSTNAME_LEN + 1) #else #define MAX_HOSTNAME_SIZE (MAXHOSTNAMELEN + 1) #endif #if MAX_HOSTNAME_SIZE > 256 /* sizeof(defdname) */ #error stap->defdname too short #endif int res, debug = statp->options & RES_DEBUG; ULONG ulOutBufLen = 0; DWORD dwRetVal; IP_ADDR_STRING * pIPAddr; FIXED_INFO * pFixedInfo; int numAddresses = 0; if (statp->use_os && ((dwRetVal = DnsQuery_A(NULL, 0, 0, NULL, NULL, NULL)) != ERROR_PROC_NOT_FOUND)) { DPRINTF(debug, "using dnsapi.dll %d\n", dwRetVal); statp->os_query = (typeof(statp->os_query)) cygwin_query; /* We just need the search list. Avoid loading iphlpapi. */ statp->nscount = -1; } if (statp->nscount != 0) goto use_registry; /* First call to get the buffer length we need */ dwRetVal = GetNetworkParams((FIXED_INFO *) 0, &ulOutBufLen); if (dwRetVal != ERROR_BUFFER_OVERFLOW) { DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal); goto use_registry; } if ((pFixedInfo = (FIXED_INFO *) alloca(ulOutBufLen)) == 0) { DPRINTF(debug, "alloca: %s\n", strerror(errno)); goto use_registry; } if ((dwRetVal = GetNetworkParams(pFixedInfo, & ulOutBufLen))) { DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal); goto use_registry; } DPRINTF(debug, "GetNetworkParams: OK\n"); /* Record server addresses, up to array size */ for (pIPAddr = &(pFixedInfo->DnsServerList), numAddresses = 0; pIPAddr; pIPAddr = pIPAddr->Next) { if (numAddresses < DIM(statp->nsaddr_list)) { DPRINTF(debug, "server \"%s\"\n", pIPAddr->IpAddress.String); statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr(pIPAddr->IpAddress.String); if (statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0) { numAddresses++; statp->nscount++; } } else DPRINTF(debug, "no space for server \"%s\"\n", pIPAddr->IpAddress.String); } use_registry: get_registry_dns(statp); if (!statp->dnsrch[0]) { statp->defdname[sizeof(statp->defdname) - 1] = 0; if (!(res = getdomainname(statp->defdname, sizeof(statp->defdname)))) { if (statp->defdname[0] && !statp->defdname[sizeof(statp->defdname) - 1]) statp->dnsrch[0] = statp->defdname; } DPRINTF(debug, "getdomainname \"%s\"\n", (res)? strerror(errno) : statp->defdname); } }
DNS_STATUS WINAPI DnsQuery_W(LPCWSTR Name, WORD Type, DWORD Options, PIP4_ARRAY Servers, PDNS_RECORD *QueryResultSet, PVOID *Reserved) { UINT i; PCHAR Buffer; DNS_STATUS Status; PDNS_RECORD QueryResultWide; PDNS_RECORD ConvertedRecord = 0, LastRecord = 0; Buffer = DnsWToC(Name); Status = DnsQuery_A(Buffer, Type, Options, Servers, &QueryResultWide, Reserved); while(Status == ERROR_SUCCESS && QueryResultWide) { switch(QueryResultWide->wType) { case DNS_TYPE_A: case DNS_TYPE_WKS: ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD)); ConvertedRecord->pName = (PCHAR)DnsCToW(QueryResultWide->pName); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = QueryResultWide->wDataLength; memcpy(ConvertedRecord, QueryResultWide, QueryResultWide->wDataLength); break; case DNS_TYPE_CNAME: case DNS_TYPE_PTR: case DNS_TYPE_NS: case DNS_TYPE_MB: case DNS_TYPE_MD: case DNS_TYPE_MF: case DNS_TYPE_MG: case DNS_TYPE_MR: ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD)); ConvertedRecord->pName = (PCHAR)DnsCToW(QueryResultWide->pName); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = sizeof(DNS_PTR_DATA); ConvertedRecord->Data.PTR.pNameHost = (PCHAR)DnsCToW(QueryResultWide->Data.PTR.pNameHost); break; case DNS_TYPE_MINFO: ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD)); ConvertedRecord->pName = (PCHAR)DnsCToW(QueryResultWide->pName); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = sizeof(DNS_MINFO_DATA); ConvertedRecord->Data.MINFO.pNameMailbox = (PCHAR)DnsCToW(QueryResultWide->Data.MINFO.pNameMailbox); ConvertedRecord->Data.MINFO.pNameErrorsMailbox = (PCHAR)DnsCToW(QueryResultWide->Data.MINFO.pNameErrorsMailbox); break; case DNS_TYPE_MX: ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD)); ConvertedRecord->pName = (PCHAR)DnsCToW(QueryResultWide->pName); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = sizeof(DNS_MX_DATA); ConvertedRecord->Data.MX.pNameExchange = (PCHAR)DnsCToW( QueryResultWide->Data.MX.pNameExchange); ConvertedRecord->Data.MX.wPreference = QueryResultWide->Data.MX.wPreference; break; case DNS_TYPE_HINFO: ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_TXT_DATA) + QueryResultWide->Data.TXT.dwStringCount); ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = sizeof(DNS_TXT_DATA) + (sizeof(PWCHAR) * QueryResultWide->Data.TXT.dwStringCount); ConvertedRecord->Data.TXT.dwStringCount = QueryResultWide->Data.TXT.dwStringCount; for(i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++) ConvertedRecord->Data.TXT.pStringArray[i] = (PCHAR)DnsCToW(QueryResultWide->Data.TXT.pStringArray[i]); break; case DNS_TYPE_NULL: ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount); ConvertedRecord->pName = (PCHAR)DnsCToW(QueryResultWide->pName); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount; ConvertedRecord->Data.Null.dwByteCount = QueryResultWide->Data.Null.dwByteCount; memcpy(&ConvertedRecord->Data.Null.Data, &QueryResultWide->Data.Null.Data, QueryResultWide->Data.Null.dwByteCount); break; } if(LastRecord) { LastRecord->pNext = ConvertedRecord; LastRecord = LastRecord->pNext; } else { LastRecord = *QueryResultSet = ConvertedRecord; } } if (LastRecord) LastRecord->pNext = 0; /* The name */ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); return Status; }
WINAPI rgethostbyaddr(const char *addr, int len, int type) { DNS_STATUS status; struct hostent* host; #ifdef DEBUG char debstr[80]; #endif PDNS_RECORD pDnsRecord; DNS_FREE_TYPE freetype ; char qbuf[BUFSIZ]; if (type != AF_INET) return ((struct hostent *) NULL); wsprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", ((unsigned)addr[3] & 0xff), ((unsigned)addr[2] & 0xff), ((unsigned)addr[1] & 0xff), ((unsigned)addr[0] & 0xff)); freetype = DnsFreeRecordListDeep; status = DnsQuery_A(qbuf, //pointer to OwnerName DNS_TYPE_PTR, //Type of the record to be queried DNS_QUERY_STANDARD, NULL, //contains DNS server IP address &pDnsRecord, //Resource record comprising the response NULL); //reserved for future use if (status) { #ifdef DEBUG if (_res.options & RES_DEBUG) { wsprintf(debstr, "res_query failed\n"); OutputDebugString(debstr); } #endif return NULL; } host = (struct hostent*)(TlsGetValue(dwGhaIndex)); if (host == NULL) { LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent)); if (lpvData != NULL) { TlsSetValue(dwGhaIndex, lpvData); host = (struct hostent*)lpvData; } else return NULL; } if (host->h_name == NULL) host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH); if (host->h_aliases == NULL) host->h_aliases = LocalAlloc(LPTR, 1*sizeof(LPSTR)); if (host->h_addr_list == NULL) { host->h_addr_list = LocalAlloc(LPTR, 2*sizeof(LPSTR)); host->h_addr_list[0] = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH); } strcpy(host->h_name, pDnsRecord->Data.Ptr.pNameHost); host->h_addrtype = type; host->h_length = len; host->h_aliases[0] = NULL; memcpy(host->h_addr_list[0], addr, sizeof(unsigned long)); host->h_addr_list[1] = NULL; DnsRecordListFree(pDnsRecord, freetype); return host; }
bool dns_srv_lookup(const std::string& name, dns_srv_record_list& recordList) { static OSS::Private::DnsSrvExpireCache srvCache(3600 * 1000); if (name.empty()) { // // Treat an empty name as a flush request // srvCache.clear(); // // Return false so that it does not break any accidental call to flush with empty name. // A real request to flush wont care about the return value // return false; } recordList.clear(); // // Check if we have something in cache // OSS::Private::DnsSrvPtr cached = srvCache.get(name); if (cached) { recordList = *cached; return !recordList.empty(); } OSS::Private::DNS_RECORD results = 0; DNS_STATUS status = DnsQuery_A(name.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, 0, &results, 0); if (status != 0) return false; // find records matching the correct type OSS::Private::DNS_RECORD dnsRecord = results; while (dnsRecord != 0) { dns_srv_record record; if (!handle_dns_srv_record(dnsRecord, results, record) ) break; recordList.insert(record); dnsRecord = dnsRecord->pNext; } if (results != 0) DnsRecordListFree(results, DnsFreeRecordList); if (!recordList.empty()) { // // cache it // srvCache.add(name, OSS::Private::DnsSrvPtr(new dns_srv_record_list(recordList))); return true; } return !recordList.empty(); }
static int knp_query_resolve_srv_name(char *srv_name, unsigned long *addr_array, unsigned int *port_array, int *nb_addr) { int error; int i, j; int used_addr = 0; PDNS_RECORD record_list = NULL; PDNS_RECORD record; karray srv_array; kmod_log_msg(3, "knp_query_resolve_srv_name() called.\n"); karray_init(&srv_array); /* Try. */ do { /* Ask Windows to resolve that. */ error = DnsQuery_A(srv_name, 33, DNS_QUERY_STANDARD, NULL, &record_list, NULL); if (error) { /* No easy way to get the error string? Screw it! */ kmo_seterror("cannot resolve %s (error %d)", srv_name, error); error = -1; break; } /* We got the data. */ record = record_list; /* Not using constant names since they're not all defined in my * environment. */ while (record) { /* 1 = DNS_TYPE_A. Resolved address. Ignore. We can't depend on it * being set. */ if (record->wType == 1) { /* void */ } /* 33 = DNS_TYPE_SRV. SRV entry. */ else if (record->wType == 33) { karray_add(&srv_array, &record->Data.SRV); } else { kmo_seterror("cannot resolve %s (received unexpected DNS entry of type %d)", srv_name, record->wType); error = -1; break; } record = record->pNext; } if (error) break; if (! srv_array.size) { kmo_seterror("cannot resolve %s: no addresses returned", srv_name); error = -1; break; } /* Sort the SRV array. */ qsort(srv_array.data, srv_array.size, sizeof(void *), (int (*)(const void *, const void *)) srv_entry_sort); /* Resolve each host. */ for (i = 0; i < srv_array.size && used_addr < *nb_addr; i++) { DNS_SRV_DATA *srv = (DNS_SRV_DATA *) srv_array.data[i]; int nb = *nb_addr - used_addr; error = ksock_get_host_addr_list(srv->pNameTarget, addr_array + used_addr, &nb); if (error) { error = 0; continue; } for (j = 0; j < nb; j++) { port_array[used_addr + j] = srv->wPort; } used_addr += nb; } } while (0); /* Great API MS! Keep it up! */ if (record_list) DnsRecordListFree(record_list, DnsFreeRecordList); karray_free(&srv_array); *nb_addr = used_addr; return error; }
static int dns_lookup(nsp_state *N, obj_t *tobj, const char *domain) { #define __FN__ __FILE__ ":dns_lookup()" #ifdef WIN32 DNS_FREE_TYPE freetype; DNS_STATUS status; PDNS_RECORD pDnsRecord; PDNS_RECORD pDnsCur; obj_t *stobj; IN_ADDR ipaddr; char namebuf[8]; register int i; freetype = DnsFreeRecordListDeep; /* status=DnsQuery_A(domain, DNS_TYPE_ANY, DNS_QUERY_STANDARD, NULL, &pDnsRecord, NULL); */ status = DnsQuery_A(domain, DNS_TYPE_ANY, DNS_QUERY_BYPASS_CACHE, NULL, &pDnsRecord, NULL); if (status) { if (N->debug) n_warn(N, __FN__, "res_search failed"); return -1; } /* Loop through the answer buffer and extract records. */ i = 0; pDnsCur = pDnsRecord; while (pDnsCur != NULL) { stobj = nsp_settable(N, tobj, n_ntoa(N, namebuf, i, 10, 0)); switch (pDnsCur->wType) { case DNS_TYPE_A: { ipaddr.S_un.S_addr = (pDnsCur->Data.A.IpAddress); nsp_setstr(N, stobj, "type", "A", -1); nsp_setstr(N, stobj, "host", pDnsCur->pName, -1); nsp_setstr(N, stobj, "addr", inet_ntoa(ipaddr), -1); if (N->debug) n_warn(N, __FN__, "A [%s]", inet_ntoa(ipaddr)); break; } case DNS_TYPE_NS: { nsp_setstr(N, stobj, "type", "NS", -1); /* is PTR the right struct? */ nsp_setstr(N, stobj, "host", pDnsCur->Data.PTR.pNameHost, -1); if (N->debug) n_warn(N, __FN__, "NS [%s]", pDnsCur->Data.PTR.pNameHost); break; } case DNS_TYPE_SOA: { nsp_setstr(N, stobj, "type", "SOA", -1); nsp_setstr(N, stobj, "host", pDnsCur->Data.SOA.pNamePrimaryServer, -1); nsp_setstr(N, stobj, "mail", pDnsCur->Data.SOA.pNameAdministrator, -1); nsp_setnum(N, stobj, "serial", pDnsCur->Data.SOA.dwSerialNo); nsp_setnum(N, stobj, "refresh", pDnsCur->Data.SOA.dwRefresh); nsp_setnum(N, stobj, "retry", pDnsCur->Data.SOA.dwRetry); nsp_setnum(N, stobj, "expire", pDnsCur->Data.SOA.dwExpire); nsp_setnum(N, stobj, "minttl", pDnsCur->Data.SOA.dwDefaultTtl); break; } case DNS_TYPE_PTR: { nsp_setstr(N, stobj, "type", "PTR", -1); nsp_setstr(N, stobj, "host", pDnsCur->Data.PTR.pNameHost, -1); if (N->debug) n_warn(N, __FN__, "PTR [%s]", pDnsCur->Data.PTR.pNameHost); break; } case DNS_TYPE_MX: { nsp_setstr(N, stobj, "type", "MX", -1); nsp_setnum(N, stobj, "pref", pDnsCur->Data.MX.wPreference); nsp_setstr(N, stobj, "host", pDnsCur->Data.MX.pNameExchange, -1); if (N->debug) n_warn(N, __FN__, "MX [%s]", pDnsCur->Data.MX.pNameExchange); break; } default: { /* skip data we're too dumb to parse */ nsp_setnum(N, stobj, "type", pDnsCur->wType); /* if (N->debug) */ n_warn(N, __FN__, "xx[%d]", pDnsCur->wType); break; } } i++; pDnsCur = pDnsCur->pNext; } DnsRecordListFree(pDnsRecord, freetype); return 0; #else char hostbuf[HOSTBUF + 1]; char abuf[20]; char namebuf[8]; querybuf answer; HEADER *hp; int ancount, qdcount; uchar *msg, *eom, *cp; //int type, class, ttl, dlen; int type, dlen; unsigned short pref; register int i; register int n; uchar *e; obj_t *stobj; /* Query the nameserver to retrieve mx records for the given domain. */ n = res_search(domain, C_ANY, T_ANY, (u_char *)&answer, sizeof(answer)); if (n < 0) { if (N->debug) n_warn(N, __FN__, "res_search failed"); return -1; } if (n < HFIXEDSZ) return -1; /* avoid problems after truncation in tcp packets */ if (n > (int)sizeof(answer)) n = (int)sizeof(answer); /* Valid answer received. Skip the query record. */ hp = (HEADER *)&answer; qdcount = ntohs((u_short)hp->qdcount); ancount = ntohs((u_short)hp->ancount); msg = (u_char *)&answer; eom = (u_char *)&answer + n; cp = (u_char *)&answer + HFIXEDSZ; while (qdcount-->0 && cp < eom) { n = dn_skipname(cp, eom); if (n < 0) return -1; cp += n; cp += QFIXEDSZ; } /* Loop through the answer buffer and extract records. */ i = 0; memset(hostbuf, 0, sizeof(hostbuf)); while (ancount-->0 && cp < eom) { stobj = nsp_settable(N, tobj, n_ntoa(N, namebuf, i, 10, 0)); if ((n = dn_expand(msg, eom, cp, hostbuf, HOSTBUF)) < 0) break; if (N->debug) n_warn(N, __FN__, "?[%s]", hostbuf); cp += n; GETSHORT(type, cp); // GETSHORT(class, cp); // GETLONG(ttl, cp); GETSHORT(dlen, cp); e = cp + dlen; switch (type) { case T_A: { snprintf(abuf, sizeof(abuf), "%d.%d.%d.%d", (int)cp[0], (int)cp[1], (int)cp[2], (int)cp[3]); nsp_setstr(N, stobj, "type", "A", -1); nsp_setstr(N, stobj, "host", hostbuf, -1); nsp_setstr(N, stobj, "addr", abuf, -1); if (N->debug) n_warn(N, __FN__, "A [%s]", abuf); cp += dlen; break; } case T_NS: { if ((n = dn_expand(msg, eom, cp, hostbuf, HOSTBUF)) < 0) return -1; cp += n; n = strlen(hostbuf); nsp_setstr(N, stobj, "type", "NS", -1); nsp_setstr(N, stobj, "host", hostbuf, n); if (N->debug) n_warn(N, __FN__, "NS [%s]", hostbuf); break; } case T_SOA: { unsigned int n; nsp_setstr(N, stobj, "type", "SOA", -1); if ((n = dn_expand(msg, eom, cp, hostbuf, HOSTBUF)) < 0) return -1; cp += n; nsp_setstr(N, stobj, "host", hostbuf, -1); if ((n = dn_expand(msg, eom, cp, hostbuf, HOSTBUF)) < 0) return -1; cp += n; nsp_setstr(N, stobj, "mail", hostbuf, -1); GETLONG(n, cp); nsp_setnum(N, stobj, "serial", n); GETLONG(n, cp); nsp_setnum(N, stobj, "refresh", n); GETLONG(n, cp); nsp_setnum(N, stobj, "retry", n); GETLONG(n, cp); nsp_setnum(N, stobj, "expire", n); GETLONG(n, cp); nsp_setnum(N, stobj, "minttl", n); break; } case T_PTR: { if ((n = dn_expand(msg, eom, cp, hostbuf, HOSTBUF)) < 0) return -1; cp += n; n = strlen(hostbuf); nsp_setstr(N, stobj, "type", "PTR", -1); nsp_setstr(N, stobj, "host", hostbuf, n); if (N->debug) n_warn(N, __FN__, "PTR [%s]", hostbuf); break; } case T_MX: { GETSHORT(pref, cp); if ((n = dn_expand(msg, eom, cp, hostbuf, HOSTBUF)) < 0) return -1; cp += n; n = strlen(hostbuf); nsp_setstr(N, stobj, "type", "MX", -1); nsp_setnum(N, stobj, "pref", pref); nsp_setstr(N, stobj, "host", hostbuf, n); if (N->debug) n_warn(N, __FN__, "MX [%s]", hostbuf); break; } default: { /* skip data we're too dumb to parse */ nsp_setnum(N, stobj, "type", type); /* if (N->debug) */ n_warn(N, __FN__, "xx[%d]", type); cp += dlen; break; } } i++; if (cp != e) n_warn(N, __FN__, "SOA[%d %d]", cp, e); cp = e; } #endif return 0; #undef __FN__ }
DNS_RECORDA *DnsQueryA(char *name,IP4_ARRAY *servers) { DNS_STATUS status; WORD type= DNS_TYPE_ANY; DWORD fOptions=DNS_QUERY_BYPASS_CACHE | DNS_QUERY_NO_LOCAL_NAME |DNS_QUERY_NO_HOSTS_FILE | DNS_QUERY_NO_NETBT | DNS_QUERY_TREAT_AS_FQDN; PVOID* reserved=NULL; DNS_RECORDA *records=(PDNS_RECORDA)malloc(sizeof(DNS_RECORDA)); DNS_RECORDA *result; IN_ADDR ipaddr; int i; int count=0; if (!name) { return (NULL); } else { memset(records,'\0',sizeof(DNS_RECORDA)); status = DnsQuery_A( name, //PCWSTR pszName, type, //WORD wType, fOptions, //DWORD fOptions, servers, //PIP4_ARRAY aipServers, (DNS_RECORDA**)&records, //PDNS_RECORD* ppQueryResultsSet, reserved ); //PVOID* pReserved if (status == ERROR_SUCCESS) { fflush(stdout); result=records; do { #ifdef _DBG_ printf("[+] Record %i---\n",count); count++; printf("[+] DNS wDataLength %i\n",result->wDataLength); printf("[+] DNS Flags DW: %x\n",result->Flags.DW); printf("[+] DNS Flags S.Section: %x\n",result->Flags.S.Section); printf("[+] DNS Flags S.Delete: %x\n",result->Flags.S.Delete); printf("[+] DNS Flags S.CharSet: %x\n",result->Flags.S.CharSet); printf("[+] DNS Flags S.Unused: %x\n",result->Flags.S.Unused); printf("[+] DNS Flags S.Reserved: %x\n",result->Flags.S.Reserved); #endif switch (result->wType) { case DNS_TYPE_A: ipaddr.S_un.S_addr = (result->Data.A.IpAddress); printf("[+] Host %s resolved as %s\n", result->pName,inet_ntoa(ipaddr)); break; case DNS_TYPE_NS: printf("[+] Domain %s Dns Servers: %s\n",result->pName,result->Data.Ns.pNameHost); break; case DNS_TYPE_CNAME: printf("[+] Host %s resolved as CNAME %s\n", result->pName,result->Data.Cname.pNameHost); //DnsQueryA(result->Data.Cname.pNameHost,servers); break; case DNS_TYPE_SOA: printf("[+] SOA Information: PrimaryServer: %s\n",result->Data.Soa.pNamePrimaryServer); printf("[+] SOA Information: Administrator: %s\n",result->Data.Soa.pNameAdministrator); printf("[+] SOA Information: SerialNo %x - Refresh %i - retry %i - Expire %i - DefaultTld %i\n", result->Data.Soa.dwSerialNo, result->Data.Soa.dwRefresh, result->Data.Soa.dwRetry, result->Data.Soa.dwExpire, result->Data.Soa.dwDefaultTtl); break; case DNS_TYPE_MX: printf("[+] %s MX Server resolved as %s (Preference %i)\n", result->pName,result->Data.Mx.pNameExchange, result->Data.Mx.wPreference); break; case DNS_TYPE_TEXT: printf("[+] Text: %i bytes\n",result->Data.Txt.dwStringCount); //:? break; case DNS_TYPE_SRV: printf("[+] SRV Record. NameTarget %s ",result->Data.Srv.pNameTarget); printf("(Priority %i - Port %i - Weigth: %i)\n",result->Data.Srv.wPriority,result->Data.Srv.wPort,result->Data.Srv.wWeight); //printf("[+] Resource Pad %i \n",result->Data.Srv.Pad); break; default: printf("[-] DnsQuery returned unknown wtype %x\n",result->wType); break; } result=result->pNext; } while (result!=NULL); } else { if (status==9003) printf("[-] Record not found\n"); else printf("[-] Query Error: %i - %i\n",status,GetLastError()); exit(-1); } } return records; }
int getAFSServer(const char *service, const char *protocol, const char *cellName, unsigned short afsdbPort, /* network byte order */ int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], unsigned short ports[], /* network byte order */ unsigned short ipRanks[], int *numServers, int *ttl) { #ifndef DNSAPI_ENV SOCKET commSock; SOCKADDR_IN sockAddr; PDNS_HDR pDNShdr; char buffer[BUFSIZE]; char query[1024]; int rc; #ifdef DEBUG fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled); #endif *numServers = 0; *ttl = 0; #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */ cm_InitDNS(1); /* assume enabled */ } #endif if (cm_dnsEnabled == 0) { /* possibly we failed in cm_InitDNS above */ fprintf(stderr, "DNS initialization failed, disabled\n"); return -1; } if (service == NULL || protocol == NULL || cellName == NULL) { fprintf(stderr, "invalid input\n"); return -1; } sockAddr = setSockAddr(dns_addr, DNS_PORT); commSock = socket( AF_INET, SOCK_DGRAM, 0 ); if ( commSock < 0 ) { /*afsi_log("socket() failed\n");*/ fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno); return (-1); } StringCbCopyA(query, sizeof(query), cellName); if (query[strlen(query)-1] != '.') { StringCbCatA(query, sizeof(query), "."); } rc = send_DNS_AFSDB_Query(query,commSock,sockAddr, buffer); if (rc < 0) { closesocket(commSock); fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n"); return -1; } pDNShdr = get_DNS_Response(commSock,sockAddr, buffer); /*printReplyBuffer_AFSDB(pDNShdr);*/ if (pDNShdr) processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, ports, ipRanks, numServers, ttl); closesocket(commSock); if (*numServers == 0) return(-1); else return 0; #else /* DNSAPI_ENV */ PDNS_RECORD pDnsCell, pDnsIter, pDnsVol, pDnsVolIter, pDnsCIter; int i; char query[1024]; *numServers = 0; *ttl = 0; if (service == NULL || protocol == NULL || cellName == NULL) return -1; #ifdef AFS_FREELANCE_CLIENT if ( cm_stricmp_utf8N(cellName, "Freelance.Local.Root") == 0 ) return -1; #endif /* AFS_FREELANCE_CLIENT */ /* query the SRV _afs3-vlserver._udp records of cell */ StringCbPrintf(query, sizeof(query), "_%s._%s.%s", service, protocol, cellName); if (query[strlen(query)-1] != '.') { StringCbCatA(query, sizeof(query), "."); } if (DnsQuery_A(query, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pDnsCell, NULL) == ERROR_SUCCESS) { /* go through the returned records */ for (pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) { /* if we find an SRV record, we found the service */ if (pDnsIter->wType == DNS_TYPE_SRV) { StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), pDnsIter->Data.SRV.pNameTarget); ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority; ports[*numServers] = htons(pDnsIter->Data.SRV.wPort); (*numServers)++; if (!*ttl) *ttl = pDnsIter->dwTtl; if (*numServers == AFSMAXCELLHOSTS) break; } } for (i=0;i<*numServers;i++) cellHostAddrs[i] = 0; /* now check if there are any A records in the results */ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { if(pDnsIter->wType == DNS_TYPE_A) /* check if its for one of the service */ for (i=0;i<*numServers;i++) if(cm_stricmp_utf8(pDnsIter->pName, cellHostNames[i]) == 0) cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; } for (i=0;i<*numServers;i++) { /* if we don't have an IP yet, then we should try resolving the afs3-vlserver hostname in a separate query. */ if (!cellHostAddrs[i]) { if (DnsQuery_A(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pDnsVol, NULL) == ERROR_SUCCESS) { for (pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) { /* if we get an A record, keep it */ if (pDnsVolIter->wType == DNS_TYPE_A && cm_stricmp_utf8(cellHostNames[i], pDnsVolIter->pName)==0) { cellHostAddrs[i] = pDnsVolIter->Data.A.IpAddress; break; } /* if we get a CNAME, look for a corresponding A record */ if (pDnsVolIter->wType == DNS_TYPE_CNAME && cm_stricmp_utf8(cellHostNames[i], pDnsVolIter->pName)==0) { for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) { if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf8(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) { cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress; break; } } if (cellHostAddrs[i]) break; /* TODO: if the additional section is missing, then do another lookup for the CNAME */ } } /* we are done with the service lookup */ DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep); } } } DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep); } else { /* query the AFSDB records of cell */ StringCbCopyA(query, sizeof(query), cellName); if (query[strlen(query)-1] != '.') { StringCbCatA(query, sizeof(query), "."); } if (DnsQuery_A(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, &pDnsCell, NULL) == ERROR_SUCCESS) { /* go through the returned records */ for (pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) { /* if we find an AFSDB record with Preference set to 1, we found a service instance */ if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) { StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), pDnsIter->Data.Afsdb.pNameExchange); ipRanks[*numServers] = 0; ports[*numServers] = afsdbPort; (*numServers)++; if (!*ttl) *ttl = pDnsIter->dwTtl; if (*numServers == AFSMAXCELLHOSTS) break; } } for (i=0;i<*numServers;i++) cellHostAddrs[i] = 0; /* now check if there are any A records in the results */ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { if(pDnsIter->wType == DNS_TYPE_A) /* check if its for one of the service */ for (i=0;i<*numServers;i++) if(cm_stricmp_utf8(pDnsIter->pName, cellHostNames[i]) == 0) cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; } for (i=0;i<*numServers;i++) { /* if we don't have an IP yet, then we should try resolving the service hostname in a separate query. */ if (!cellHostAddrs[i]) { if (DnsQuery_A(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pDnsVol, NULL) == ERROR_SUCCESS) { for (pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) { /* if we get an A record, keep it */ if (pDnsVolIter->wType == DNS_TYPE_A && cm_stricmp_utf8(cellHostNames[i], pDnsVolIter->pName)==0) { cellHostAddrs[i] = pDnsVolIter->Data.A.IpAddress; break; } /* if we get a CNAME, look for a corresponding A record */ if (pDnsVolIter->wType == DNS_TYPE_CNAME && cm_stricmp_utf8(cellHostNames[i], pDnsVolIter->pName)==0) { for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) { if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf8(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) { cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress; break; } } if (cellHostAddrs[i]) break; /* TODO: if the additional section is missing, then do another lookup for the CNAME */ } } /* we are done with the service lookup */ DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep); } } } DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep); } } if ( *numServers > 0 ) return 0; else return -1; #endif /* DNSAPI_ENV */ }