Scapy: добавление нового протокола со сложными группировками полей - PullRequest
5 голосов
/ 10 ноября 2011

Я пытаюсь указать новый формат пакета, используя scapy.В пакете есть список элементов, а элементы состоят из «сгруппированных полей».Под «сгруппированными полями» я подразумеваю подпоследовательность полей разных типов.Единственный способ создания «сгруппированных полей», о которых я знаю, в scapy - это использование класса Packet и использование FieldLenField / PacketListField для ссылки на длину последовательности и тип членов списка.Это путь?Что-то похожее на это:

from scapy.packet import Packet
from scapy.fields import *

class RepeatingGroupedSequence(Packet):
    name = "Simple group of two fields"

    fields_desc = [IntField('field1', 1), 
                   IntField('field2', 2)]

class TopLayer(Packet):
    name = "Storage for Repeating Sequence"

    fields_desc = [FieldLenField("length", None, count_of='rep_seq'),
                   PacketListField('rep_seq', None, RepeatingGroupedSequence, 
                                   count_from = lambda pkt: pkt.length),
                  ]

#Now here is the problem that I have with assembling PacketListField: 

#craft TopLayer packet
p = TopLayer()

#add two "repeated sequences"
p.rep_seq = [ RepeatingGroupedSequence(), RepeatingGroupedSequence() ]

#both sequences can observed
p.show()

#but the underlying structure of the repeated sequence is #Raw# at this stage
p.show2()

#length is 2
print p.rep_seq, 'length:', len(p.rep_seq)

#but the cloned packet has only one "repeated sequence", the rest is raw
clone = TopLayer(str(p))
clone.show()

#length is 1
print clone.rep_seq, 'length:', len(clone.rep_seq)

Проблема этого подхода заключается в том, что структура группировки не сохраняется при повторной сборке пакета.При сборке второй экземпляр RepeatedSequence обрабатывается как необработанное тело, даже если поле count равно 2. Как добавить RepeatingSequences таким образом, чтобы структура сохранялась при повторной сборке?Есть ли способ сгруппировать поля, не прибегая к Packet в качестве типа хранения списков?

1 Ответ

7 голосов
/ 12 ноября 2011

Класс RepeatingGroupedSequence необходимо перезаписать extract_padding метод:

def extract_padding(self, s):
    return '', s

По умолчанию каждый подпакет обрабатывает все как принадлежащее своему слою, то есть:

def extract_padding(self, s):
    return s, None

Иэто не то, что используется для группирования.Может кто-нибудь уточнить разницу между заполнением и разделением слоев?

...