Reputation: 121
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?
Upvotes: 4
Views: 2969
Reputation: 46
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
Upvotes: 3