One week ago I needed to replay traffic saved in a pcap file using tcpreplay and I got a lot of warning messages:
Warning: Unable to send packet: Error with PF_PACKET send() : Message too long (errno=90)
I opened the pcap file and I saw some packages with 40K or more. WTF😳⁉️
I knew Jumbo Frame existed, whose MTU (Maximum Transmission Unit) is 9000. So, what is a package with 40K? They are know as Super Jumbo Frame (SJFs) whose MTU limit is 64000 bytes.
The problem was that the MTU limit on Linux is 9000, so we must fragment this SJFs into packets of 9000 bytes.
At this point, I realized that option 'fragroute' is disabled by default in tcpreplay and for changed it I should recompile it.
We must install the following dependencies:
apt-get install git build-essential libtool libpcap-dev nfs-common automake autoconf autotools-dev autogen
tar -xvf libdnet* cd libdnet* ./configure make make install ln -s /usr/local/lib/libdnet.1.0.1 /usr/lib/libdnet.1
So, we download the latest version of tcreplay from their official git repository .
git clone https://github.com/appneta/tcpreplay
We modify the buffer packet length, this change is necessary to process the super jumbo frames. Go to file src/fragroute/pkt.h and change the following lines:
#define PKT_BUF_LEN (ETH_HDR_LEN + ETH_MTU) with
#define PKT_BUF_LEN 65000
Finally we go to compile tcprepaly with libdnet library
bash autogen.sh ./configure —enable-libdnet —disable-local-libopts —disable-ibopts-install make make install
Check that fragroute option is enabled
user@localhost:/# tcpreplay -V tcpreplay version: 4.2.6 (build git:v4.2.6-4-g54da3478) Copyright 2013-2017 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net> The entire Tcpreplay Suite is licensed under the GPLv3 Cache file supported: 04 Compiled against libdnet: 1.11 Compiled against libpcap: 1.8.1 64 bit packet counters: enabled Verbose printing via tcpdump: disabled Packet editing: disabled Fragroute engine: enabled Injection method: PF_PACKET send() Not compiled with netmap
The flag 'fragroute' in tcprewrite must receive as input a file with the following content
echo "ip_frag 1500" > frag.cfg tcprewrite --fragroute=frag.cfg --infile=input.pcap --outfile=output.pcap
Now, in output.pcap file all packets whose size was more than 1500 have been fragmented. And the most important thing, we have not lost any packet😃