I'm putting together a new protocol layer in scapy. I'm using a packetfield to represent a len-value pair within the protocal. I can get the layer to build a packet.  .show() and hexdump() show the packet fields as expected.  .show2() however is a different story.
I have something similar too:
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)
                  ]
If I construct a packet as such:
p = foo()
p.fld3 = bar(val="one")
p.fld4 = bar(val="two")
p.fld5 = bar(val="three")
p.show() and hexdump(p) work as expected.
However, p.show2() builds the packet just fine but fails to dissect the packet string.  Fields 1 - 3 dissect as expected (fld3.len even gets properly calculated).  Dissection stop here.  The remaining bytes become Raw payload to fld3, and fields 4 - 7 get nothing.
I've attempted to bind_layers(foo, bar) and get the same results.  Based on reading here, in the scapy documentation, and in various scapy protocol files, I think something needs to be done in bar.post_dissect(), but I'm not sure what.
How do I get bar to relinquish its remaining raw payload back to foo for further dissection?
I have solved it, I've just added an extract_padding function to the Bar class, the Code is like:
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)
                  ]
If you review the Scapy documentation, it tells:
I run this code and this is the result:
###[ 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
Process finished with exit code 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With