Работа с LenFields в ScaPy

Я пишу некоторые протоколы в ScaPy, но мне трудно понять, как работают поля len. Прочитав http://trac.secdev.org/scapy/wiki/LengthFields, я м не менее просвещен.

Очевидно, у нас есть то, что они называют «lenfield» (содержит длину поля) и «varfield» (содержит фактическое поле переменной длины). Однако кажется, что единственными полями, которые могут быть varfields, являются PacketLenField, StrFixedLenField и StrLenField. Где остальные поля? Почему вы не можете иметь переменную длину BitField или XBitField?

Например, у меня есть:

BitFieldLenField('lenfield', None, 8, length_of='varfield')

Это правильно возвращает длину 8 (поле, которое я хочу в этом случае, имеет длину 8 октетов/4 шестнадцатеричных пары). Пока все хорошо. Однако, когда я пытаюсь получить это поле, кажется, что мой единственный вариант - это StrLenField, который возвращает что-то вроде "A\x81\x11\x11P 3"

Итак, мой вопрос: как мне вернуть это поле как фактическое шестнадцатеричное значение в пакете? Я что-то упустил во встроенных полях или мне нужно создать что-то вроде XBitLenField?

Спасибо за вашу помощь.


person lightstrike    schedule 23.02.2012    source источник


Ответы (2)


Вы можете переписать объект Fields, например StrLenField:

# String to hex split by space
def str2hex(string):
    return ' '.join('%02x' % ord(b) for b in string)


class XStrLenField(scapy.fields.StrLenField):

    def i2repr(self, pkt, x):
        return str2hex(scapy.fields.StrLenField.i2m(self, pkt, x))

После того, как вы сможете использовать XStrLenField в field_desc[]:

XStrLenField("rand", "", length_from=lambda x: x.len)
person M-L    schedule 31.07.2012

Этот ответ относится к Scapy 2.2.0.

LenFields обычно работают парами, как показано ниже:

FieldLenField("len", None, length_of="data")
StrLenField("data", "", length_from=lambda pkt:pkt.len)

Обратите внимание, как length_of и length_from связывают два поля вместе. Значение length_of сообщает Scapy, как вычислять поле "len" при отправке пакета (обратите внимание, что значение по умолчанию — None, чтобы указать, что оно должно вычисляться автоматически). Значение length_from сообщает Scapy, сколько байтов нужно ввести в поле "data" при разборе пакета.

Существует специальное поле LenField, которое можно использовать отдельно. Обратите внимание еще раз, что значение по умолчанию равно None, что означает, что оно должно рассчитываться автоматически. При отправке Scapy просто рассчитает "len" как количество байтов, следующих за текущим слоем.

LenField("len", None)

Теперь, когда введены поля длины, вы можете использовать Python для кодирования вывода StrLenField в шестнадцатеричный формат.

# In layer definition
BitFieldLenField("lenfield", None, 8, length_of="varfield")
StrLenField("varfield", "", length_from=lambda pkt:pkt.lenfield)

# In main script
print(pck[mylayer].varfield.encode("hex"))    # Replace "mylayer" with the name of your new layer
person phoenix    schedule 16.05.2012