Use the DnsQuery function to resolve host names and host addresses with Visual C++ .NET
This article provides a Win32 console application sample that illustrates how to use the DnsQuery
function to resolve host names and host IP.
Original product version: Winsock
Original KB number: 831226
Create a sample Win32 console application that illustrates how to use the DnsQuery function
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:
#include <winsock2.h> //winsock #include <windns.h> //DNS api's #include <stdio.h> //standard i/o //Usage of the program void Usage(char *progname) { fprintf(stderr,"Usage\n%s -n [HostName|IP Address] -t [Type] -s [DnsServerIp]\n",progname); fprintf(stderr,"Where:\n\t\"HostName|IP Address\" is the name or IP address of the computer "); fprintf(stderr,"of the record set being queried\n"); fprintf(stderr,"\t\"Type\" is the type of record set to be queried A or PTR\n"); fprintf(stderr,"\t\"DnsServerIp\"is the IP address of DNS server (in dotted decimal notation)"); fprintf(stderr,"to which the query should be sent\n"); exit(1); } void ReverseIP(char* pIP) { char seps[] = "."; char *token; char pIPSec[4][4]; int i=0; token = strtok( pIP, seps); while( token != NULL ) { /* While there are "." characters in "string"*/ sprintf(pIPSec[i],"%s", token); /* Get next "." character: */ token = strtok( NULL, seps ); i++; } sprintf(pIP,"%s.%s.%s.%s.%s", pIPSec[3],pIPSec[2],pIPSec[1],pIPSec[0],"IN-ADDR.ARPA"); } // 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], "A")) wType = DNS_TYPE_A; //Query host records to resolve a name. else if (!stricmp(argv[i + 1], "PTR")) { //pOwnerName should be in "xxx.xxx.xxx.xxx" format if (strlen(pOwnerName) <= 15) { //You must reverse the IP address to request a Reverse Lookup //of a host name. sprintf(pReversedIP, "%s", 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("Memory allocation failed \n"); 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("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); }
On the Project menu, click Properties.
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:
- Ws2_32.lib
- Dnsapi.lib
Press Ctrl+Shift+B to build the solution.
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
hostname 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
xxx.xxx.xxx.xxx is a placeholder of the IP address of the computer that is being queried.
References
For more information about DNS lookup, see: DnsQuery_A function.