层长度场

2024-09-29 01:23:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Scapy构建PTPv2协议。 此协议中的消息类型很少,因此我使用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和{},但似乎它们都描述了一个字段的长度,而不是一组字段(据我所知)。在

我也读过LenField(它是作为代码中的类型编写的),但是它计算下一层的长度,而不是当前层的长度(因此在本例中总是给出0)。在

你知道我怎么解决这个问题吗?在

谢谢!在


Tags: lambda协议类型messagepktintfieldmessagetypemessagelength
1条回答
网友
1楼 · 发布于 2024-09-29 01:23:02

这通常是在scapy中使用post_build回调来完成的:(您需要将它添加到您的包中)

(取自inet6.py)

def post_build(self, p, pay):
    # p += pay  # if you also want the payload to be taken into account
    if self.messageLength is None:
        tmp_len = len(p) # edit as you want
        p = p[:2] + struct.pack("!H", tmp_len) + p[4:]  # Adds length as short on bytes 3-4
    return p + pay # edit if previous is changed

然后可以使用ByteField/ShortField。。。而不是伦菲尔德。在

PacketLenField表示使用PacketListField,而{}表示FieldListField

相关问题 更多 >