Winand

dns request (vb)

Jun 17th, 2012
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Option Explicit
  2.  
  3. Sub main()
  4.     Dim DOMAIN As String
  5.     DOMAIN = InputBox("Input domain name:")
  6.     Dim REM_IP As String
  7.     REM_IP = InputBox("Input DNS server address [8.8.8.8]:")
  8.     If REM_IP = vbNullString Then REM_IP = "8.8.8.8"
  9.     Const REM_PORT As Long = 53
  10.    
  11.     Dim dmn_parts() As String
  12.     dmn_parts = Split(DOMAIN, ".")
  13.     Dim values() As Variant
  14.     values = Array(&H123, &H100, 1, 0, 0, 0)
  15.     Dim dmn_parts_fmt() As Variant
  16.     dmn_parts_fmt = Array(vbInteger, vbInteger, vbInteger, vbInteger, vbInteger, vbInteger)
  17.     Dim part As Variant
  18.     For Each part In dmn_parts
  19.         cnct values, Array(Len(part), part)
  20.         cnct dmn_parts_fmt, Array(vbByte, vbString)
  21.     Next part
  22.     cnct values, Array(0, &H1, &H1)
  23.     cnct dmn_parts_fmt, Array(vbByte, vbInteger, vbInteger)
  24.     Dim MESSAGE() As Byte
  25.     MESSAGE = pack(values, dmn_parts_fmt)
  26.    
  27.     Dim sock As Object
  28.     Set sock = CreateObject("MSWinSock.Winsock")
  29.     sock.Protocol = &H1 'sckUDPProtocol
  30.    sock.RemoteHost = REM_IP
  31.     sock.RemotePort = REM_PORT
  32.     sock.SendData MESSAGE
  33.     Do Until sock.BytesReceived 'Wait for response
  34.        DoEvents
  35.     Loop
  36.     ReDim ANSWER(sock.BytesReceived - 1) As Byte
  37.     sock.GetData ANSWER
  38.     Dim h() As Variant, que_n As Long, ans_n As Long, aut_n As Long, add_n As Long
  39.     h = unpack(ANSWER, Array(vbInteger, vbInteger, vbInteger, vbInteger, vbInteger, vbInteger))
  40.     que_n = h(2)
  41.     ans_n = h(3)
  42.     aut_n = h(4)
  43.     add_n = h(5)
  44.    
  45.     Debug.Print "DNS server: " & REM_IP & ":" & REM_PORT
  46.     Debug.Print "Query (UDP): " & hexlify(MESSAGE)
  47.     Debug.Print "Answer from " & sock.RemoteHostIP & ":" & sock.RemotePort & ": " & hexlify(ANSWER)
  48.     Debug.Print
  49.     Debug.Print "Transaction ID: 0x" & Hex(h(0))
  50.     Debug.Print "Flags: 0x" & Hex(h(1))
  51.     Debug.Print "Questions: " & que_n
  52.     Debug.Print "Answer RRs: " & ans_n
  53.     Debug.Print "Authority RRs: " & aut_n
  54.     Debug.Print "Additional RRs: " & add_n
  55.     Debug.Print
  56.    
  57.     Dim pos As Long, name As String, i As Long
  58.     'Queries
  59.    pos = 12
  60.     For i = 1 To que_n
  61.         name = readDomainName(ANSWER, pos)
  62.         Debug.Print i & " Query for: " & name
  63.         pos = pos + 2 + 2
  64.     Next i
  65.     Debug.Print
  66.     'Answers
  67.    Dim answ As String, type_ As Long
  68.     For i = 1 To ans_n
  69.         name = readDomainName(ANSWER, pos)
  70.         If Len(name) Then
  71.             answ = ""
  72.             type_ = unpack(ANSWER, Array(vbInteger), pos)(0)
  73.             pos = pos + 2 + 2 + 4 + 2
  74.             If type_ = &H1 Then 'A record
  75.                answ = getIPv4(ANSWER, pos)
  76.             ElseIf type_ = &H5 Then 'CNAME
  77.                answ = readDomainName(ANSWER, pos)
  78.             End If
  79.             If Len(answ) Then
  80.                 Debug.Print i & " Answer for " & name & " is " & answ
  81.             Else
  82.                 Debug.Print i & " Corrupted answer for " & name
  83.                 Exit For
  84.             End If
  85.         Else
  86.             Debug.Print i & " Corrupted answer"
  87.             Exit For
  88.         End If
  89.     Next i
  90. End Sub
  91.  
  92. 'append values to array
  93. Private Sub cnct(arr As Variant, vals As Variant)
  94.     Dim l As Long, u As Long
  95.     l = UUBound(arr) + 1
  96.     u = l + UBound(vals)
  97.     ReDim Preserve arr(u)
  98.     Dim i As Long
  99.     For i = l To u
  100.         arr(i) = vals(i - l)
  101.     Next i
  102. End Sub
  103.  
  104. Private Function UUBound(arr) As Long
  105. On Error GoTo 1:
  106.     UUBound = UBound(arr)
  107. Exit Function
  108. 1: UUBound = -1
  109. End Function
  110.  
  111. Private Function pack(arr() As Variant, fmt() As Variant) As Byte()
  112.     Dim ret() As Byte, aux() As Byte, i As Long
  113.     For i = 0 To UBound(fmt)
  114.         Select Case fmt(i)
  115.         Case vbByte:
  116.             ReDim aux(0) As Byte
  117.             aux(0) = arr(i)
  118.         Case vbInteger:
  119.             Dim swap As Byte
  120.             aux = ChrW$(arr(i))
  121.             swap = aux(0)
  122.             aux(0) = aux(1)
  123.             aux(1) = swap
  124.         Case vbString: aux = StrConv(arr(i), vbFromUnicode)
  125.         End Select
  126.         cnct ret, aux
  127.     Next i
  128.     pack = ret
  129. End Function
  130.  
  131. Private Function unpack(arr() As Byte, fmt As Variant, Optional ByVal off As Long = -1) As Variant()
  132.     Dim i As Long, pos As Long
  133.     If off <> -1 Then pos = off
  134.     Dim arrs As String
  135.     arrs = arr
  136.     ReDim ret(UBound(fmt)) As Variant
  137.     For i = 0 To UBound(fmt)
  138.         Select Case fmt(i)
  139.         Case vbByte:
  140.             ret(i) = AscB(MidB(arrs, pos + 1, 1))
  141.             pos = pos + 1
  142.         Case vbInteger:
  143.             ret(i) = CLng(AscB(MidB(arrs, pos + 1, 1))) * &H100 Or _
  144.                     CLng(AscB(MidB(arrs, pos + 1 + 1, 1)))
  145.             pos = pos + 2
  146.         End Select
  147.     Next i
  148.     unpack = ret
  149. End Function
  150.  
  151. Private Function hexlify(arr() As Byte) As String
  152.     Dim i As Long
  153.     For i = 0 To UBound(arr)
  154.         hexlify = hexlify & Format$(Hex$(arr(i)), "00")
  155.     Next i
  156. End Function
  157.  
  158. Private Function readDomainName(dat() As Byte, off As Long, Optional ByVal lvl_ptr As Long = 0) As String
  159.     Dim got_ptr As Boolean, ret As String, isptr As Long, dats As String
  160.     dats = dat
  161.     got_ptr = False
  162.     While Not got_ptr And dat(off)
  163.         If LenB(ret) Then ret = ret & "."
  164.         isptr = unpack(dat, Array(vbInteger), off)(0)
  165.         If isptr >= 49152 Then '0xC000
  166.            got_ptr = True
  167.             If lvl_ptr < 5 Then _
  168.                 ret = ret & readDomainName(dat, isptr And &H3FFF, lvl_ptr + 1) _
  169.             Else ret = ret & "[depth err]"
  170.             off = off + 2
  171.         Else
  172.             ret = ret & StrConv(MidB(dats, off + 1 + 1, dat(off)), vbUnicode)
  173.             off = off + dat(off) + 1
  174.         End If
  175.     Wend
  176.     If Not got_ptr And dat(off) = 0 Then off = off + 1 'skip /0
  177.    readDomainName = ret
  178. End Function
  179.  
  180. Private Function getIPv4(dat() As Byte, off As Long) As String
  181.     Dim ip() As Variant
  182.     ip = unpack(dat, Array(vbByte, vbByte, vbByte, vbByte), off)
  183.     getIPv4 = Join(ip, ".")
  184.     off = off + 4
  185. End Function
Advertisement
Add Comment
Please, Sign In to add comment