You have made a packet capture (.pcap file) of the live traffic and you want to see whether your firewall will be able to handle this traffic. Whether you are trying to debug a rule or testing a new firewall configuration on your staging setup, you will need a tool that can replay this traffic.
Scapy is the right tool for this purpose. It's a Python library that lets you craft, send, and receive network packets at a low level. With Scapy, you can read a .pcap file and send every packet out onto your network exactly as it was captured.
Let me show you how to build a practical network traffic replayer step by step.
⚠️ Legal and Ethical Disclaimer
It’s important that you understand one thing before I proceed with the guide.
This guide is for educational and legitimate testing purposes only. Network traffic replaying may affect your network operations, generate security alerts and even become illegal.
You must:
- Have explicit written permission from the owner of any network you test
- Only use this tool in your own lab or staging environment
- Never use it on networks you don't own or control
- Comply with all applicable laws and your organization's security policies
- Understand that unauthorized network testing is illegal in many jurisdictions
I am not responsible for any misuse of this information. You are solely responsible for ensuring that your use of these techniques is legal, authorized, and ethical.
If you're not sure whether you have permission to test, ask first. If you can't ask, don't do it.
Requirements
First, here is what you need before we begin:
- Installation of Python version 3.6 or above
- Installation of Scapy library using pip (pip install scapy)
- .pcap file of the network traffic to be replayed
- Environment in which the traffic replay can happen without any issues
- Privileges of an administrator or a root user (necessary for sending raw packets)
In case you do not have Scapy, install it using this command:
pip install scapyIn Linux, it is also required that you install libpcap:
sudo apt-get install python3-scapyStep 1: Understanding Your .pcap File
A .pcap file contains captured network packets. Each of these packets contains the raw data transmitted across the wire, which is accompanied by header information from such protocols as Ethernet, IP, TCP, UDP, and others.
Traffic replayer is a tool that allows you to take these packets and replay them in your network. This way, you will be able to observe the behavior of your firewall and other network equipment in response to the traffic.
Information to remember about your .pcap file:
- Which is the protocol? (TCP, UDP, ICMP and so on)
- What are the source and destination IP addresses?
- What are the ports of the source and destination?
- Is HTTP, DNS, or some other application layer protocol being used?
This all is processed automatically by Scapy, so there is no need to process it manually.
Step 2: Simple Script using Scapy to Read and Replay Packets
Now let’s look at the most simple script. The script is going to read the packets from the .pcap file and forward it on the network.
from scapy.all import rdpcap, sendp
def replay_traffic(pcap_file, interface="eth0"):
# Read packets from the pcap file
packets = rdpcap(pcap_file)
print(f"Read {len(packets)} packets from {pcap_file}")
# Send each packet out on the specified interface
for packet in packets:
sendp(packet, iface=interface)
print(f"Sent packet {packet.summary()}")
print("Finished replaying traffic")
# Example usage
if __name__ == "__main__":
replay_traffic("captured_traffic.pcap", "eth0")
Here is what this script does:
- rdcap() reads the .pcap file and outputs a list of packets
- For each packet in that list, we run a loop
- sendp() sends each packet at layer 2(Ethernet)
Run the script:
sudo python3 replay.pyYou will notice that the script is outputting each packet sent, along with a summary of what's in the packet.
Step 3: Implementing Speed Control
This simple script will send packets at maximum speed; however, that may not be practical. Real packet traffic has timing between packets. Delays can be used to simulate realistic traffic.
Following is a modified script that will maintain the timing between packets:
import time
from scapy.all import rdpcap, sendp
def replay_with_timing(pcap_file, interface="eth0"):
packets = rdpcap(pcap_file)
print(f"Read {len(packets)} packets from {pcap_file}")
# Track packet timing
previous_time = None
total_packets = len(packets)
for i, packet in enumerate(packets):
current_time = packet.time
# Calculate delay since previous packet
if previous_time is not None:
delay = current_time - previous_time
if delay > 0:
time.sleep(delay)
# Send the packet
sendp(packet, iface=interface, verbose=False)
# Print progress
if (i + 1) % 10 == 0:
print(f"Sent {i+1}/{total_packets} packets")
previous_time = current_time
print(f"Finished replaying {total_packets} packets")
if __name__ == "__main__":
replay_with_timing("captured_traffic.pcap", "eth0")Changes made:
- Script is modified to check timestamp of each packet obtained from the pcap file
- It calculates delay between each two packets
- Then it sleeps for that particular period before sending the packet
- Thus original timings are maintained
Step 4: Modifying Packets Before Sending
When you replay traffic against a staging environment, you often need to modify the packets. For example, the source IP addresses in your pcap probably point to the original sender's IP. Without the IP in your staging environment, your routing might not be correct.
An example of a script used to change the source and destination IPs follows:
from scapy.all import rdpcap, sendp
from scapy.all import IP
def replay_with_ip_rewrite(pcap_file, interface="eth0",
new_src_ip="192.168.1.100",
new_dst_ip="192.168.1.200"):
packets = rdpcap(pcap_file)
print(f"Read {len(packets)} packets")
sent_count = 0
for packet in packets:
# Check if the packet has an IP layer
if packet.haslayer(IP):
# Create a copy of the packet
modified_packet = packet.copy()
# Replace the source IP
modified_packet[IP].src = new_src_ip
# Replace the destination IP
modified_packet[IP].dst = new_dst_ip
# Send the modified packet
sendp(modified_packet, iface=interface,
verbose=False)
sent_count += 1
else:
# If it's not IP traffic, skip it or send as-is
# You might want to handle other protocols here
pass
if sent_count % 10 == 0:
print(f"Sent {sent_count} packets")
print(f"Finished replaying {sent_count} packets")
if __name__ == "__main__":
replay_with_ip_rewrite("captured_traffic.pcap", "eth0",
"192.168.1.100", "192.168.1.200")What does it do:
- It checks if there is any IP layer in that packet
- Yes, then it makes a copy of that packet and modifies IP source and IP destination
- It sends this packet to the network
Practical use case of this:
Let’s say you captured packets from your production network. Source IPs are production servers and destination IPs are production services. In your staging setup, you have other IPs. Changing IPs will help you forward this traffic into your staging servers.
Step 5: Adding MAC Address Rewriting
In many networks, MAC addresses also matter. If you’re operating within a different subnet or VLAN in your testing environment, your pcap file MAC addresses may no longer be valid.
Here’s a simple script for changing the IP and MAC addresses:
from scapy.all import rdpcap, sendp, Ether, IP
def replay_with_mac_rewrite(pcap_file, interface="eth0",
new_src_ip="192.168.1.100",
new_dst_ip="192.168.1.200"):
# Get the MAC address of your interface
import socket
import fcntl
import struct
def get_mac_address(iface):
try:
s = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)
info = fcntl.ioctl(s.fileno(), 0x8927,
struct.pack('256s', iface[:15].encode('utf-8')))
return ':'.join(f'{b:02x}' for b in info[18:24])
except:
return None
my_mac = get_mac_address(interface)
if not my_mac:
print("Could not get MAC address for interface")
return
packets = rdpcap(pcap_file)
print(f"Read {len(packets)} packets")
sent_count = 0
for packet in packets:
modified_packet = packet.copy()
# Handle Ethernet layer
if modified_packet.haslayer(Ether):
modified_packet[Ether].src = my_mac
# The destination MAC might need to
be changed based on your network
# Handle IP layer
if modified_packet.haslayer(IP):
modified_packet[IP].src = new_src_ip
modified_packet[IP].dst = new_dst_ip
sendp(modified_packet, iface=interface,
verbose=False)
sent_count += 1
if sent_count % 10 == 0:
print(f"Sent {sent_count} packets")
print(f"Finished replaying {sent_count} packets")
if __name__ == "__main__":
replay_with_mac_rewrite("captured_traffic.pcap", "eth0")Step 6: Practical Scenario – Testing a Firewall Rule
Here is an entire practical scenario for testing a firewall rule. The rule you want to test is supposed to block traffic from a particular source IP address on a particular port number.
Your production network has already had traffic captured, and now you have to replay that same traffic in your staging firewall network so you can test out the rule.
The script:
#!/usr/bin/env python3
"""
Network Traffic Replayer for Firewall Testing
Replays a .pcap file against a staging environment
"""
import time
import sys
from scapy.all import rdpcap, sendp, IP, TCP, UDP, Ether
class TrafficReplayer:
def __init__(self, pcap_file, interface="eth0"):
self.pcap_file = pcap_file
self.interface = interface
self.packets = []
self.stats = {
"total": 0,
"sent": 0,
"tcp": 0,
"udp": 0,
"icmp": 0,
"errors": 0
}
def load_packets(self):
try:
self.packets = rdpcap(self.pcap_file)
self.stats["total"] = len(self.packets)
print(f"[+] Loaded {self.stats['total']}
packets from {self.pcap_file}")
return True
except Exception as e:
print(f"[-] Failed to load pcap file: {e}")
return False
def analyze_traffic(self):
"""Analyze the traffic to understand
what we're replaying"""
tcp_count = 0
udp_count = 0
icmp_count = 0
for packet in self.packets:
if packet.haslayer(TCP):
tcp_count += 1
elif packet.haslayer(UDP):
udp_count += 1
elif packet.haslayer(ICMP):
icmp_count += 1
self.stats["tcp"] = tcp_count
self.stats["udp"] = udp_count
self.stats["icmp"] = icmp_count
print(f"[+] Traffic analysis:")
print(f" - TCP: {tcp_count} packets")
print(f" - UDP: {udp_count} packets")
print(f" - ICMP: {icmp_count} packets")
def replay(self, speed=1.0, target_ip=None):
"""
Replay the traffic
speed: 1.0 = original speed, 2.0 = double speed,
0.5 = half speed
target_ip: If provided, rewrite destination IP
to this address
"""
if not self.packets:
print("No packets to replay. Did you load the file?")
return
print(f"[>] Starting replay on interface
{self.interface}")
print(f" Speed: {speed}x")
if target_ip:
print(f" Rewriting destination IP to:
{target_ip}")
previous_time = None
sent_count = 0
for i, packet in enumerate(self.packets):
try:
# Create a copy to modify
modified_packet = packet.copy()
# If target_ip is provided, rewrite destination
if target_ip and modified_packet.haslayer(IP):
modified_packet[IP].dst = target_ip
# Handle timing
current_time = packet.time
if previous_time is not None and speed > 0:
delay = (current_time - previous_time)
/ speed
if delay > 0:
time.sleep(delay)
# Send the packet
sendp(modified_packet, iface=
self.interface, verbose=False)
sent_count += 1
# Progress update
if sent_count % 100 == 0:
print(f" Sent {sent_count} /
{self.stats['total']} packets")
previous_time = current_time
except Exception as e:
self.stats["errors"] += 1
print(f" [-] Error sending packet {i}: {e}")
self.stats["sent"] = sent_count
print(f"\n[+] Replay completed!")
print(f" Total packets: {self.stats['total']}")
print(f" Successfully sent: {self.stats['sent']}")
print(f" Errors: {self.stats['errors']}")
def main():
# Configuration
PCAP_FILE = "production_traffic.pcap"
INTERFACE = "eth0"
TARGET_IP = "192.168.1.50" # Your staging firewall's IP
print("=" * 50)
print("NETWORK TRAFFIC REPLAYER")
print("=" * 50)
# Create the replayer
replayer = TrafficReplayer(PCAP_FILE, INTERFACE)
# Load and analyze
if not replayer.load_packets():
sys.exit(1)
replayer.analyze_traffic()
# Ask user to confirm
print("\n[!] This will send traffic out on your network.")
confirm = input("Continue? (y/n): ")
if confirm.lower() != 'y':
print("Cancelled.")sys.exit(0)
# Start replay
try:
replayer.replay(speed=0.5, target_ip=TARGET_IP)
except KeyboardInterrupt:
print("\n[!] Replay stopped by user")
except Exception as e:
print(f"\n[-] Unexpected error: {e}")
if __name__ == "__main__":
main()Key Points & Tips
- Testing should always be done in the staging environment. Testing on the production network may have an impact on your business operations. All your tests must be performed in the staging environment.
- Check your network. Ensure that the staging environment is isolated from the live environment. You do not want your test traffic on the live network.
- Monitor the firewall logs. The point of replaying traffic is to see how your firewall responds. Watch the logs carefully while the replay is running.
- Make sure the right interface is chosen. Make sure you are sending the packets through the right network interface. If there is any doubt about the interface being used, just do an “ip link show” on Linux and “ipconfig” on Windows.
- Speed must be set during analysis. During the process of firewall log analysis, ensure that the speed is slowed down to make the correlation between the two possible.
- Take into consideration two-way traffic. The firewall handles traffic both ways and thus the tests should include testing both ingress and egress rules.
- Be in line with your organization’s policy. Ensure that you have the authorization to carry out the test.
FAQ Section
What is Scapy and why use it for traffic replay?
Scapy is a Python library that enables packet crafting and transmission on the network. Traffic replay is one of the major applications of Scapy since it allows full control over the transmitted packets.
Can I replay traffic from a .pcap file without modifying the IP addresses?
Yes, you can send packets exactly as they were captured. However, this might not work in a different network environment because the IP addresses might not be reachable.
What happens if I replay traffic on my network?
Your network devices will see the replayed traffic exactly as if it were genuine. It will be forwarded, switched, and processed normally. This is why you should only use it in a staging environment.
Is it possible for me to use this tool to test other network devices apart from firewalls?
Yes. It is also possible to capture the traffic to test other network devices such as Intrusion Detection Systems, Load Balancers, routers and switches.
What is the reason why I need root/administrator privileges?
Raw packet sending needs access to network socket interface, and that access is available only to privileged users.
But what if my traffic does not reach the firewall after the replay?
Your networking settings are not correct. You need to make sure that you have the correct MAC and IP addresses on your staging network. There are instances when you need to change the MAC address.