0

I receive in real-time a list of raw packets (bytes) and I want to parse them into scapy without having to write and read them from a pcap.

Here the answer is to use Ether if the first layer is Ether, but what if not?

For example:

>>> pkt.layers()
>>> [scapy.layers.inet6.IPv6, scapy.layers.inet.TCP]
>>> pkt.build()
>>> b'`\x00\x00\x00\x00(\x06@ \x01\x06\x18\x04\x00\x00\x00\x00\x00\x00\x00Q\x99\xccp \x01\x06\x18\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x05\x8c\x9b\x00Pj\xe7\x076\x00\x00\x00\x00\xa0\x02\x160)\x9c\x00\x00\x02\x04\x05\x8c\x04\x02\x08\n\x00\xdd\x1a9\x00\x00\x00\x00\x01\x03\x03\x02'

I can't use Ether(pkt) since pkt has no Ether layer.

But if I write the packet to a pcap file and read it again I can parse it.

>>> wrpcap("/tmp/proof.pcap", pkt)
>>> pcap = rdpcap("/tmp/proof.pcap")                              
>>> type(pcap[0])
scapy.layers.inet6.IPv6

How could I parse packets like wrpcap-rdpcap without writing and reading files all time?

2 Answers2

1

You can use

pkt.__class__(bytes(pkt))

to re-build a packet regardless of its type. It's very unclear what object pkt is in your example but I assumed it was a packet object.

For instance

pkt = Ether()/IP()
pkt.__class__(bytes(pkt))

If you're asking how to dissect bytes that you don't know the type of (without the datalink), the answer is: it's impossible.

Cukic0d
  • 5,111
  • 2
  • 19
  • 48
-1

A way without using pcap files is using hexedit, e.g:

>>> from scapy.all import *
>>> data = b'`\x00\x00\x00\x00(\x06@ \x01\x06\x18\x04\x00\x00\x00\x00\x00\x00\x00Q\x99\xccp \x01\x06\x18\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x05\x8c\x9b\x00Pj\xe7\x076\x00\x00\x00\x00\xa0\x02\x160)\x9c\x00\x00\x02\x04\x05\x8c\x04\x02\x08\n\x00\xdd\x1a9\x00\x00\x00\x00\x01\x03\x03\x02'
>>> pkt = Packet(data)
>>> pkt.build()
b'`\x00\x00\x00\x00(\x06@ \x01\x06\x18\x04\x00\x00\x00\x00\x00\x00\x00Q\x99\xccp \x01\x06\x18\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x05\x8c\x9b\x00Pj\xe7\x076\x00\x00\x00\x00\xa0\x02\x160)\x9c\x00\x00\x02\x04\x05\x8c\x04\x02\x08\n\x00\xdd\x1a9\x00\x00\x00\x00\x01\x03\x03\x02'
>>> test = hexedit(pkt)
>>> type(test[0])
<class 'scapy.layers.l2.Dot3'>

It returns scapy.layers.l2.Dot3 in difference with scapy.layers.inet6.IPv6 because you are using binary data in your code.

>>> data = b'`\x00\x00\x00\x00(\x06@ \x01\x06\x18\x04\x00\x00\x00\x00\x00\x00\x00Q\x99\xccp \x01\x06\x18\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x05\x8c\x9b\x00Pj\xe7\x076\x00\x00\x00\x00\xa0\x02\x160)\x9c\x00\x00\x02\x04\x05\x8c\x04\x02\x08\n\x00\xdd\x1a9\x00\x00\x00\x00\x01\x03\x03\x02'
>>> pkt = Packet(data)
>>> pkt.build()
b'`\x00\x00\x00\x00(\x06@ \x01\x06\x18\x04\x00\x00\x00\x00\x00\x00\x00Q\x99\xccp \x01\x06\x18\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x05\x8c\x9b\x00Pj\xe7\x076\x00\x00\x00\x00\xa0\x02\x160)\x9c\x00\x00\x02\x04\x05\x8c\x04\x02\x08\n\x00\xdd\x1a9\x00\x00\x00\x00\x01\x03\x03\x02'
>>> wrpcap("/tmp/proof.pcap", pkt)
>>> pcap = rdpcap("/tmp/proof.pcap") 
>>> type(pcap[0])
<class 'scapy.layers.l2.Dot3'>
sinkmanu
  • 1,034
  • 1
  • 12
  • 24
  • Ass you see, your method doesn't work.. You parsed it into Dot3 layer not IPv6 – manulqwerty Jan 20 '21 at 13:44
  • @manulqwerty, hexedit function works in the same way that rdpcap function. In this case it parsed into Dot3 in Wireshark too. It is because you wrote binary data as a string... I took your code example. – sinkmanu Jan 20 '21 at 14:05
  • I get the packets in binary daya because I'm using pcapy as sniffer. Now I'm parsing the packets to scapy using `Ether(pkt)` but if the first layer is not "Ether" it won't work. You are using `Packet(pkt)` to parse it into SCAPY, but it doesn't work like that. – manulqwerty Jan 20 '21 at 15:19
  • So, which is the difference between hexedit and wrpcap-rdpcap? I have run your code and obtain the same results for both. – sinkmanu Jan 20 '21 at 15:22