Skip to content

Instantly share code, notes, and snippets.

Created November 4, 2012 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4011018 to your computer and use it in GitHub Desktop.
Save anonymous/4011018 to your computer and use it in GitHub Desktop.
QueryDNS.py
###############file QueryDNS.py#################################
#coding: GBK
#Get DNS answer
#详情见RFC 1035
import os, sys
import socket
import struct
import random
from domaintobyte import domaintobyte, bytetodomain
#DHOST = '208.67.222.222' #DNS 服务器的地址
DHOST = '8.8.8.8' #DNS 服务器的地址
DPORT = 53 #默认端口是53
LHOST = ''
LPORT = 10001 #绑定到的本地端口
TIMEOUT = 3.0 #超时设置为3秒
##数据包整体的格式
## +---------------------+
## | Header |
## +---------------------+
## | Question | the question for the name server
## +---------------------+
## | Answer | RRs answering the question
## +---------------------+
## | Authority | RRs pointing toward an authority
## +---------------------+
## | Additional | RRs holding additional information
## +---------------------+
def QueryDNS(domain):
TID = random.randint(-32768, 32767)
Flags = 0x0100
Questions = 0x0001
AnswerRRs = 0x0000
AuthorityRRs = 0x0000
AdditionalRRs = 0x0000
TIDCHARS = struct.pack('!h', TID)
domainbyte = domaintobyte(domain)
#TYPE value and meaning
#A 1 a host address
#NS 2 an authoritative name server
#MD 3 a mail destination (Obsolete - use MX)
#MF 4 a mail forwarder (Obsolete - use MX)
#CNAME 5 the canonical name for an alias
SEARCHTYPE = 0x0001
#Class 一般为 1 指 Internet
SEARCHCLASS = 0x0001
#构造请求报文
Bufhead = struct.pack('!hhhhhh', TID, Flags, Questions, AnswerRRs, AuthorityRRs, AdditionalRRs)
Buftail = struct.pack('!hh', SEARCHTYPE, SEARCHCLASS)
Buf = Bufhead + domainbyte + Buftail
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(TIMEOUT) #设置超时时间
s.bind((LHOST,LPORT))
s.sendto(Buf,(DHOST, DPORT))
print 'Send [OK]'
try:
data, addr = s.recvfrom(1024)
except socket.timeout:
s.close()
print u'响应超时'
return
s.close()
print 'From', addr
print 'Receved', repr(data)
if data[0:2] == TIDCHARS:
flags = struct.unpack('!h', data[2:4])[0]
errormsg = flags & 0x000F
if errormsg != 0:
return
answerRRs = struct.unpack('!h', data[6:8])[0]
bitflags = 12;
while data[bitflags] != '\x00':
bitflags += 1
bitflags += 1
bitflags += 2
bitflags += 2
i = 0
while i < answerRRs:
bitflags += 2
if data[bitflags:bitflags+2] == '\x00\x05':
bitflags += 8
rdatalength = struct.unpack('!h', data[bitflags:bitflags+2])[0]
bitflags += 2
#得到rdata中的全部域名
fullRecord = GetFullName(bitflags, data)
bitflags += rdatalength
print 'CNAME:', bytetodomain(fullRecord)
i += 1
def GetFullName(offset, Buf):
fullRecord = ''
oneChar = struct.unpack('!B', Buf[offset:offset+1])[0]
#print oneChar
if oneChar & 0xc0 == 0xc0 : #指针
jump = struct.unpack('!h', Buf[offset:offset+2])[0]
jump = jump & 0x3FFF #指针指向的地址
fullRecord += GetFullName(jump, Buf)
elif oneChar == 0 : #域名以\0结束
return '\x00'
else : #域名部分
fullRecord += Buf[offset:offset+oneChar+1]
fullRecord += GetFullName(offset+oneChar+1, Buf)
return fullRecord
if __name__ == "__main__":
print 'main start...'
if len(sys.argv) < 2:
print "Usage:QueryDNS.py www.google.cn"
elif len(sys.argv) == 2:
DHOST = '8.8.8.8' #DNS 服务器的地址
else:
DHOST = sys.argv[2]
try:
domain = sys.argv[1]
QueryDNS(domain)
except Exception, e:
logging.error("exit:error:%s" %e)
print 'main over'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment