def recv(self, timeout=3): """ 返回一个生成器,用于迭代socket在timeout内接受到的响应包 """ while True: rsocket, wsocket, errsocket = select.select([self.sock], [], [], timeout) if len(rsocket) == 0: return (response_buffer, address) = self.sock.recvfrom(65535) u = Lib.Munpacker(response_buffer) r = Lib.DnsResult(u, {}) yield (r, address[0])
try: s.sendto(request, (ip, DPORT)) print 'domain: ', domain, " send to Dns server:", ip except socket.error, reason: print reason continue '''循环接收收到的返回header''' while 1: try: r, w, e = select.select([s], [], [], 3) if not (r or w or e): break (data, addr) = s.recvfrom(65535) u = Lib.Munpacker(data) r = Lib.DnsResult(u, {}) print r.header if r.header['status'] == 'NOERROR' and len(r.answers): # 判断可解析条件 result.append( {'domain': r.questions[0]['qname'], 'ip': addr[0], 'domain_info': 'yes'}) print r.questions[0]['qname'] + '\t' + addr[0] + ' success' # break else: if len(r.questions) != 0: result.append( {'domain': r.questions[0]['qname'], 'ip': addr[0], 'domain_info': 'failed'}) print r.questions[0]['qname'] + '\t' + addr[0] + ' failed' # break
def batch_server_detect(list_ip=[]): ''' batch dns detect , each time sends 'num' packets ''' # TID为随机数 tid = random.randint(0, 65535) # 端口为53,UDP port = 53 # 操作为查询 opcode = Opcode.QUERY # Tpye类型为A qtype = Type.PTR # 查询类,一般为IN qclass = Class.IN # 期望递归 rd = 1 # 建立一个UDP套接字(SOCK_DGRAM,代表UDP,AF_INET表示IPv4) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) source_port = random.randint(1024, 65535) # socket绑定到指定IP地址和接口上 s.bind(('', source_port)) ip_count = len(list_ip) count = 0 result = [] while count * THREAD_NUM < ip_count: ips = list_ip[count * THREAD_NUM: (count + 1) * THREAD_NUM] for ip in ips: server = long2ip(ip) m = Lib.Mpacker() m.addHeader(tid, 0, opcode, 0, 0, rd, 0, 0, 0, 1, 0, 0, 0) ip_tips = server.split(".") qname = ip_tips[3] + '.' + ip_tips[2] + \ '.' + ip_tips[1] + '.' + ip_tips[0] qname += '.in-addr.arpa' m.addQuestion(qname, qtype, qclass) request = m.getbuf() try: a = s.sendto(request, (server, port)) print a, "send to IP:", server except socket.error, reason: print reason while s: try: r, w, e = select.select([s], [], [], TIMEOUT) if not len(r): break (reply, from_address) = s.recvfrom(65535) u = Lib.Munpacker(reply) r = Lib.DnsResult(u, {}) if r.header['ra'] == 1 and r.header['aa'] == 0: print from_address, "递归服务器" result.append( {'ip': from_address[0], 'type': DNSSERVERTYPE[2], 'other': r.header['status']}) elif r.header['ra'] == 1 and r.header['aa'] == 1: print from_address, "权威服务器(递归服务)" result.append( {'ip': from_address[0], 'type': DNSSERVERTYPE[1], 'other': r.header['status']}) elif r.header['ra'] == 0 and r.header['aa'] == 1: print from_address, "权威服务器" result.append( {'ip': from_address[0], 'type': DNSSERVERTYPE[0], 'other': r.header['status']}) else: print from_address, "服务器类型探测失败:未知服务器", r.header['status'] result.append( {'ip': from_address[0], 'type': DNSSERVERTYPE[3], 'other': r.header['status']}) except socket.error, reason: print reason except DNS.Error as e: print e