Scapy - layer's length field

爷,独闯天下 提交于 2019-12-25 02:44:48

问题


I'm trying to build PTPv2 protocol using Scapy. There are few message types in this protocol, so I use ConditionalField to describe the different fields options:

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)

Now, I want the messageLength field to describe the layer's length, and be calculated automatically, depending on the existing fields. It should describe the length of all fields in the PTPv2 layer, starting from the first one (transportSpecific).

I read about PacketLenField and FieldLenField, but it seems they both describe the length of one field, not a group of fields (as far as I understand).

I also read about LenField (which is written as the type in the code), but it calculates the length of the next layers, not the current one (so in this case always gives 0).

Any idea how can I solve this?

Thanks!


回答1:


This is usually done in scapy using the post_build callback, as so: (you need to add it to your packet)

(Taken from 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

You can then use a ByteField/ShortField... accordingly instead of the LenField.

PacketLenField is when you use a PacketListField and FieldLenField is for FieldListField



来源:https://stackoverflow.com/questions/54125711/scapy-layers-length-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!