class LTPex(Packet): name = "LTP Extension" fields_desc = [ ByteEnumField("ExTag", 0, _ltp_extension_tag), SDNV2FieldLenField("ExLength", None, length_of="ExData"), # SDNV2FieldLenField StrLenField("ExData", "", length_from=lambda x: x.ExLength) ] def default_payload_class(self, pay): return conf.padding_layer
class BPBLOCK(Packet): fields_desc = [ByteEnumField('Type', 1, {1: "Bundle payload block"}), SDNV2('ProcFlags', 0), SDNV2FieldLenField('BlockLen', None, length_of="load"), StrLenField("load", "", length_from=lambda pkt: pkt.BlockLen, max_length=65535) ] def mysummary(self): return self.sprintf("BPBLOCK(%Type%) Flags: %ProcFlags% Len: %BlockLen%") # noqa: E501
class LTP(Packet): name = "LTP" fields_desc = [ BitField('version', 0, 4), BitEnumField('flags', 0, 4, _ltp_flag_vals), SDNV2("SessionOriginator", 0), SDNV2("SessionNumber", 0), BitFieldLenField("HeaderExtensionCount", None, 4, count_of="HeaderExtensions"), # noqa: E501 BitFieldLenField("TrailerExtensionCount", None, 4, count_of="TrailerExtensions"), # noqa: E501 PacketListField( "HeaderExtensions", [], LTPex, count_from=lambda x: x.HeaderExtensionCount), # noqa: E501 # # LTP segments containing data have a DATA header # ConditionalField(SDNV2("DATA_ClientServiceID", 0), lambda x: x.flags in _ltp_data_segment), ConditionalField(SDNV2("DATA_PayloadOffset", 0), lambda x: x.flags in _ltp_data_segment), ConditionalField( SDNV2FieldLenField("DATA_PayloadLength", None, length_of="LTP_Payload"), # noqa: E501 lambda x: x.flags in _ltp_data_segment), # # LTP segments that are checkpoints will have a checkpoint serial number and report serial number. # noqa: E501 # ConditionalField(SDNV2("CheckpointSerialNo", 0), lambda x: x.flags in _ltp_checkpoint_segment), ConditionalField(SDNV2("ReportSerialNo", 0), lambda x: x.flags in _ltp_checkpoint_segment), # # Then comes the actual payload for data carrying segments. # ConditionalField( PacketListField( "LTP_Payload", None, next_cls_cb=_ltp_guess_payload, # noqa: E501 length_from=lambda x: x.DATA_PayloadLength), # noqa: E501 lambda x: x.flags in _ltp_data_segment), # # Report ACKS acknowledge a particular report serial number. # ConditionalField(SDNV2("RA_ReportSerialNo", 0), lambda x: x.flags == 9), # # Reception reports have the following fields. # ConditionalField(SDNV2("ReportSerialNo", 0), lambda x: x.flags == 8), ConditionalField(SDNV2("ReportCheckpointSerialNo", 0), lambda x: x.flags == 8), ConditionalField(SDNV2("ReportUpperBound", 0), lambda x: x.flags == 8), ConditionalField(SDNV2("ReportLowerBound", 0), lambda x: x.flags == 8), ConditionalField( SDNV2FieldLenField("ReportReceptionClaimCount", None, count_of="ReportReceptionClaims"), # noqa: E501 lambda x: x.flags == 8), ConditionalField( PacketListField( "ReportReceptionClaims", [], LTPReceptionClaim, # noqa: E501 count_from=lambda x: x.ReportReceptionClaimCount ), # noqa: E501 lambda x: x.flags == 8 and (not x.ReportReceptionClaimCount or x.ReportReceptionClaimCount > 0 )), # noqa: E501 # # Cancellation Requests # ConditionalField( ByteEnumField("CancelFromSenderReason", 15, _ltp_cancel_reasons), lambda x: x.flags == 12), ConditionalField( ByteEnumField("CancelFromReceiverReason", 15, _ltp_cancel_reasons), lambda x: x.flags == 14), # # Cancellation Acknowldgements # ConditionalField(SDNV2("CancelAckToBlockSender", 0), lambda x: x.flags == 13), ConditionalField(SDNV2("CancelAckToBlockReceiver", 0), lambda x: x.flags == 15), # # Finally, trailing extensions # PacketListField("TrailerExtensions", [], LTPex, count_from=lambda x: x.TrailerExtensionCount ) # noqa: E501 ] def mysummary(self): return self.sprintf("LTP %SessionNumber%"), [UDP]