I am currently modifying a pcap
file (on a Linux system) using scapy
in Python. I do this for two reasons:
tcpreplay
or scapy
's own sendp(...)
. Trimming down the load should (if I'm not mistaken) allow me to go around this problem.Here is a small example of what I do (I use ipython
):
from scapy.all import rdpcap, wrpcap
from scapy.utils import sendp
import re
# Load PCAP file. In my case I have 24 packets
pkts = rdpcap('dump.pcap')
# Change the load of packet 16 by removing some of the data inside
pkts[16].load = re.sub(r'<Stop[0-9]+>[0-9]+</Stop[0-9]+>', '', pkts[16].load)
# Write the changes to a new file
wrpcap('dump_edited.pcap', pkts)
# and send those (the operation requires admin privileges!)
sendp(pkts) # or use tcpreplay in the terminal
Now the problem is that editing the load in this way means that other properties related to it will not get updated. For example if the length was previously 2982 (using pkts[16].show()
you can get a detailed overview of the packet's properties) after editing its load the length is still the same. Checksum doesn't change also. This is of course expected since all I'm doing is directly edit the string, which clearly doesn't trigger any updates of the packets properties.
I've just discovered scapy
so the question is probably too obvious but is there a way to alter the load in such a way that its properties also get updated automatically?
Scapy avoid doing things without the coder wanting it. For instance, you must be able to specify manually a wrong checksum for your tests, without having scapy modifying it.
In general, when a property is None
, then scapy calculates the value automatically. For instance, set all the checksums and the lengths to None
, and scapy will calculate them for you based on the packet when building.
If you don’t want to write it, you can also build it using
pkt = Ether(bytes(pkt))
(Supposing Ether is the lowest layer), after having set the values to None, this also recalculate the checksums
A packet will also be built while doing wrpcap(..)
, bytes(packet)
or packet.show2()
This should fix your problem