python - Scapy - 从 FieldLenField 引用多个字段

标签 python field layer scapy

我已经达到了下一种情况,我需要在 Scapy 中定义一个新的协议(protocol)层,并且其中一个字段具有可变大小(1、2、3 或 4 字节),具体取决于其他特定层的大小。情况是这样的:

class newLayer(Packet):
      name = "newLayer fixed header"
      fields_desc = [
          ByteField("msgtype",0),
              # Some other fields ...
          FieldLenField("length", XXX), # length of newLayer_specific layer
                        # This field can be 1,2,3 or 4 bytes long depending
                        # on the length of the variable header
        ]

class newLayer_specific(Packet):
      name = "variable header"
      fields_desc = [
              FieldLenField("length2","field1"), # This field is always 2 bytes long
              StrLenField("field1","",length_from = lambda pkt:pkt.length2),
              StrLenField("field2","", length_from = lambda pkt:pkt.underlayer.length - pkt.length - 2)
              # 2 is because the length of the length2 field 

bind_layers(newLayer, newLayer_specific, msgtype=1)

我不知道如何从层 newLayer 的字段 length 引用 newLayer_specific 层的大小 有什么建议吗?提前致谢。

最佳答案

由于您在 newLayernewLayerSpecific 之间使用无条件层绑定(bind),因此也许我们可以使用一个单层。在这种情况下,我将使用 adjust 参数来处理此处的长度:

class NewLayer(Packet):
    name = "NewLayer"
    fields_desc = [
        FieldLenField("length", None, length_of="field2",
                      adjust=lambda pkt, val: val + 2 + len(pkt.field1)),
        FieldLenField("length_field1", None, length_of="field1"),
        StrLenField("field1", "", length_from=lambda pkt: pkt.length_field1),
        StrLenField("field2", "",
                    length_from=lambda pkt: pkt.length - pkt.length_field1 - 2),
    ]

现在,我们可以通过运行来测试结果:

NewLayer(field1="test", field2="tototiti")
str(_)
NewLayer(_)

如果您的第一个长度字段具有可变大小,则只需将 FieldLenField 替换为您必须实现的 VariableFieldLenField(示例可以在 here 中找到) )。

如果由于某种原因,您不能或不想仅使用一层,我的建议如下:您可以使用 length_of 参数“作弊”,并使用 调整参数来完成这项工作:

class NewLayer(Packet):
    name = "NewLayer"
    fields_desc = [
        FieldLenField("length", None, length_of="length",
                      adjust=lambda pkt, x: len(pkt.payload)),
    ]

class NewLayerSpecific(Packet):
    name = "NewLayer Specific"
    fields_desc = [
        FieldLenField("length_field1", None, length_of="field1"),
        StrLenField("field1", "", length_from=lambda pkt: pkt.length_field1),
        StrLenField("field2", "",
                    length_from=lambda pkt: (pkt.underlayer.length
                                             - pkt.length_field1 - 2),
        ),
    ]

bind_layers(NewLayer, NewLayerSpecific)

我们可以再次测试:

NewLayer()/NewLayerSpecific(field1="test", field2="tototiti")
str(_)
NewLayer(_)

关于python - Scapy - 从 FieldLenField 引用多个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43721828/

相关文章:

python - printf 在 Python 中将时间格式化为字符串

python - 正则表达式替换的组合乘积

python - 在字段中添加 "UOM"(测量单位) - OpenErp

ios - 自调整 UILabel 与 UIView 子类化

javascript - ESRI javascript API TOC 不适用于 TitledMapService

python - 根据日期和时区计算 tm_isdst

python - 为什么 dict 有这么多操作的最坏情况 O(n)?

javascript - 从子对象修改原型(prototype)上的字段

c# - 反序列化之前在序列化时包含值的空字段

ios - UIView block 动画更新间隔