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.
Uruchom program Microsoft Visual Studio .NET.
W obszarze Typy projektów kliknij pozycję Projekty Visual C++, a następnie kliknij pozycję Projekt Win32 w obszarze Szablony.
Wpisz Q831226 w polu Nazwa .
W kreatorze aplikacji Win32 kliknij pozycję Aplikacja konsola, kliknij pozycję Pusty projekt, a następnie kliknij przycisk Zakończ.
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.
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); }
W menu Projekt kliknij pozycję Właściwości.
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
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.