我正在尝试将一个字段添加到数据包中,该字段的类型取决于另一个字段的值。这些“类型”之一是可变长度字符串,带有附加的“ len”属性(如果适用)。
请考虑以下示例:
from scapy.all import *
class TestPacket(Packet):
fields_desc=[
ShortField("index", 0),
ByteEnumField("type", 0 , { 1: "String", 2: "Integer" }),
ConditionalField(FieldLenField("len", None, length_of="data"), lambda x: x.type==1),
ConditionalField(StrLenField("data", "", length_from=lambda pkt:pkt.len), lambda x: x.type==7 or x.type==11),
ConditionalField(IntField("data", 1), lambda pkt: pkt.type==2)]
p = TestPacket(index=12, type=1, data="My Sample String")
p.show2()
p = TestPacket(index=13, type=2, data=5)
p.show2()
问题是,“ len”始终设置为4(IntField的长度,因为它是最后一个“ data”条件字段)。
实现此功能的最佳方法是什么?有不同名称的条件字段?是否将原始字节存储为var长度字符串,无论类型如何?
您可以使用MultipleTypeField。看到https://scapy.readthedocs.io/en/latest/api/scapy.fields.html#scapy.fields.MultipleTypeField
例如:
class DebugPacket(Packet):
fields_desc = [
ByteEnumField("atyp", 0x1, {0x1: "IPv4", 0x3: "DNS", 0x4: "IPv6"}),
MultipleTypeField(
[
# IPv4
(IPField("addr", "0.0.0.0"), lambda pkt: pkt.atyp == 0x1),
# DNS
(DNSStrField("addr", ""), lambda pkt: pkt.atyp == 0x3),
# IPv6
(IP6Field("addr", "::"), lambda pkt: pkt.atyp == 0x4),
],
StrField("addr", "") # By default
),
]
它允许您根据条件使同一字段具有多种类型