Używanie funkcji DnsQuery do rozpoznawania nazw hostów i adresów hostów za pomocą programu Visual C++ .NET

Ten artykuł zawiera przykład aplikacji konsolowej Win32, który ilustruje, jak używać DnsQuery funkcji do rozpoznawania nazw hostów i adresu IP hosta.

Oryginalna wersja produktu: Winsock
Oryginalny numer KB: 831226

Tworzenie przykładowej aplikacji konsolowej Win32, która ilustruje sposób używania funkcji DnsQuery

W usłudze Winsock użyj getaddrinfo funkcji zamiast getaddrbyname funkcji do hostowania nazw w aplikacji. Funkcja getaddrbyname została zastąpiona przez funkcję getaddrinfo do obsługi adresowania IPv4 i IPv6.

Winsock nigdy nie uwzględniał szerokich getaddrinfo znaków do niedawna w systemie Windows Server 2003, gdzie jest dołączona nowa wersja funkcji. Nowa wersja nosi nazwę GetAddrInfo. Jeśli potrzebujesz rozwiązania dla wszystkich systemów operacyjnych opartych na systemie NT, użyj funkcji DNSQuery klienta DNS, aby rozpoznać nazwy hostów. Funkcja DNSQuery ma szeroką wersję, która powinna działać w systemach operacyjnych Microsoft Windows 2000 i nowszych.

Wykonaj poniższe kroki, aby utworzyć przykładową aplikację konsolową Win32, która ilustruje sposób korzystania z DnsQuery funkcji. Funkcja DnsQuery wysyła zapytanie do serwera DNS w celu rozpoznania nazwy hosta na adres IP i na odwrót.

  1. Uruchom program Microsoft Visual Studio .NET.

  2. W obszarze Typy projektów kliknij pozycję Projekty Visual C++, a następnie kliknij pozycję Projekt Win32 w obszarze Szablony.

  3. Wpisz Q831226 w polu Nazwa .

  4. W kreatorze aplikacji Win32 kliknij pozycję Aplikacja konsola, kliknij pozycję Pusty projekt, a następnie kliknij przycisk Zakończ.

  5. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję Pliki źródłowe, kliknij przycisk Dodaj, a następnie kliknij pozycję Dodaj nowy element. Dodaj plik C++ (.cpp) do projektu. Nadaj plikowi nazwę Q831226.cpp.

  6. Wklej następujący kod w pliku Q831226.cpp :

    #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. W menu Projekt kliknij pozycję Właściwości.

  8. W oknie dialogowym Właściwości projektu rozwiń węzeł Konsolidator w obszarze Właściwości konfiguracji, kliknij pozycję Wiersz polecenia, a następnie dodaj następujące biblioteki do pola Opcje dodatkowe :

    • Ws2_32.lib
    • Dnsapi.lib
  9. Naciśnij klawisze Ctrl+Shift+B, aby skompilować rozwiązanie.

Testowanie przykładu

  • Znajdź adres IP odpowiadający nazwie hosta: Q831226.exe -n <hostname> -t A -s <IP address of DNS server>

    Uwaga

    nazwa hosta jest symbolem zastępczym nazwy komputera, którego dotyczy zapytanie.

  • Znajdź nazwę hosta odpowiadającą adresowi IP: Q831226.exe -n <xxx.xxx.xxx.xxx> -t PTR -s <IP address of DNS server>

    Uwaga

    xxx.xxx.xxx.xxx jest symbolem zastępczym adresu IP komputera, na który jest wykonywane zapytanie.

Informacje

Aby uzyskać więcej informacji na temat wyszukiwania DNS, zobacz: funkcja DnsQuery_A.