代码之家  ›  专栏  ›  技术社区  ›  Shir

scapy-层的长度字段

  •  0
  • Shir  · 技术社区  · 6 年前

    我正在尝试使用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 FieldLenField 但它们似乎都描述了一个字段的长度,而不是一组字段(据我所知)。

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

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

    谢谢!

    1 回复  |  直到 6 年前
        1
  •  1
  •   Cukic0d    6 年前

    这通常是用 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
    

    然后可以使用字节字段/短字段…相应地,而不是Lenfield。

    PacketLenField 当你使用 PacketListField FieldLenField 是为了 FieldListField