So one of the tcpreplay users has pointed out that it sometimes it doesn’t send the entire packet. I thought this was very odd since tcpreplay is actually quite simple relatively speaking so there’s not much room for bugs like this to sneak in. After some research I figured out the problem was a broken pcap capture file.
Specifically:
The libpcap specification stores multiple instances of the packet length:
- Maximum stored packet size per file (snaplen)
- Original packet size per packet (len)
- Stored packet size per packet (caplen)
The issue becomes when the snaplen is less then the caplen. This shouldn’t happen, but it may due to bugs in code. The result is that the libpcap library lies and returns the lesser of the two numbers (snaplen) and truncates the packet- even though libpcap advances the file descriptor caplen bytes. This clearly violates Postel’s Law.
Of course the maximum stored packet size is rather redundant- no reason you couldn’t pick a reasonable default buffer size (say 65535 bytes) and realloc the buffer if the stored packet size is larger then that. But libpcap doesn’t do that, and doesn’t provide an API to let you know that this is happening. The result is that tcpreplay only has access to incorrect information and fails to send the entire packet.