import time, struct import socket, select
class MyPing(): def raw_socket(self, dst_addr, imcp_packet): rawsocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp")) send_request_ping_time = time.time() rawsocket.sendto(imcp_packet, (dst_addr, 80)) return send_request_ping_time, rawsocket
def chesksum(self, data): n = len(data) m = n % 2 sum = 0 for i in range(0, n - m, 2): sum += (data[i]) + ((data[i + 1]) << 8) sum = (sum >> 16) + (sum & 0xffff) if m: sum += (data[-1]) sum = (sum >> 16) + (sum & 0xffff) answer = ~sum & 0xffff answer = answer >> 8 | (answer << 8 & 0xff00) return answer
def get_host_address(self,host): dst_addr = socket.gethostbyname(host) return dst_addr
def request_ping(self, data_type, data_code, data_checksum, data_ID, data_Sequence, payload_body): imcp_packet = struct.pack('>BBHHH32s', data_type, data_code, data_checksum, data_ID, data_Sequence,payload_body) icmp_chesksum = self.chesksum(imcp_packet) imcp_packet = struct.pack('>BBHHH32s', data_type, data_code, icmp_chesksum, data_ID, data_Sequence,payload_body) return imcp_packet
def reply_ping(self, send_request_ping_time, rawsocket, data_Sequence, timeout=3): while True: what_ready = select.select([rawsocket], [], [], timeout) wait_for_time = (time.time() - send_request_ping_time) if what_ready[0] == []: return -1 time_received = time.time() received_packet, addr = rawsocket.recvfrom(1024) icmpHeader = received_packet[20:28] type, code, r_checksum, packet_id, sequence = struct.unpack(">BBHHH", icmpHeader) if type == 0 and sequence == data_Sequence: return time_received - send_request_ping_time timeout = timeout - wait_for_time if timeout <= 0: return -1
def send_ping(self, address): data_type = 8 data_code = 0 data_checksum = 0 data_ID = 0 data_Sequence = 1 payload_body = b'abcdefghijklmnopqrstuvwabcdefghi'
icmp_packet = self.request_ping(data_type, data_code, data_checksum, data_ID, data_Sequence, payload_body) send_request_ping_time, rawsocket = self.raw_socket(address, icmp_packet) times = self.reply_ping(send_request_ping_time, rawsocket, data_Sequence) if times > 0: return_time = int(times * 1000) return return_time else: return -1
|