def __init__(self): self.op_code = 0 self.chunk_size = 0 self.chunk_id = 0 self.session_id = 0 self.data_type = 0 self.first = False self.package_number = 0 self.tlv = TLV(TLPParamLength) self.data_tlv = TLV(DLPParamLength)
class TLPHeader(object): """Transport Layer Protocol header v2: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 .... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |L|O|Len|ChunkID|if L>8 then TLV else skip .... | Payload +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ L : Header Length O : Operation Code (see TLPFlag) Len : Length of payload (Data Header + Data) ChunkID : ID of chunk (last chunk ID + last chunk Len) TLV : See TLPParamType for possible types Payload : Data Header + Data Data Header (if data length > 0) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 .... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |L|T|PN |Session|if L>8 then TLV else skip .... | Data +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ L : Data Header Length T : Type-First combination (see DLPType for types) PN : Package number (common between chunks of the same blob) Session : Session Ientifier TLV : See DLPParamType for possible types""" def __init__(self): self.op_code = 0 self.chunk_size = 0 self.chunk_id = 0 self.session_id = 0 self.data_type = 0 self.first = False self.package_number = 0 self.tlv = TLV(TLPParamLength) self.data_tlv = TLV(DLPParamLength) @property def size(self): size = 8 + len(self.tlv) if self.chunk_size > 0: size += 8 + len(self.data_tlv) return size @property def data_size(self): size = self.chunk_size if self.chunk_size > 0: size += 8 + len(self.data_tlv) return size @rw_property def peer_info(): def fget(self): return self.tlv.get(TLPParamType.PEER_INFO, "") def fset(self, value): self.tlv.update(TLPParamType.PEER_INFO, value) return locals() @rw_property def ack_seq(): def fget(self): return self.tlv.get(TLPParamType.ACK_SEQ, 0) def fset(self, value): self.tlv.update(TLPParamType.ACK_SEQ, value) return locals() @rw_property def nak_seq(): def fget(self): return self.tlv.get(TLPParamType.NAK_SEQ, 0) def fset(self, value): self.tlv.update(TLPParamType.NAK_SEQ, value) return locals() @rw_property def tf_combination(): def fget(self): return self.data_type | self.first def fset(self, value): self.first = bool(value & 0x01) self.data_type = value & 0xFE return locals() @rw_property def data_remaining(): def fget(self): return self.data_tlv.get(DLPParamType.DATA_REMAINING, 0) def fset(self, value): self.data_tlv.update(DLPParamType.DATA_REMAINING, value) return locals() def set_sync(self, sync): if sync: self.op_code = TLPFlag.SYN | TLPFlag.RAK self.peer_info = struct.pack( ">HHHHI", PeerInfo.PROTOCOL_VERSION, PeerInfo.IMPLEMENTATION_ID, PeerInfo.VERSION, 0, PeerInfo.CAPABILITIES, ) else: self.op_code = 0 self.peer_info = "" def __str__(self): size = 8 + len(self.tlv) data_size = self.chunk_size data_header = "" if data_size > 0: data_header_size, data_header = self.build_data_header() data_size += data_header_size header = struct.pack(">BBHL", size, self.op_code, data_size, self.chunk_id) header += str(self.tlv) header += data_header return header def parse(self, data): try: fields = struct.unpack(">BBHL", data[:8]) except: header = debug.hexify_string(data[:8]) raise TLPParseError(2, "invalid header", header) size = fields[0] self.op_code = fields[1] self.chunk_size = fields[2] self.chunk_id = fields[3] self.tlv.parse(data[8:], size - 8) if self.chunk_size > 0: dph_size = self.parse_data_header(data[size:]) self.chunk_size -= dph_size size += dph_size return size def build_data_header(self): size = len(self.data_tlv) + 8 header = struct.pack(">BBHL", size, self.tf_combination, self.package_number, self.session_id) header += str(self.data_tlv) return size, header def parse_data_header(self, data): try: fields = struct.unpack(">BBHI", data[:8]) except: header = debug.hexify_string(data[:8]) raise TLPParseError(2, "invalid data header", header) size = fields[0] self.tf_combination = fields[1] self.package_number = fields[2] self.session_id = fields[3] self.data_tlv.parse(data[8:], size - 8) return size
class TLPHeader(object): """Transport Layer Protocol header v2: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 .... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |L|O|Len|ChunkID|if L>8 then TLV else skip .... | Payload +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ L : Header Length O : Operation Code (see TLPFlag) Len : Length of payload (Data Header + Data) ChunkID : ID of chunk (last chunk ID + last chunk Len) TLV : See TLPParamType for possible types Payload : Data Header + Data Data Header (if data length > 0) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 .... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |L|T|PN |Session|if L>8 then TLV else skip .... | Data +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ L : Data Header Length T : Type-First combination (see DLPType for types) PN : Package number (common between chunks of the same blob) Session : Session Ientifier TLV : See DLPParamType for possible types""" def __init__(self): self.op_code = 0 self.chunk_size = 0 self.chunk_id = 0 self.session_id = 0 self.data_type = 0 self.first = False self.package_number = 0 self.tlv = TLV(TLPParamLength) self.data_tlv = TLV(DLPParamLength) @property def size(self): size = 8 + len(self.tlv) if self.chunk_size > 0: size += 8 + len(self.data_tlv) return size @property def data_size(self): size = self.chunk_size if self.chunk_size > 0: size += 8 + len(self.data_tlv) return size @rw_property def peer_info(): def fget(self): return self.tlv.get(TLPParamType.PEER_INFO, "") def fset(self, value): self.tlv.update(TLPParamType.PEER_INFO, value) return locals() @rw_property def ack_seq(): def fget(self): return self.tlv.get(TLPParamType.ACK_SEQ, 0) def fset(self, value): self.tlv.update(TLPParamType.ACK_SEQ, value) return locals() @rw_property def nak_seq(): def fget(self): return self.tlv.get(TLPParamType.NAK_SEQ, 0) def fset(self, value): self.tlv.update(TLPParamType.NAK_SEQ, value) return locals() @rw_property def tf_combination(): def fget(self): return self.data_type | self.first def fset(self, value): self.first = bool(value & 0x01) self.data_type = value & 0xFE return locals() @rw_property def data_remaining(): def fget(self): return self.data_tlv.get(DLPParamType.DATA_REMAINING, 0) def fset(self, value): self.data_tlv.update(DLPParamType.DATA_REMAINING, value) return locals() def set_sync(self, sync): if sync: self.op_code = TLPFlag.SYN | TLPFlag.RAK self.peer_info = struct.pack(">HHHHI", PeerInfo.PROTOCOL_VERSION, PeerInfo.IMPLEMENTATION_ID, PeerInfo.VERSION, 0, PeerInfo.CAPABILITIES) else: self.op_code = 0 self.peer_info = "" def __str__(self): size = 8 + len(self.tlv) data_size = self.chunk_size data_header = "" if data_size > 0: data_header_size, data_header = self.build_data_header() data_size += data_header_size header = struct.pack(">BBHL", size, self.op_code, data_size, self.chunk_id) header += str(self.tlv) header += data_header return header def parse(self, data): try: fields = struct.unpack(">BBHL", data[:8]) except: header = debug.hexify_string(data[:8]) raise TLPParseError(2, "invalid header", header) size = fields[0] self.op_code = fields[1] self.chunk_size = fields[2] self.chunk_id = fields[3] self.tlv.parse(data[8:], size - 8) if self.chunk_size > 0: dph_size = self.parse_data_header(data[size:]) self.chunk_size -= dph_size size += dph_size return size def build_data_header(self): size = len(self.data_tlv) + 8 header = struct.pack(">BBHL", size, self.tf_combination, self.package_number, self.session_id) header += str(self.data_tlv) return size, header def parse_data_header(self, data): try: fields = struct.unpack(">BBHI", data[:8]) except: header = debug.hexify_string(data[:8]) raise TLPParseError(2, "invalid data header", header) size = fields[0] self.tf_combination = fields[1] self.package_number = fields[2] self.session_id = fields[3] self.data_tlv.parse(data[8:], size - 8) return size