python发送icmp echo requesy请求
代码如下:
import socketimport struct
def checksum(source_string): sum = 0 countto = (len(source_string)/2)*2 count = 0 while count 16) + (sum & 0xffff) sum = sum + (sum >> 16) answer = ~sum answer = answer & 0xffff answer = answer >> 8 | (answer > 16) + (sum & 0xffff) sum = sum + (sum >> 16) return (~sum) & 0xffff @property def __icmppacket(self): ”’构造 icmp 报文”’ if not self.ipv6: header = struct.pack(‘bbhhh’, 8, 0, 0, self.__id, 0) # type、code、chksum、id、seq else: header = struct.pack(‘bbhhh’, 128, 0, 0, self.__id, 0) packet = header + self.__data # packet without checksum chksum = self.__incksum(packet) # make checksum if not self.ipv6: header = struct.pack(‘bbhhh’, 8, 0, chksum, self.__id, 0) else: header = struct.pack(‘bbhhh’, 128, 0, chksum, self.__id, 0) return header + self.__data # packet *with* checksum def isunip(self, ip): ”’判断ip是否是一个合法的单播地址”’ ip = [int(x) for x in ip.split(‘.’) if x.isdigit()] if len(ip) == 4: if (0 < ip[0] < 223 and ip[0] != 127 and ip[1] < 256 and ip[2] < 256 and 0 < ip[3] < 255): return true return false def makeippool(self, startip, lastip): '''生产 ip 地址池''' ipver = 6 if self.ipv6 else 4 intip = lambda ip: ipy.ip(ip).int() ippool = {ipy.inttoip(ip, ipver) for ip in range(intip(startip), intip(lastip)+1)} return {ip for ip in ippool if self.isunip(ip)} def mping(self, ippool): '''利用icmp报文探测网络主机存活 参数: ippool -- 可迭代的ip地址池 ''' sock = self.__icmpsocket sock.settimeout(self.timeout) packet = self.__icmppacket recvfroms = set() #接收线程的来源ip地址容器 sendthr = sendpingthr(ippool, packet, sock, self.timeout) sendthr.start() while true: try: recvfroms.add(sock.recvfrom(1024)[1][0]) except exception: pass finally: if not sendthr.isalive(): break return recvfroms & ippoolif __name__=='__main__': s = nscan() ippool = s.makeippool('192.168.0.1', '192.168.0.254') print( s.mping(ippool) )