开心每一天1111
嘿伙计们,经过几次尝试,我终于自己解决了这个问题!这是编辑后的代码:#!/usr/bin/python3import socketimport structICMP_ECHO = 0ICMP_ECHO_REQUEST = 8class ICMPPacket(object): def __init__(self, type, code, checksum, id, sequence, data, source_ip, dest=(None, None)): self.type, self.code, self.checksum = type, code, checksum self.id, self.sequence, self.data = id, sequence, data self.dest = dest self.source_ip = source_ip self.length = len(self.data) def __repr__(self): return "<ICMP packet: type = {s.type}, code = {s.code}, " \ "data length = {length}".format(s=self, length=len(self.data)) def __str__(self): return "Type of message: {s.type}, Code {s.code},"\ "Checksum: {s.checksum}, ID: {s.id}, Sequence: {s.sequence}, " \ "Data: {s.data}, Data length: {length}".format(s=self, length=len(self.data)) def create(self): #print("\nEntering CREATE!!\n\n") pack_str = "!BBHHH4sH" pack_args = [self.type, self.code, 0, self.id, self.sequence, socket.inet_aton(self.dest[0]), self.dest[1]] if self.length: pack_str += "{}s".format(self.length) #print("PACK STR: " + pack_str) pack_args.append(self.data) #print("Pack ARGS: \n", pack_args, "\n") self.checksum = self._checksum(struct.pack(pack_str, *pack_args)) #print("CHECKSUM: ", self.checksum) pack_args[2] = self.checksum return struct.pack(pack_str, *pack_args) @classmethod def parse(cls, packet): ip_pack_str = "BBHHHBBH4s4s" icmp_pack_str = "!BBHHH4sH" data = "" ip_packet, icmp_packet = packet[:20], packet[20:] # split ip header ip_packet = struct.unpack(ip_pack_str, ip_packet) source_ip = ip_packet[8] icmp_pack_len = struct.calcsize(icmp_pack_str) packet_len = len(icmp_packet) - icmp_pack_len if packet_len > 0: icmp_data_str = "{}s".format(packet_len) data = struct.unpack(icmp_data_str, icmp_packet[icmp_pack_len:])[0] type, code, checksum, id, sequence, dest_ip, \ dest_port = struct.unpack(icmp_pack_str, icmp_packet[:icmp_pack_len]) return cls(type, code, checksum, id, sequence, data, socket.inet_ntoa(source_ip), (socket.inet_ntoa(dest_ip), dest_port)) @staticmethod def _checksum(packet): #print("Argument for checksum: !!\n",packet) packet = packet.decode('ISO-8859-1') # edited to match python3 csum = 0 countTo = (len(packet) / 2) * 2 count = 0 while count < countTo: thisVal = ord(packet[count+1]) * 256 + ord(packet[count]) #print("THISVAL: ", thisVal) csum = csum + thisVal csum = csum & 0xffffffff count = count + 2 if countTo < len(packet): csum = csum + ord(packet[len(packet) - 1]) csum = csum & 0xffffffff csum = (csum >> 16) + (csum & 0xffff) csum = csum + (csum >> 16) checksum = ~csum checksum = checksum & 0xffff checksum = checksum >> 8 | (checksum << 8 & 0xff00) return checksum我对数据包进行了重新编码以匹配字节使用packet = packet.decode('ISO-8859-1')为了匹配这一行thisVal = ord(packet[count+1]) * 256 + ord(packet[count])因为它需要一个字符串,但它收到了一个 INT。因此将其解码为字符串解决了这个问题!编辑:如果您对更好的编码来处理数据包的二进制数据有任何建议,请告诉我。