Verwenden der DnsQuery-Funktion zum Auflösen von Hostnamen und Hostadressen mit Visual C++ .NET


EINFÜHRUNG


In diesem Artikel wird beschrieben, wie Sie die DNSQuery-Funktion verwenden, um Hostnamen und Host-IP-Adressen aufzulösen.

Weitere Informationen


Verwenden Sie in Winsock die getaddrinfo-Funktion anstelle der getaddrbyname-Funktion, um Namen in Ihrer Anwendung zu hosten. Die getaddrbyname-Funktion wurde durch die getaddrinfo-Funktion ersetzt, um IPv4- und IPv6-Adressierung zu verarbeiten. Winsock hat bis vor kurzem in Windows Server 2003, wo eine neue Version der getaddrinfo-Funktion enthalten ist, keine großen Zeichen berücksichtigt. Die neue Version heißt GetAddrInfo. Wenn Sie eine Lösung für alle NT-basierten Betriebssysteme benötigen, verwenden Sie die DNS-Client-DNSQuery-Funktion, um Hostnamen aufzulösen. Die DNSQuery-Funktion verfügt über eine breite Version, die auf Microsoft Windows 2000 und neueren Betriebssystemen funktionieren sollte. Führen Sie die folgenden Schritte aus, um eine Win32-Konsolenanwendungsbeispiel zu erstellen, die veranschaulicht, wie die DnsQuery-Funktion verwendet wird. Die DnsQuery-Funktion sendet eine Abfrage an einen DNS-Server, um den Hostnamen in eine IP-Adresse aufzulösen und umgekehrt.
  1. Starten Sie Microsoft Visual Studio .NET.
  2. Klicken Sie unter Projekttypenauf Visual C++-Projekte, und klicken Sie dann unterVorlagenauf Win32-Projekt .
  3. Geben Sie Q831226 in das FeldName ein.
  4. Klicken Sie im Win32-Anwendungsassistenten auf Konsolenanwendung, klicken Sie auf Projektleeren , und klicken Sie dann aufFertig stellen.
  5. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Quelldateien, klicken Sie auf Hinzufügen, und klicken Sie dann auf Neues Element hinzufügen. Fügen Sie dem Projekt eine C++-Datei (.cpp) hinzu. Benennen Sie die Datei Q831226.cpp.
  6. Fügen Sie den folgenden Code in die Datei Q831226.cpp ein:
    #include <winsock2.h>  //winsock#include <windns.h>   //DNS api's#include <stdio.h>    //standard i/o//Usage of the programvoid 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. Klicken Sie im Menü Projekt auf Eigenschaften.
  8. Erweitern Sie Linker im Dialogfeld Projekteigenschaften unter Konfigurationseigenschaften, klicken Sie auf Befehlszeile, und fügen Sie dann die folgenden Bibliotheken zum Feld Zusätzliche Optionen hinzu:
    • Ws2_32.lib
    • Dnsapi.lib
  9. Drücken Sie Strg+Umschalt+B, um die Lösung zu erstellen.

Testen der Probe

  • Suchen Sie die IP-Adresse, die dem Hostnamen entspricht:Q831226.exe -n Hostname -t A -s <IP-Adresse des DNS-Servers>Hinweis Hostname ist der Platzhalter des Namens des Computers, der abgefragt wird.
  • Suchen Sie den Hostnamen, der der IP-Adresse entspricht:Q831226.exe -n xxx.xxx.xxx.xxx -t PTR -s <IP-Adresse des DNS-Servers>Hinweis xxx.xxx.xxx.xxx ist ein Platzhalter der IP-Adresse des Computers, der abgefragt wird.

Informationsquellen


Weitere Informationen zur DNS-Suche finden Sie auf der folgenden MSDN-Website (Microsoft Developer Network):Weitere Informationen finden Sie im folgenden Artikel der Microsoft Knowledge Base:
164213 Beschreibung der DNS-Reverse-Lookups