Winand

dns request (python)

Jun 17th, 2012
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.78 KB | None | 0 0
  1. import socket
  2. import struct
  3. import binascii
  4. import sys
  5.  
  6. def readDomainName(dat, off, lvl_ptr = 0):
  7.     got_ptr = False
  8.     ret = ''
  9.     while not got_ptr and ord(dat[off]):
  10.         if ret: ret = ret + '.'
  11.         isptr = struct.unpack('>H', dat[off:off+2])[0]
  12.         if isptr >= 0xc000:
  13.             got_ptr = True
  14.             if lvl_ptr < 5: #avoid inf loops
  15.                 ret += readDomainName(dat, isptr & 0x3fff, lvl_ptr+1)[0]
  16.             else: ret += '[depth err]'
  17.             off += 2
  18.         else:
  19.             off2 = off + ord(dat[off]) + 1
  20.             ret += dat[off + 1: off2]
  21.             off = off2
  22.     if not got_ptr and ord(dat[off]) == 0: off += 1 #skip /0
  23.     return ret, off
  24.  
  25. def getIPv4(dat, off):
  26.     ip = struct.unpack('BBBB', dat[off:off+4])
  27.     strip = '.'.join(str(i) for i in ip)
  28.     return strip, off + 4
  29.  
  30. DOMAIN = raw_input("Input domain name: ") #'www.google.com'
  31. REM_IP = raw_input("Input DNS server address [8.8.8.8]: ") or '8.8.8.8'
  32. REM_PORT = 53
  33.  
  34. dmn_parts = DOMAIN.split('.')
  35. dmn_parts_len = ()
  36. values = (0x0123, 0x0100, 1, 0, 0, 0)
  37. for part in dmn_parts:
  38.     values += (len(part), part,)
  39.     dmn_parts_len += (len(part),)
  40. values += (0, 0x0001, 0x0001,)
  41. dmn_parts_fmt = ''.join(['B%ds' for i in xrange(len(dmn_parts_len))])
  42. s = struct.Struct(('>HHHHHH' + dmn_parts_fmt + 'BHH') % dmn_parts_len)
  43. MESSAGE = s.pack(*values)
  44. sock = socket.socket( socket.AF_INET, # Internet
  45.                       socket.SOCK_DGRAM) # UDP
  46. sock.sendto( MESSAGE, (REM_IP, REM_PORT) )
  47. ANSWER, addr = sock.recvfrom( 1024 ) # buffer size is 1024 bytes
  48. h = struct.unpack('>HHHHHH', ANSWER[0:12])
  49. que_n = h[2]
  50. ans_n = h[3]
  51. aut_n = h[4]
  52. add_n = h[5]
  53.  
  54. print "DNS server:", REM_IP + ":" + str(REM_PORT)
  55. print "Query (UDP):", binascii.hexlify(MESSAGE)
  56. print "Answer from", addr[0] + ":" + str(addr[1]) + ":", binascii.hexlify(ANSWER)
  57. print
  58. print "Transaction ID:", hex(h[0])
  59. print "Flags:", hex(h[1])
  60. print "Questions:", que_n
  61. print "Answer RRs:", ans_n
  62. print "Authority RRs:", aut_n
  63. print "Additional RRs:", add_n
  64. print
  65.  
  66. #Queries
  67. pos = 12
  68. for i in xrange(que_n):
  69.     name, pos = readDomainName(ANSWER, pos)
  70.     print i + 1, "Query for:", name
  71.     pos += 2 + 2
  72. print
  73. #Answers
  74. for i in xrange(ans_n):
  75.     name, pos = readDomainName(ANSWER, pos)
  76.     if name:
  77.         answ = ''
  78.         type = struct.unpack('>H', ANSWER[pos:pos+2])[0]
  79.         pos += 2 + 2 + 4 + 2
  80.         if type == 0x0001: #A record
  81.             answ, pos = getIPv4(ANSWER, pos)
  82.         elif type == 0x0005: #CNAME
  83.             answ, pos = readDomainName(ANSWER, pos)
  84.         if answ:
  85.             print i + 1, "Answer for", name, "is", answ
  86.         else:
  87.             print i + 1, "Corrupted answer for", name
  88.             break
  89.     else:
  90.         print i + 1, "Corrupted answer"
  91.         break
Advertisement
Add Comment
Please, Sign In to add comment