使用scapy数据包字段

时间:2016-07-13 21:38:24

标签: scapy

我在scapy中整理了一个新的协议层。我使用数据包字段来表示协议中的len-value对。我可以获得该层来构建数据包。 .show()hexdump()按预期显示数据包字段。 .show2()然而却是另一回事。

我也有类似的东西:

class bar(Packet):
    name="Bar Packet"
    fields_desc = [
                    FieldLenField("len", None, length_of="val", fmt="!H"),
                    StrLenField("val", "", length_from=lambda p:p.len)
                  ]

class foo(Packet):
    name="Foo Packet"
    fields_desc = [
                    XByteField("fld1", 0x00),
                    XByteField("fld2", 0x00),
                    PacketField("fld3", '', bar),
                    PacketField("fld4", '', bar),
                    PacketField("fld5", '', bar),
                    XByteField("fld6", 0x00),
                    XByteField("fld7", 0x00)
                  ]

如果我这样构建一个数据包:

p = foo()
p.fld3 = bar(val="one")
p.fld4 = bar(val="two")
p.fld5 = bar(val="three")

p.show()hexdump(p)按预期工作。

但是,p.show2()构建数据包很好,但无法剖析数据包字符串。字段1 - 3按预期剖析(fld3.len甚至得到正确计算)。解剖在这里停止。剩余的字节变为原始有效载荷到fld3,而字段4-7什么都没有。

我试图bind_layers(foo, bar)并获得相同的结果。根据这里的阅读,在scapy文档和各种scapy协议文件中,我认为需要在bar.post_dissect()中完成某些事情,但我不确定是什么。

如何让bar将剩余的原始有效负载放回foo进行进一步解剖?

1 个答案:

答案 0 :(得分:2)

我已经解决了,我刚刚在Bar类中添加了一个extract_padding函数,代码如下:

class Bar(Packet):
name = "Bar Packet"
fields_desc = [
                FieldLenField("len", None, length_of="val", fmt="!H"),
                StrLenField("val", 0, length_from=lambda pkt:pkt.len)
              ]

def extract_padding(self, p):
    return "", p

class Foo(Packet):
name = "Foo Packet"
fields_desc = [
                XByteField("fld1", 0x00),
                XByteField("fld2", 0x00),
                PacketField("fld3", "", Bar),
                PacketField("fld4", "", Bar),
                PacketField("fld5", "", Bar),
                XByteField("fld6", 0x00),
                XByteField("fld7", 0x00)
              ]

如果您查看Scapy文档,它会告诉:

  • extract_padding()是一个重要的函数,应该由每个包含自己大小的层调用,以便它可以在有效负载中分辨出与该层真正相关的内容以及将被视为附加填充字节的内容。

我运行此代码,结果如下:

###[ Foo Packet ]###
  fld1      = 0x0
  fld2      = 0x0
  \fld3      \
   |###[ Bar Packet ]###
   |  len       = 3
   |  val       = 'one'
  \fld4      \
   |###[ Bar Packet ]###
   |  len       = 3
   |  val       = 'two'
  \fld5      \
   |###[ Bar Packet ]###
   |  len       = 5
   |  val       = 'three'
  fld6      = 0x0
  fld7      = 0x0

处理完成,退出代码为0