VB6 Поиск имени хоста с IP, указание DNS-сервера - PullRequest
4 голосов
/ 07 февраля 2010

Я знаю, как найти имя хоста из IPv4 в VB с помощью вызова API GetHostByAddr для Windows (, это прекрасно работает). Однако эта функция не позволяет указать DNS-сервер для использования. Иногда стандартные DNS-серверы компании подходят, но в других случаях мне нужно указать внешний DNS-сервер для поиска, и я не думаю, что здесь лучше использовать оболочку nslookup и анализ выходных данных.

Примечание: на самом деле это будет использоваться в качестве кода VBA в книге Excel, чтобы помочь кому-то еще выполнять свою работу, и не стоит писать большое приложение, когда ему нужны простые функции.

Я думал Возможно, я нашел ответ в вызове API getnameinfo , но, как представляется, внимательное чтение указывает, что он не предлагает параметр servername.

После некоторого интенсивного поиска я нашел ссылку на параметр pExtra для функции DNSQuery . Но я даже не знаю, как начать использовать это в VB6.

Может ли кто-нибудь помочь мне с поиском DNS из VB6, указав имя сервера для использования?

Полное рабочее решение, конечно, было бы неплохо, но я готов работать: просто направьте меня в правильном направлении.

ОБНОВЛЕНИЕ: по какой-то странной причине он не нажал, что DNSQuery был вызовом API Windows. Это просто не звучало как один. Я, конечно, смог бы продвинуться вперед в решении этой проблемы, если бы собрал эту крошечную деталь.

Ответы [ 3 ]

4 голосов
/ 09 февраля 2010

Попробуйте это:

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
0 голосов
/ 19 марта 2018

Это не ответ, а очень важное примечание к wqw post :

Предупреждение безопасности при функции lstrlen (строки 5 и 55):

Неправильное использование этой функции может поставить под угрозу безопасность вашего применение . lstrlen предполагает, что lpString имеет нулевое окончание строка или NULL. Если это не так, это может привести к переполнению буфера или * отказ в обслуживании атака на ваше приложение.

Рассмотрите возможность использования одной из следующих альтернатив: StringCbLength или StringCchLength.

0 голосов
/ 07 февраля 2010

Можете ли вы использовать поставщика WMI DNS для установки DNS системы, а затем использовать GetHostByAddr

...