[enhancement] Provide a kind of packet that doesn't expect a payload
In order to make it easier to integrate with packet fields.
The following example intends to make use of PacketListField:
class B0(Packet):
fields_desc = [
ByteField("value", default=0)
]
class A0(Packet):
fields_desc = [
PacketListField("b", pkt_cls=B0, count_from=lambda pkt: 2, default=[])
]
a0 = A0(bytes.fromhex("0102"))
a0.show()
Output:
###[ A0 ]###
\b \
|###[ B0 ]###
| value = 1
|###[ Raw ]###
| load = b'\x02'
While parsing B0 items,
Scapy does not break dissection once the first item has been analyzed,
and continues on considering that the remaining content is the payload of the latter.
For the concern, the length_from parameter of the PacketLenField
makes it convenient to restrict the amount of data to parse for a given packet field.
class B1(Packet):
fields_desc = [
ByteField("value", default=0)
]
class A1(Packet):
fields_desc = [
FieldListField(
"b",
field=PacketLenField("", B1(), B1, length_from=lambda pkt: 1),
count_from=lambda pkt: 2,
default=[],
),
]
a1 = A1(bytes.fromhex("0102"))
a1.show()
Output:
###[ A1 ]###
b = [<B1 value=1 |>, <B1 value=2 |>]
Or, another trick to override the extract_padding() method for the final class
to let Scapy know there's no payload to parse:
class B2(Packet):
fields_desc = [
ByteField("value", default=0)
]
def extract_padding(self, s):
return b'', s
class A2(Packet):
fields_desc = [
PacketListField("b", pkt_cls=B2, count_from=lambda pkt: 2, default=[])
]
a2 = A2(bytes.fromhex("0102"))
a2.show()
Output:
###[ A2 ]###
\b \
|###[ B2 ]###
| value = 1
|###[ B2 ]###
| value = 2
Proposal: provide a FinalPacket class that implements this no-payload trait.
class FinalPacket(Packet):
def extract_padding(self, s):
return b'', s
class B3(FinalPacket):
fields_desc = [
ByteField("value", default=0)
]
class A3(Packet):
fields_desc = [
PacketListField("b", pkt_cls=B3, count_from=lambda pkt: 2, default=[])
]
a3 = A3(bytes.fromhex("0102"))
a3.show()
Output:
###[ A3 ]###
\b \
|###[ B3 ]###
| value = 1
|###[ B3 ]###
| value = 2
If of interest, I may provide a PR for that.
Possibly related to #1021?