代码之家  ›  专栏  ›  技术社区  ›  momo

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

  •  4
  • momo  · 技术社区  · 15 年前

    我知道如何使用gethostbyddr 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 回复  |  直到 6 年前
        1
  •  4
  •   wqw    15 年前

    试试这个:

    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
    
        2
  •  0
  •   joejoeson    15 年前

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

        3
  •  0
  •   user6698332    6 年前

    这不是一个答案,但对WQW来说非常重要。 post :

    Security Warning lstrlen 功能(第5行和第55行):

    不正确地使用此功能可能会损害您的 应用 . 莱斯特伦 假设lpstring是以空结尾的 字符串或空。如果不是,这可能导致 缓冲区溢出或 拒绝服务 攻击您的应用程序。

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