DnsQueryEx with custom interfaceIndex is not working

Dima 6 Reputation points
2022-04-21T10:57:53.487+00:00

Hello everybody.

I need to perform a DNS lookup using a specified adapter.

I've discovered that for DnsQueryEx I can specify adapterIndex using field in DNS_QUERY_REQUEST struct. The documentations says:
"A value that contains the interface index over which the query is sent. If InterfaceIndex is 0, all interfaces will be considered."

But in fact when I set InterfaceIndex to anything except 0, the API returns an error code 87 ("The parameter is incorrect"). Does it mean that the API doesn't support the ability to set the interface index and I have too search for another solution?

Thank you in advance

Dima

Windows development Windows API - Win32
{count} vote

2 answers

Sort by: Most helpful
  1. Castorix31 90,521 Reputation points
    2022-04-21T12:35:18.367+00:00

    when I set InterfaceIndex to anything except 0, the API returns an error code 87 (

    You must set an index of a valid adaper (one of the list returned by GetInterfaceInfo for example)
    (tested on Windows 10 21H1)
    On my PC, I have indexes : 13, 3, 22, 6, 14, 10, 16, 27 and only 3 is valid (Ethernet)


  2. Junjie Zhu - MSFT 21,646 Reputation points
    2022-04-27T09:40:01.69+00:00

    Hello,
    Welcome to Microsoft Q&A!
    I used your code to test, and there is no ERROR_SUCCESS. Do you run it with administrator privileges? Below is my full test code.

    #define WIN32_LEAN_AND_MEAN  
      
    #include <windows.h>  
      
    #include <WinDNS.h>  
    #include <iphlpapi.h>  
    #include <iostream>  
    #include <stdio.h>  
    #include <tchar.h>  
    #include <winsock2.h>  
      
    static DNS_QUERY_RESULT result = { 0 };  
    static DNS_QUERY_CANCEL cancel = { 0 };  
      
    #pragma comment (lib,"Dnsapi.lib")  
    #pragma comment (lib,"Ws2_32.lib")  
    #pragma comment (lib,"Iphlpapi.lib")  
      
    int _tmain(int argc, _TCHAR* argv[])  
    {  
     WSADATA wsaData = { 0 };  
     ::WSAStartup(MAKEWORD(2, 2), &wsaData);  
     DNS_QUERY_REQUEST rq{};  
     DNS_QUERY_RESULT rslt{};  
     DNS_ADDR_ARRAY dns{};  
     dns.MaxCount = sizeof(dns);  
     dns.AddrCount = 1;  
     dns.Family = AF_INET;  
     int length = sizeof(dns.AddrArray[0].MaxSa);  
      
     wchar_t lpWStr[32] = { 0 };  
     wsprintfW(lpWStr, L"8.8.8.8");  
      
     WSAStringToAddressW(lpWStr, AF_INET, nullptr, (sockaddr*)& dns.AddrArray[0].MaxSa[0], &length);  
      
     rq.Version = 1;  
     rq.QueryName = L"google.com";  
     rq.QueryType = DNS_TYPE_A;  
     rq.QueryOptions = DNS_QUERY_STANDARD;  
     rq.pDnsServerList = &dns;  
     rslt.Version = 1;  
     //Just big enough buffer.  
     char buf[2000];  
     ULONG len = 2000;  
     GetInterfaceInfo((PIP_INTERFACE_INFO)& buf[0], &len);  
     auto interface_info = (PIP_INTERFACE_INFO)& buf[0];  
     for (int i = 0; i < interface_info->NumAdapters; ++i)  
     {  
     rq.InterfaceIndex = interface_info->Adapter[i].Index;  
     DNS_STATUS status = DnsQueryEx(&rq, &rslt, nullptr /*pCancelHandle*/);  
     if (status != ERROR_INVALID_PARAMETER)  
     {  
     std::cout << "ERROR_SUCCESS";  
     }  
     }  
     rq.InterfaceIndex = 0;  
     DNS_STATUS status = DnsQueryEx(&rq, &rslt, nullptr /*pCancelHandle*/);  
      
      
     if (status == ERROR_SUCCESS)  
     {  
     std::cout << "everything works with 0";  
     }  
     else  
     {  
      
     std::cout << "Version:" <<rslt.Version << std::endl;  
     std::cout << "QueryStatus:" << rslt.QueryStatus << std::endl;  
     std::cout << "QueryOptions:" << rslt.QueryOptions << std::endl;  
     std::cout << "pQueryRecords:" << rslt.pQueryRecords << std::endl;  
      
     }  
    }  
    

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.