Send packets on the same computer running tcpreplay
Q: Can I send packets on the same computer running tcpreplay?
Generally speaking no. When tcpreplay sends packets, it injects them between the TCP/IP stack of the system and the device driver of the network card. The result is the TCP/IP stack system running tcpreplay never sees the packets.
One suggestion that has been made is using something like VMWare, Parallels or Xen. Running tcpreplay in the virtual machine (guest) would allow packets to be seen by the host operating system.
That's what official documentation says ... In my opinion answer "generally speaking yes" is more optimistic :).
I would like to appreciate help of Denis Pynkin who was able to find practical solution how to resolve the issue and use only one machine to send and receive traffic. Denis thank you!
Prepare environment
In this part we are going to deal with feature called namespaces.
A namespace wraps a global system resource in an abstraction that
makes it appear to the processes within the namespace that they have
their own isolated instance of the global resource. Changes to the
global resource are visible to other processes that are members of
the namespace, but are invisible to other processes. One use of
namespaces is to implement containers.
You can learn more about namespaces from
man page or from serie of articels at lwn:
Namespaces in operation, part 1: namespaces overview.
We are going to work with unshare utility. Our goal is to create process with isolated network namespace, to have two "honest" network interfaces to send from and to accept on.
We start with screen shot of my environment with some explanation and than we'll see the steps how to create your own one. First of all there is a
tmux session. So left pane is our host environment. Right is "container" environment. Pay attention to the first command in both panes:
echo $$: it shows two different PID ( proccess ID ). In right pane I executed the following command :
unshare --net bash. (After that we have different bash process with network namespace unshared). Network interfaces ceth1 and ceth0 are manually created with IP addresses assigned. And we can send and receiver ping requests.
If you carefully follow the commands below, you should have similiar environment.
Here is H == host, C == container:
H: ip link add name ceth0
type veth peer name ceth1
H: ip a add 172.18.0.1/24 dev ceth0
H: unshare --net bash
C: echo $$ = PID
H: ip link set ceth1 netns <PID>
C: ip a add 172.18.0.2/24 dev ceth1
C: ip link set dev ceth1 up
At this step we have environment configured and ready to move next ...
Prepare traffic with tcprewrite
download template.pcap
Before we can play multicast UDP traffic we have to make some preparation of our pcap file.
That's can be done by one command:
tcprewrite --enet-dmac=4e:ae:72:a4:2a:96 --srcipmap=127.0.0.1:172.18.0.5 --fixcsum --infile=template.pcap --outfile=dump.pcap
Let’s examine parameters:
--enet-dmac=4e:ae:72:a4:2a:96
Says to replace L2 destination mac address into input file to specified in command line.
In our case we want destination mac address was equal host’s mac address.
--srcipmap=127.0.0.1:172.18.0.5
Says to replace L3 source ip address from 127.0.01 to 172.18.0.5
Since our container’s ip address is equal to 172.18.0.5 we put it in IP packets.
--fixcsum
Documentation says that IP checksum will be re-calculated automatically (but when I did commands separatelly, step by step, somehow checksum was not recalculated, that's why I prefer to pass it manually now)
--infile=part.pcap
Name of the input pcap file
--outfile=prep.pcap
Name of the output pcap file
Now we have changed destanation mac address and source IP address, moreover we pass
--fixcsum parameter to recalculate IP check sum field.
Output file is ready to be replayed.
Let's check
Now we are goingn to check that trafic we send from
eth1 is can be captured on
eth0.
I will use
socat tool for that.
In left pane of our
tmux application run the following command:
socat UDP4-RECVFROM:11000,ip-add-membership=239.10.5.2:172.18.0.1,
STDOUT
In the right pane (child container) run:
tcpreplay -i ceth1 dump.pcap
If everything goes smoothly you should see some printed bytes on left pane and then
socat would exit.
It measn that
socat was able to receive the traffic and everything works fine!
Now you can run your application in left pane instead of
socat and run
tcpreplay on the right pane.
Enjoy!