Scapy - поле длины слоя - PullRequest
       16

Scapy - поле длины слоя

0 голосов
/ 10 января 2019

Я пытаюсь построить протокол 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).

Есть идеи, как мне это решить?

Спасибо!

1 Ответ

0 голосов
/ 10 января 2019

Обычно это делается в 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 ... соответственно вместо LenField.

PacketLenField - это когда вы используете PacketListField, а FieldLenField - для FieldListField

...