manulqwerty
manulqwerty

Reputation: 11

Scapy read packets from bytes

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?

Upvotes: 0

Views: 4073

Answers (2)

Cukic0d
Cukic0d

Reputation: 5411

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.

Upvotes: 1

sinkmanu
sinkmanu

Reputation: 1102

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'>

Upvotes: -1

Related Questions