Pages

Replaying packets with tcpreplay

Tcpreplay is a suite of tools that allows editing and replaying previously captured traffic in libpcap format. This can come handy in many situations, one common use is traffic pattern based behavior re-creation in a lab environment.
Tcpreplay suite comes with the following tools:
  • tcpprep - multi-pass pcap file pre-processor which determines packets as client or server and creates cache files used by tcpreplay and tcprewrite
  • tcprewrite - pcap file editor which rewrites TCP/IP and Layer 2 packet headers
  • tcpreplay - replays pcap files at arbitrary speeds onto the network
  • tcpliveplay - Replays network traffic stored in a pcap file on live networks using new TCP connections
  • tcpreplay-edit - replays; edits pcap files at arbitrary speeds onto the network
  • tcpbridge - bridge two network segments with the power of tcprewrite
  • tcpcapinfo - raw pcap file decoder and debugger
To exemplify the use of tcpreplay, let's say we have the following setup:
Now in this setup we're interested in how our DUT device (Device Under Test) is reacting given a specific traffic pattern that is let's say very specific to this environment. I will assume the DUT is a Layer 3 device. 

I will take different scenario of interest and show how tcpreplay helps.

Scenario 1:  The interesting traffic pattern is unidirectional only from the client. We are not interested in what the server sends. In this case a packet capture file (I name it original.pcap) can be taken between the client  and the DUT and subsequently replayed in a lab environment. I'll assume the packet capture was taken on the client itself in this example and the traffic was unidirectional. The tcpreplay environment will look as below:
The traffic capture should have the following characteristics:
Source MAC address: client MAC address / Source IP: 192.168.0.1
Destination MAC address: router MAC address / Destination IP: 172.16.0.1

Let's  assume that the device running tcpreplay is a Linux device and the interface connecting it to the DUT is eth0. 
What we want to do first is to rewrite the MAC addresses of the traffic (at least the destination MAC address) in order to reflect the devices involved in the traffic at replay time (source MAC address would be the tcpreplay's eth0 interface (eg. 00:11:11:11:11:11), destination mac address would be of the DUT's interface connecting  to the tcpreplay box(eg. 00:22:22:22:22:22))
To do this we can use tcprewrite:
tcprewrite --enet-dmac=00:22:22:22:22:22 --enet-smac=00:11:11:11:11:11:11 --infile=original.pcap --outfile=rewritten.pcap
Now we should have a file named rewritten.pcap with the source and destination MAC addresses rewritten. The characteristics of the rewritten.pcap are now transformed to:
Source MAC address: tcpreplay eth0  MAC address / Source IP: 192.168.0.1
Destination MAC address: DUT MAC address / Destination IP: 172.16.0.
We can use now tcpreplay to replay this traffic now:
tcpreplay --intf1=eth0 rewritten.pcap
Scenario 2: The interesting traffic pattern is bidirectional. We are interested in both what the client sends as well as what the server sends. In this case a packet capture file can be taken anywhere between the client  and the DUT. Now here the best option is to get the 2 packet captures: one between the client and the DUT and another between the DUT and the server and then merge them into one file. This would give us the client side packets as well as the server side packets before they are processed by the DUT. A tool to merge packet captures is mergecap and very quickly, let's say that we have 2 capture files taken:

client.pcap - taken in between the client and the router and contains packets client -> server
server.pcap - taken in between the DUT and the server and contains packets server -> client
We can merge the 2 pcaps above with the command:
mergecap -w merged.pcap client.pcap server.pcap
merged.pcap is the merged output file.

The tcpreplay environment will look like below:
The packet capture file, before processing it would have the endpoint IP addresses of the client/server (192.168.0.1 and 172.16.0.1) and the MAC addresses of  the client/router and server/DUT from the 1st image.
What we want to do is:
  1.   to define in our packet capture what traffic belongs to the server side and which traffic belongs to the client side
  2.   to rewrite the MAC endpoints so that they reflect our tcpreplay environment
  3.   to replay the traffic as it is in the packet capture (some packets being sent by the client and some by the server)
Let's take it step by step.
    1. First we define which packets belong to the client and which to the server. This is done with the help of tcpprep. There are several options on how to make this separation (by IP address space - CIDR, by source MAC address, by port number, by regular expression). There are also some auto modes based on client/server traffic type, but I won't cover this here. You can check the tcpprep documentation. By default the matched packets will be associated with server side traffic. 
The result of tcpprep operation will be a cachefile  that will hold information about which packets belong to which side (client/server). Let's split the packet capture we have based on CIDR:
tcpprep --cidr=172.16.0.0/24 --pcap=merged.pcap --cachefile=merged.cache
The above means all packets being sent from 172.16.0.0/24 are server sent packets. All other packets are client side packets. The file merged.cache is the file holding the information about packets direction (server/client side packets).
    2. We want to rewrite the MAC addresses of the original merged.pcap packet capture to reflect the source/destination MAC addresses of our tcpreplay environment (DUT and computer running tcpreplay). We can use tcprewrite for this:
tcprewrite --enet-dmac=00:22:22:22:22:23,00:22:22:22:22:22 --enet-smac=00:11:11:11:11:11:12,00:11:11:11:11:11:11 --cachefile=merged.cache --infile=merged.pcap --outfile=rewritten.pcap
Important to note that the first MAC address in both enet-dmac and enet-smac being rewritten is the server side MAC address, the 2nd MAC address is the client side (00:22:22:22:22:23 is the destination MAC address of packets originated from the server, 00:22:22:22:22:22 is the destination MAC address of the packets originated from the client; 00:11:11:11:11:11:12 is the source MAC address of packets originating from the server side, 00:11:11:11:11:11:11 is the source MAC address originating from the client side). The differentiation on which packets are server side and which are client side are done again based on the cachefile previously generated with tcpprep.
    3. We can use tcpreplay now to replay the file rewritten.pcap and using the merged.cache file to instruct tcpreplay to send the server originated packets on the server side bound interface (eth1) and to send the client side packets out on the client side bound interface (eth0)
tcpreplay --cachefile=merged.cache --intf1=eth1 --intf2=eth0 rewritten.pcap
Again, here is important to note that intf1 is the interface on the server side (sending server generated packets -from 172.16.0.0/24) and intf2  is the client side interface (sending packets that are not from 172.16.0.0/24).
The packets from client -> server will be sent out eth0, the packets from server -> client will be sent out eth1. 

Some other uses of of the tools in the tcpreplay suite:
  • Removing vlan tags from  pcaps with tcprewrite
tcprewrite --enet-vlan=del --infile=filename.pcap --outfile=rewritten.pcap
  • Fixing checksums (IPv4/TCP/UDP). The --fixcsum option forces recalculation of IPv4/TCP/UDP checksums
tcprewrite --fixcsum --infile=filename.pcap --outfile=rewritten.pcap
  • Replaying the same capture file for a number of times (10 times in the example)
tcpreplay --loop 10 --cachefile=merged.cache --intf1=eth1 --intf2=eth0 rewritten.pcap
  • Replaying the packet capture not at the speed it was captured, but with a define pps (packets/second) rate  (5 pps in the example)
tcpreplay --pps 5 --cachefile=merged.cache --intf1=eth1 --intf2=eth0 rewritten.pcap

No comments: