它们只是对不同类型的对象进行操作。看scapy 构建解剖 http://www.secdev.org/projects/scapy/doc/build_dissect.html
数据包列表字段
描述了一个列表数据包字段同一类型,而一个数据包字段代表一个Packet类型对象放入另一个数据包字段中。它以数据包原型作为第三个参数cls __init__(self, name, default, cls, count_from=None, length_from=None)
。 PacketListField 的构造函数需要设置 count_from (对象数量)或 lengt_from (字节)参数,以便了解要传递到数据包列表的字节数或要解析的对象数。(例如,您可以有BGPUpdate
作为 PacketField 或 PacketListField 的原型)。
例如:
PacketListField("total_path", [], BGPPathAttribute, length_from = lambda p: p.tp_len),
创建一个名为“total_path”的字段,默认值为空列表 [],并尝试将 raw_bytestream 的 length_from 字节解析为 BGPPathAttribute(Packet)。
字段列表字段
相比之下字段列表字段将 Field 作为原型并尝试将 raw_bytestream 剖析为原型字段列表__init__(self, name, default, field, length_from=None, count_from=None):
FieldListField("withdrawn",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.withdrawn_len),
字段长度
通常最多可容纳 length_from 字节的 DataField__init__(self, name, default, fld=None, length_from=None):
.
场Len场
保存同一数据包中另一个字段长度的数字字段__init__(self, name, default, length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
class SomePacket(Packet):
name = "SomePacket"
fields_desc = [ByteEnumField("type", 0x00, {0x00:"SomeType"}),
FieldLenField("length", None, length_of="data"), # hold length of data
StrLenField("data", "", length_from=lambda x:x.length), # holds data
]
解剖中, scapy 会将第一个字节放入“type”,接下来的 2 个字节(默认 fmt="H" 表示短整型“length”,最多将“length”个字节放入“data”
On build,scapy会自动用len(data)填充'length'。
数据包长度字段
是一个将 length_from 字节解析为一个原型数据包的字段__init__(self, name, default, cls, length_from=None):
class AnotherPacket(Packet):
name = "AnotherPacket"
fields_desc = [
BLenField("length", None, length_of="data"),
PacketLenField("data", None, SomePacket, length_from=lambda x:x.length),]
]
解剖中,scapy 会将第一个字节放入 ByteLengthField 'length' 中,并将最多 'length' 个字节解析为 'SomePacket' 放入 'data' 中
On build,scapy 会自动用序列化 SomePacket 的大小填充“length”。