17

Using the python packet parsing/sniffing tool Scapy, I would like to create a packet from a raw byte-string. While the details of my specific use-case are more realistic, the following example illustrates my problem and my present attempt:

# Get an example packet (we won't really have an offline file in production.)
pkt = sniff(offline="./example_packets/example_packets2.pcap")

# Convert it to raw bytes -- oddly __str__ does this.
raw_packet = str(pkt)

# Current, broken, attempt to construct a new packet from the same bytes as the old.
# In truth, there are easier ways to copy packets from existing Scapy packets, but
# we are really just using that offline packet as a convenient example.
new_packet = Packet(_pkt=raw_packet)

# Sadly, while this packet has the bytes internally, it no longer has the
# interpretations of the layers like the original packet did (such as saying that
# the packet is ARP and has these field values, etc.
print repr(new_packet)

How can I produce a new_packet from raw bytes that will look the same as if it were sniffed from a pcap file?

icfy
  • 173
  • 1
  • 1
  • 6

1 Answers1

16

There is no way for Scapy to guess the first layer of your packet, so you need to specify it.

You can do so by using the appropriate Packet subclass. For example, say your packet's first layer is Ethernet, use Ether(raw_packet) instead of Packet(raw_packet).

Pierre
  • 6,047
  • 1
  • 30
  • 49
  • 1
    If the `Ether` class is used, will Scapy be able to determine the other layers automatically? It seems that the `sniff` function somehow figures out the other layers. – BlackVegetable Dec 03 '14 at 13:58
  • 1
    If by other layers you mean the layers on top of the Ethernet layer, the answer is yes, thanks to the `type` field. – Pierre Dec 03 '14 at 14:01
  • Of course! That should've been obvious to me. Thanks for the clarification. (How else would routers know how to interpret the other layers if not for type information?) – BlackVegetable Dec 03 '14 at 14:06
  • 4
    Use `from scapy.layers.l2 import Ether` to get `Ether`. I got this by grepping through the installed library code. – jtpereyda Jan 08 '16 at 01:06