Microsoft KB Archive/831226

= How to use the DnsQuery function to resolve host names and host addresses with Visual C++ .NET =

Article ID: 831226

Article Last Modified on 1/22/2007

-

APPLIES TO


 * Microsoft Windows 2000 Standard Edition
 * Microsoft Windows XP Professional
 * Microsoft Windows XP Home Edition
 * Microsoft Windows Server 2003, Datacenter Edition (32-bit x86)
 * Microsoft Windows Server 2003, Enterprise Edition (32-bit x86)
 * Microsoft Windows Server 2003, Standard Edition (32-bit x86)

-





INTRODUCTION
This article describes how to use the DNSQuery function to resolve host names and host IP addresses.



MORE INFORMATION
In Winsock, use the getaddrinfo function instead of the getaddrbyname function to host names in your application. The getaddrbyname function was replaced by the getaddrinfo function to handle IPv4 and IPv6 addressing.

Winsock never accounted for wide characters until recently in Windows Server 2003 where a new version of the getaddrinfo function is included. The new version is named GetAddrInfo. If you need a solution for all NT-based operating systems, use the DNS client DNSQuery function to resolve host names. The DNSQuery function has a wide version that should work on Microsoft Windows 2000 and later operating systems.

Use the following steps to create a sample Win32 console application that illustrates how to use the DnsQuery function. The DnsQuery function sends a query to a DNS server to resolve the host name to an IP address and vice-versa.  Start Microsoft Visual Studio .NET. Under Project Types, click Visual C++ Projects, and then click Win32 Project under Templates. Type Q831226 in the Name box. In the Win32 Application wizard, click Console Application, click Empty project, and then click Finish. In Solution Explorer, right-click Source Files, click Add, and then click Add New Item. Add a C++ file (.cpp) to the project. Name the file Q831226.cpp.  Paste the following code in the Q831226.cpp file:
 * 1) include  //winsock
 * 2) include <windns.h>  //DNS api's
 * 3) include <stdio.h>   //standard i/o

//Usage of the program void Usage(char *progname) { fprintf(stderr,&quot;Usage\n%s -n [HostName|IP Address] -t [Type] -s [DnsServerIp]\n&quot;,progname); fprintf(stderr,&quot;Where:\n\t\&quot;HostName|IP Address\&quot; is the name or IP address of the computer &quot;); fprintf(stderr,&quot;of the record set being queried\n&quot;); fprintf(stderr,&quot;\t\&quot;Type\&quot; is the type of record set to be queried A or PTR\n&quot;); fprintf(stderr,&quot;\t\&quot;DnsServerIp\&quot;is the IP address of DNS server (in dotted decimal notation) &quot;); fprintf(stderr,&quot;to which the query should be sent\n&quot;); exit(1); }

void ReverseIP(char* pIP) {   char seps[]   = &quot;.&quot;; char *token; char pIPSec[4][4]; int i=0; token = strtok( pIP, seps); while( token != NULL ) {       /* While there are &quot;.&quot; characters in &quot;string&quot; */ sprintf(pIPSec[i],&quot;%s&quot;, token); /* Get next &quot;.&quot; character: */ token = strtok( NULL, seps ); i++; }   sprintf(pIP,&quot;%s.%s.%s.%s.%s&quot;, pIPSec[3],pIPSec[2],pIPSec[1],pIPSec[0],&quot;IN-ADDR.ARPA&quot;); }

// 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;     //Pointer to IP4_ARRAY structure. WORD wType;                     //Type of the record to be queried. char* pOwnerName;       //Owner name to be queried. char pReversedIP[255];     //Reversed IP address. char DnsServIp[255];            //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], &quot;A&quot;) ) wType = DNS_TYPE_A; //Query host records to resolve a name. else if (!stricmp(argv[i+1], &quot;PTR&quot;) ) {                           //pOwnerName should be in &quot;xxx.xxx.xxx.xxx&quot; format if(strlen(pOwnerName)<=15) {                               //You must reverse the IP address to request a Reverse Lookup //of a host name. sprintf(pReversedIP,&quot;%s&quot;,pOwnerName); ReverseIP(pReversedIP); pOwnerName=pReversedIP; wType = DNS_TYPE_PTR; //Query PTR records to resolve an IP address }                           else {                               Usage(argv[0]); }                       }                        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(&quot;Memory allocation failed \n&quot;); exit(1); }                       if(argv[++i]) { strcpy(DnsServIp,argv[i]); pSrvList->AddrCount = 1; pSrvList->AddrArray[0] = inet_addr(DnsServIp); //DNS server IP address break; }                   default: Usage(argv[0]); break; }           }            else Usage(argv[0]); }      }    else Usage(argv[0]); // Calling function DnsQuery to query Host or PTR records status = DnsQuery(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 that contains the response.                        NULL);                     //Reserved for future use.

if (status){ if(wType == DNS_TYPE_A) printf(&quot;Failed to query the host record for %s and the error is %d \n&quot;, pOwnerName, status); else printf(&quot;Failed to query the PTR record and the error is %d \n&quot;, 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(&quot;The IP address of the host %s is %s \n&quot;, pOwnerName,inet_ntoa(ipaddr));

// Free memory allocated for DNS records. DnsRecordListFree(pDnsRecord, freetype); }       else { printf(&quot;The host name is %s \n&quot;,(pDnsRecord->Data.PTR.pNameHost));

// Free memory allocated for DNS records. DnsRecordListFree(pDnsRecord, freetype); }   }    LocalFree(pSrvList); } </li> On the Project menu, click Properties.</li> In the Project Properties dialog box, expand Linker under Configuration Properties, click Command Line, and then add the following libraries to the Additional Options box: <ul> Ws2_32.lib</li> Dnsapi.lib</li></ul> </li> Press Ctrl+Shift+B to build the solution.</li></ol>

Test the sample

 * Find the IP address that corresponds to the host name:

Q831226.exe -n hostname -t A -s <IP address of DNS server>

Note  is the placeholder of the name of the computer that is being queried.
 * Find the host name that corresponds to the IP address:

Q831226.exe -n xxx.xxx.xxx.xxx -t PTR -s <IP address of DNS server>

Note  is a placeholder of the IP address of the computer that is being queried.

<div class="references_section">