DnsQuery 関数を使用して、Visual C++ .NET でホスト名とホスト アドレスを解決する

この記事では、関数を使用 DnsQuery してホスト名とホスト IP を解決する方法を示す Win32 コンソール アプリケーション サンプルを提供します。

元の製品バージョン: Winsock
元の KB 番号: 831226

DnsQuery 関数の使用方法を示すサンプル Win32 コンソール アプリケーションを作成する

Winsock で、 関数の代わりに 関数をgetaddrinfogetaddrbyname使用して、アプリケーションで名前をホストします。 関数は getaddrbyname 、IPv4 と IPv6 のアドレス指定を処理する関数に置き換えられました getaddrinfo

Winsock は、Windows Server 2003 の最近まで、関数の新しいバージョンが含まれるワイド文字を getaddrinfo 考慮しませんでした。 新しいバージョンの名前は 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 ファイルに次のコードを貼り付けます。

    #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. [ プロジェクト ] メニューの [ プロパティ] をクリックします。

  8. [プロジェクトのプロパティ] ダイアログ ボックスで、[構成プロパティ] の下の [リンカー] を展開し、[コマンド ライン] をクリックし、[追加オプション] ボックスに次のライブラリを追加します。

    • Ws2_32.lib
    • Dnsapi.lib
  9. 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関数」を参照してください。