When dealing with internet protocols that operate on top of UDP, fragmenting suddenly becomes a lot less uncommon.
Normally, you would only encounter fragments on TCP connections when the MTU on the sending host is larger then the MTU in any of the next hops. Hosts usually attempt to avoid fragmentation for obvious reasons. (Inefficiëncy, extra reassembly work.)
For connectionless UDP packets this is a different matter. Protocols over UDP expect packets to be single entities. This means that fragments must occur when the packet size exceeds the MTU.
Protocols like SIP (over UDP) work with packet data that can in some cases be larger than a normal MTU of 1500. Some tunnel setups drastically reduce the MTU, causing many if not all SIP packets to get fragmented.
Now, when you sniff this traffic using
obvious filter would be:
udp and port 5060. But, that would make you
miss out on these relevant fragments and ponder questions like: How
come my packets are incomplete? Why does it still work?
The fix? Alter the filter rules to also look for the fragment header:
bits 51..63 (most of bytes 6 and 7) of the IP header contain the
fragment offset. So, instead of looking for
udp, you would look for
udp or (ip[6:2] & 0x1fff != 0).
ngrep -qtldeth0 -Wbyline '' '(udp and port 5060) or (ip[6:2] & 0x1fff != 0)' .. or .. ngrep -qtldeth0 -Wbyline '' '((udp and port 5060) or (ip[6:2] & 0x1fff != 0)) and host my.host.tld'
When sniffing a VoIP host, the RTP (media) data packet size will be so small that it shouldn’t get fragmented and thus won’t show up. The result: packet dumps with complete SIP data and nothing else.