Get all the layers in a packet
Each additional layer is the payload of a packet, so you can iterate
def expand(x):
yield x
while x.payload:
x = x.payload
yield x
and then
res = list(expand(packet))
I hope that is what you meant.
Use packet.getLayer(<id>)
in a loop. For example:
from scapy.all import Ether
def get_packet_layers(packet):
counter = 0
while True:
layer = packet.getlayer(counter)
if layer is None:
break
yield layer
counter += 1
packet = 'ffffffffffff00ffd59c64320806000108000604000100ffd59c6432000000000000000000000a000001'.decode('hex')
packet = Ether(_pkt=packet)
for layer in get_packet_layers(packet):
print (layer.name)
outputs
Ethernet
ARP
I looked at the source code and didn't find such a method, so I altered cronos's code a bit and it looks like it does what you want now.
You could write a bug report for scapy and suggest a new method.
>>> ip = Ether()/IP()/TCP()
>>> ip
<Ether type=0x800 |<IP frag=0 proto=tcp |<TCP |>>>
>>> ip.name
'Ethernet'
>>> def expand(x):
... yield x.name
... while x.payload:
... x = x.payload
... yield x.name
...
>>> list(expand(ip))
['Ethernet', 'IP', 'TCP']
>>> l=list(expand(ip))
>>> ":".join(l)
'Ethernet:IP:TCP'
>>>