VB6查找主机名从IP,指定DNS服务器

时间:2010-02-06 23:39:02

标签: winapi vb6 dns ip-address

我知道如何使用GetHostByAddr Windows API调用从VB中的IPv4查找主机名(this效果很好)。但是,该功能不允许指定要使用的DNS服务器。有时默认的公司DNS服务器很好,但有时我需要指定一个外部DNS服务器进行查找,我不认为做一个shell nslookup并解析输出是最好的方法,在这里。

注意:这实际上将在Excel工作簿中用作VBA代码,以帮助其他人完成他的工作,当他需要一些简单的功能时,不值得编写大型应用程序。

想到我可能在API调用getnameinfo中找到了答案,但仔细阅读似乎表明它没有提供servername参数。

经过一番激烈的搜索后,我找到了reference to the pExtra parameter to the DNSQuery function。但我甚至不知道如何在VB6中使用它。

任何人都可以帮助我从VB6进行DNS查找,指定要使用的服务器名吗?

一个完整的解决方案当然会很好,但我愿意工作:只需指出正确的方向。

更新:由于一些奇怪的原因,它没有点击DNSQuery是一个Windows API调用。它听起来不像是一个。如果我收集了一个小细节,我当然能够在问题上取得更多进展。

3 个答案:

答案 0 :(得分:4)

试试这个:

Option Explicit

Private Declare Function DnsQuery Lib "dnsapi" Alias "DnsQuery_A" (ByVal strname As String, ByVal wType As Integer, ByVal fOptions As Long, ByVal pServers As Long, ppQueryResultsSet As Long, ByVal pReserved As Long) As Long
Private Declare Function DnsRecordListFree Lib "dnsapi" (ByVal pDnsRecord As Long, ByVal FreeType As Long) As Long
Private Declare Function lstrlen Lib "kernel32" (ByVal straddress As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)
Private Declare Function inet_ntoa Lib "ws2_32.dll" (ByVal pIP As Long) As Long
Private Declare Function inet_addr Lib "ws2_32.dll" (ByVal sAddr As String) As Long

Private Const DnsFreeRecordList         As Long = 1
Private Const DNS_TYPE_A                As Long = &H1
Private Const DNS_QUERY_BYPASS_CACHE    As Long = &H8

Private Type VBDnsRecord
    pNext           As Long
    pName           As Long
    wType           As Integer
    wDataLength     As Integer
    flags           As Long
    dwTel           As Long
    dwReserved      As Long
    prt             As Long
    others(35)      As Byte
End Type

Private Sub Command1_Click()
    MsgBox Resolve("google.com", "208.67.222.222")
End Sub

Private Function Resolve(sAddr As String, Optional sDnsServers As String) As String
    Dim pRecord     As Long
    Dim pNext       As Long
    Dim uRecord     As VBDnsRecord
    Dim lPtr        As Long
    Dim vSplit      As Variant
    Dim laServers() As Long
    Dim pServers    As Long
    Dim sName       As String

    If LenB(sDnsServers) <> 0 Then
        vSplit = Split(sDnsServers)
        ReDim laServers(0 To UBound(vSplit) + 1)
        laServers(0) = UBound(laServers)
        For lPtr = 0 To UBound(vSplit)
            laServers(lPtr + 1) = inet_addr(vSplit(lPtr))
        Next
        pServers = VarPtr(laServers(0))
    End If
    If DnsQuery(sAddr, DNS_TYPE_A, DNS_QUERY_BYPASS_CACHE, pServers, pRecord, 0) = 0 Then
        pNext = pRecord
        Do While pNext <> 0
            Call CopyMemory(uRecord, pNext, Len(uRecord))
            If uRecord.wType = DNS_TYPE_A Then
                lPtr = inet_ntoa(uRecord.prt)
                sName = String(lstrlen(lPtr), 0)
                Call CopyMemory(ByVal sName, lPtr, Len(sName))
                If LenB(Resolve) <> 0 Then
                    Resolve = Resolve & " "
                End If
                Resolve = Resolve & sName
            End If
            pNext = uRecord.pNext
        Loop
        Call DnsRecordListFree(pRecord, DnsFreeRecordList)
    End If
End Function

答案 1 :(得分:0)

您可以使用DNS WMI提供程序设置系统的DNS,然后使用GetHostByAddr

答案 2 :(得分:0)

对于wqw post来说,这不是答案,而是非常重要的注意事项:

lstrlen功能上的

Security Warning(第5行和第55行):

  

错误地使用此功能可能会损害您的安全性   应用即可。 lstrlen假设lpString是以null结尾的   字符串,或NULL。如果不是,则可能导致缓冲区溢出或   对您的申请进行拒绝服务攻击。

     

请考虑使用以下备选方案之一:StringCbLength或   StringCchLength