Microsoft KB Archive/831226

From BetaArchive Wiki
Knowledge Base


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.

  1. Start Microsoft Visual Studio .NET.
  2. Under Project Types, click Visual C++ Projects, and then click Win32 Project under Templates.
  3. Type Q831226 in the Name box.
  4. In the Win32 Application wizard, click Console Application, click Empty project, and then click Finish.
  5. 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.
  6. 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);
    }
  7. On the Project menu, click Properties.
  8. 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
  9. 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, visit the following Microsoft Developer Network (MSDN) Web site:

For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

164213 Description of DNS Reverse Lookups



Additional query words: getaddrinfo dnsquery ip query dns unicode

Keywords: kbcode kbdns kbnetwork kbsdk kbhowto KB831226