###############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'
----------------------------------------------
修改成了
def _get_response(self, data ,CorF):
con = 0
rspdata = None
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect((self.server.servers[(not CorF) and 1 or 0], 53))
while not rspdata and con <4:
try:
con += 1
sock.sendall(data)
sock.settimeout(3)
rspdata = sock.recv(65535)
except:
rspdata = None
sock.close()
return rspdata
这样的就可以了。获取域名的CNAME.
。。