Utiliser la fonction DnsQuery pour résoudre les noms d’hôte et les adresses d’hôte avec Visual C++ .NET

Cet article fournit un exemple d’application console Win32 qui montre comment utiliser la fonction pour résoudre les DnsQuery noms d’hôte et l’adresse IP de l’hôte.

Version d’origine du produit : Winsock
Numéro de la base de connaissances d’origine : 831226

Créer un exemple d’application console Win32 qui illustre l’utilisation de la fonction DnsQuery

Dans Winsock, utilisez la getaddrinfo fonction au lieu de la getaddrbyname fonction pour héberger des noms dans votre application. La getaddrbyname fonction a été remplacée par la fonction pour gérer l’adressage getaddrinfo IPv4 et IPv6.

Winsock n’a jamais pris en compte les caractères larges jusqu’à récemment dans Windows Server 2003 où une nouvelle version de la getaddrinfo fonction est incluse. La nouvelle version est nommée GetAddrInfo. Si vous avez besoin d’une solution pour tous les systèmes d’exploitation NT, utilisez la fonction DNSQuery du client DNS pour résoudre les noms d’hôte. La DNSQuery fonction a une version large qui doit fonctionner sur les systèmes d’exploitation Microsoft Windows 2000 et versions ultérieures.

Procédez comme suit pour créer un exemple d’application console Win32 qui illustre l’utilisation de la DnsQuery fonction . La DnsQuery fonction envoie une requête à un serveur DNS pour résoudre le nom d’hôte en adresse IP et vice versa.

  1. Démarrez Microsoft Visual Studio .NET.

  2. Sous Types de projets, cliquez sur Projets Visual C++, puis sur Projet Win32 sous Modèles.

  3. Tapez Q831226 dans la zone Nom .

  4. Dans l’Assistant Application Win32, cliquez sur Application console, sur Projet vide, puis sur Terminer.

  5. Dans Explorateur de solutions, cliquez avec le bouton droit sur Fichiers sources, cliquez sur Ajouter, puis cliquez sur Ajouter un nouvel élément. Ajoutez un fichier C++ (.cpp) au projet. Nommez le fichier Q831226.cpp.

  6. Collez le code suivant dans le fichier 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. Dans le menu Projet , cliquez sur Propriétés.

  8. Dans la boîte de dialogue Propriétés du projet , développez Éditeur de liens sous Propriétés de configuration, cliquez sur Ligne de commande, puis ajoutez les bibliothèques suivantes à la zone Options supplémentaires :

    • Ws2_32.lib
    • Dnsapi.lib
  9. Appuyez sur Ctrl+Maj+B pour générer la solution.

Tester l’exemple

  • Recherchez l’adresse IP qui correspond au nom d’hôte : Q831226.exe -n <hostname> -t A -s <IP address of DNS server>

    Remarque

    hostname est l’espace réservé du nom de l’ordinateur interrogé.

  • Recherchez le nom d’hôte qui correspond à l’adresse IP : Q831226.exe -n <xxx.xxx.xxx.xxx> -t PTR -s <IP address of DNS server>

    Remarque

    xxx.xxx.xxx.xxx est un espace réservé de l’adresse IP de l’ordinateur interrogé.

References

Pour plus d’informations sur la recherche DNS, consultez : fonction DnsQuery_A.