DnsQuery 함수를 사용하여 Visual C++ .NET으로 호스트 이름 및 호스트 주소 확인

  • 아티클
  • 2023. 07. 17.
  •  

이 문서의 내용

  1. DnsQuery 함수를 사용하는 방법을 보여 주는 샘플 Win32 콘솔 애플리케이션 만들기
  2. 샘플 테스트
  3. 참조

이 문서에서는 함수를 사용하여 DnsQuery 호스트 이름 및 호스트 IP를 확인하는 방법을 보여 주는 Win32 콘솔 애플리케이션 샘플을 제공합니다.

원래 제품 버전: Winsock
원래 KB 번호: 831226

DnsQuery 함수를 사용하는 방법을 보여 주는 샘플 Win32 콘솔 애플리케이션 만들기

Winsock에서 함수 대신 함수를 사용하여 getaddrinfo 애플리케이션에서 getaddrbyname 이름을 호스트합니다. 함수가 getaddrbyname IPv4 및 IPv6 주소 지정을 처리하는 함수로 대체 getaddrinfo 되었습니다.

Winsock은 최신 버전의 getaddrinfo 함수가 포함된 Windows Server 2003에서 최근까지 와이드 문자를 고려하지 않았습니다. 새 버전의 이름은 GetAddrInfo입니다. 모든 NT 기반 운영 체제에 대한 솔루션이 필요한 경우 DNS 클라이언트 DNSQuery 함수를 사용하여 호스트 이름을 확인합니다. 이 DNSQuery 함수에는 Microsoft Windows 2000 이상 운영 체제에서 작동해야 하는 광범위한 버전이 있습니다.

다음 단계를 사용하여 함수를 사용하는 방법을 보여 주는 샘플 Win32 콘솔 애플리케이션을 DnsQuery 만듭니다. 이 함수는 DnsQuery DNS 서버에 쿼리를 전송하여 호스트 이름을 IP 주소로 확인하고 그 반대의 경우도 마찬가지입니다.

  1. Microsoft Visual Studio .NET을 시작합니다.
  2. 프로젝트 형식에서 Visual C++ 프로젝트를 클릭한 다음 템플릿 아래에서 Win32 프로젝트를 클릭합니다.
  3. 이름 상자에 Q831226을 입력합니다.
  4. Win32 애플리케이션 마법사에서 콘솔 애플리케이션을 클릭하고 빈 프로젝트를 클릭한 다음 마침을 클릭합니다.
  5. 솔루션 탐색기 원본 파일을 마우스 오른쪽 단추로 클릭하고 추가를 클릭한 다음 새 항목 추가를 클릭합니다. 프로젝트에 C++ 파일(.cpp)을 추가합니다. 파일 이름을 Q831226.cpp로 지정합니다.
  6. Q831226.cpp 파일에 다음 코드를 붙여넣습니다.
  7. C++
  1. #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);
    }
    
  2. 프로젝트 메뉴에서 [속성]을 클릭합니다.
  3. 프로젝트 속성 대화 상자에서 구성 속성 아래에서 링커를 확장하고 명령줄을 클릭한 다음 추가 옵션 상자에 다음 라이브러리를 추가합니다.
    • Ws2_32.lib
    • Dnsapi.lib
  4. Ctrl+Shift+B를 눌러 솔루션을 빌드합니다.

샘플 테스트

  • 호스트 이름에 해당하는 IP 주소를 찾습니다. Q831226.exe -n <hostname> -t A -s <IP address of DNS server>
  • 참고
  • hostname 은 쿼리 중인 컴퓨터 이름의 자리 표시자입니다.
  • IP 주소에 해당하는 호스트 이름을 찾습니다. Q831226.exe -n <xxx.xxx.xxx.xxx> -t PTR -s <IP address of DNS server>
  • 참고
  • xxx.xxx.xxx.xxx 쿼리 중인 컴퓨터의 IP 주소 자리 표시자입니다.

참조

DNS 조회에 대한 자세한 내용은 DnsQuery_A 함수를 참조하세요.

 
 
Posted by gurupia
,