def __disassemble(self, raw_packet, cksum=0): # The kernel computes the checksum, even on a raw packet. packet = inet.net2iph(raw_packet) b1 = ord(packet[0]) self.v = (b1 >> 4) & 0x0f self.hl = b1 & 0x0f if self.v != IPVERSION: raise ValueError("cannot handle IPv{:d} packets".format(self.v)) hl = self.hl * 4 # verify the checksum self.sum = struct.unpack(b'h', packet[10:12])[0] & 0xffff if cksum: our_cksum = inet.cksum(packet[:20]) if our_cksum != 0: raise ValueError(packet) # unpack the fields elts = struct.unpack(b'cchhhcc', packet[:hl - 10]) # struct didn't do !<> when this was written self.tos = ord(elts[1]) self.len = elts[2] & 0xffff self.id = elts[3] & 0xffff self.off = elts[4] & 0xffff self.ttl = ord(elts[5]) self.p = ord(elts[6]) self.data = packet[hl:] self.src = packet[hl - 8:hl - 4] self.dst = packet[hl - 4:hl] self.__unparse_addrs()
def assemble(self, cksum=0): """ Get a packet suitable for sending over an IP socket. """ # make sure all the data is ready self.len = self.hl * 4 + len(self.data) self.__parse_addrs() # create the packet header = struct.pack( b'cchhhcc', chr((self.v & 0x0f) << 4 | (self.hl & 0x0f)), # 4bits each chr(self.tos & 0xff), self.len, self.id, self.off, # what about flags? chr(self.ttl & 0xff), chr(self.p & 0xff)) if cksum: self.sum = inet.cksum(header + '\000\000' + self.__src + self.__dst) packet = header + struct.pack('h', self.sum) + self.__src + self.__dst else: packet = header + '\000\000' + self.__src + self.__dst packet += self.data self.__packet = inet.iph2net(packet) return self.__packet
def __disassemble(self, packet, cksum=1): if cksum: our_cksum = inet.cksum(packet) if our_cksum != 0: raise ValueError(packet) self.type = ord(packet[0]) self.code = ord(packet[1]) elts = struct.unpack('hhh', packet[2:8]) [self.cksum, self.id, self.seq] = [x & 0xffff for x in elts] self.data = packet[8:]
def assemble(self, cksum=1): idseq = struct.pack('hh', self.id, self.seq) packet = chr(self.type) + chr( self.code) + '\000\000' + idseq + self.data if cksum: self.cksum = inet.cksum(packet) packet = chr(self.type) + chr(self.code) + struct.pack( 'H', self.cksum) + idseq + self.data # Don't need to do any byte-swapping, because idseq is # appplication defined and others are single byte values. self.__packet = packet return self.__packet
def __compute_cksum(self): "Use inet.cksum instead" return inet.cksum(self.packet) packet = self.packet if len(packet) & 1: packet = packet + '\0' words = array.array('h', packet) sum = 0 for word in words: sum = sum + (word & 0xffff) hi = sum >> 16 lo = sum & 0xffff sum = hi + lo sum = sum + (sum >> 16) return (~sum) & 0xffff