Я пытаюсь создать протокол PTPv2 с помощью Scapy. В этом протоколе несколько типов сообщений, поэтому я использую ConditionalField
для описания различных параметров полей:
class PTPv2(Packet):
name = "Precision Time Protocol V2"
fields_desc = [
# Header
BitField('transportSpecific', 1, 4),
BitEnumField('messageType', 0, 4, Message_Types),
ByteField('versionPTP', 2),
LenField('messageLength', None),
ByteField('subdomainNumber', 0),
ByteField('empty1', 0),
XShortField('flags', 0),
LongField('correction', 0),
IntField('empty2', 0),
XLongField('ClockIdentity', 0),
XShortField('SourcePortId', 0),
XShortField('sequenceId', 0),
ByteField('control', 0),
SignedByteField('logMessagePeriod', 0),
# SYNC message, messageType=0
ConditionalField(XBitField('TimestampSec', 0, 48),lambda pkt: pkt.messageType==0),
ConditionalField(IntField('TimestampNanoSec', 0), lambda pkt: pkt.messageType == 0),
# Follow up message, messageType=8
ConditionalField(XBitField('preciseOriginTimestampSec', 0, 48), lambda pkt: pkt.messageType == 8),
ConditionalField(IntField('preciseOriginTimestampNanoSec', 0), lambda pkt: pkt.messageType == 8)
# Path delay resp follow up message, messageType=0xA
ConditionalField(XBitField('responseOriginTimestampSec', 0, 48), lambda pkt: pkt.messageType == 0xA),
ConditionalField(IntField('responseOriginTimestampNanoSec', 0), lambda pkt: pkt.messageType == 0xA),
ConditionalField(XLongField('requestingSourcePortIdentity', 0), lambda pkt: pkt.messageType == 0xA),
ConditionalField(XShortField('requestingSourcePortId', 0), lambda pkt: pkt.messageType == 0xA)
Теперь я хочу, чтобы поле messageLength
описывало длину слоя и вычислялось автоматически в зависимости от существующих полей. Он должен описывать длину всех полей на уровне PTPv2, начиная с первого (transportSpecific
).
Я читал про PacketLenField
и FieldLenField
, но вроде они оба описывают длину одного поля, а не группы полей (насколько я понимаю).
Еще читал про LenField
(что в коде пишется как тип), но он вычисляет длину следующих слоев, а не текущего (поэтому в этом случае всегда дает 0).
Есть идеи, как я могу это решить?
Спасибо!