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])
def _make_packet(self, server, qtype=Type.A, recursive=True, qclass=Class.IN, port=53): """ 组装探测请求包 """ domainlist = ['www.wizeye.com.cn', server] domain_id = { 'www.wizeye.com.cn': 11111, server: 55555 } packetlsit = [] for domain in domainlist: packer = Lib.Mpacker() tid = domain_id[domain] if domain.split('.')[0] == 'www': self._add_qheader(packer, recursive, tid) packer.addQuestion(domain, qtype, qclass) request_data = packer.getbuf() packetlsit.append(request_data) else: ip_tips = domain.split('.') qname = ip_tips[3] + '.' + ip_tips[2] + \ '.' + ip_tips[1] + '.' + ip_tips[0] qname += '.in-addr.arpa' self._add_qheader(packer, recursive, tid) packer.addQuestion(qname, Type.PTR, qclass) request_data = packer.getbuf() packetlsit.append(request_data) return packetlsit
class DomainToIp: def __init__(self,DHOST='114.114.114.114'): ''' 初始化类DomainToIp,连接数据库,DNS服务器ip地址可以更改,默认为114.114.114.114 ''' self.DHOST = DHOST #DNS 服务器的地址 self.DPORT = 53 #默认端口是53 self.tid = random.randint(0,65535) #tid为随机数 self.opcode = Opcode.QUERY #标准查询 self.qtype = Type.A #查询类型为A self.qclass = Class.IN #查询类IN self.rd = 1 #期望递归查询 #要查询的域名 self.domain_list = ['www.baidu.com','www.sina.com','www.163.com','www.ifeng.com','www.hitwh.edu.cn'] def send_domain_receive_ip(self): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #建立一个UDP套接字(SOCK_DGRAM,代表UDP,AF_INET表示IPv4) except socket.error,msg: print "无法创建socket.Error code:" +str(msg[0])+',Error message:'+msg[1] #error sys.exit(1) source_port = random.randint(1024, 65535) #windows不是65535 #随机port s.bind(('', source_port)) #绑定,检测所有接口 domain_source = [] #发送的domain数量 domain_result = [] #接收到的domain数量,这两个变量主要用来判断丢包情况 '''循环发送需要解析的domain name''' for domain in self.domain_list: #domain_source.append(domain) m = Lib.Mpacker() m.addHeader(self.tid, 0, self.opcode, 0, 0, self.rd, 0, 0, 0, 1, 0, 0, 0) m.addQuestion(domain,self.qtype,self.qclass) request = m.getbuf() try: s.sendto(request,(self.DHOST, self.DPORT)) print 'domain: ',domain," send to Dns server:",self.DHOST except socket.error,reason: print reason continue
def send(self, server, qname, qtype=Type.A, recursive=True, qclass=Class.IN, port=53): """ 发送请求数据包,不返回任何响应 """ packer = Lib.Mpacker() self._add_qheader(packer, recursive) packer.addQuestion(qname, qtype, qclass) request_data = packer.getbuf() self.sock.sendto(request_data, (server, port))
# error print "无法创建socket.Error code:" + str(msg[0]) + ',Error message:' + msg[1] sys.exit(1) # windows不是65535 #随机port source_port = random.randint(1024, 65535) s.bind(('', source_port)) # 绑定,检测所有接口 result = [] # 得到的结果 result_ip = [] result_diffrences = [] ip_source = [] for domain in domain_list: try: m = Lib.Mpacker() m.addHeader(tid, 0, opcode, 0, 0, rd, 0, 0, 0, 1, 0, 0, 0) m.addQuestion(domain, qtype, qclass) request = m.getbuf() except: print 'test' pass try: s.sendto(request, (ip, DPORT)) print 'domain: ', domain, " send to Dns server:", ip except socket.error, reason: print reason continue '''循环接收收到的返回header'''
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