tcpdump抓UDP包的一个坑
简介
抓包是分析网络协议、问题排查利器,tcpdump是Linux下的一款抓包工具。
分片
首先了解一个概念:MTU(最大传输单元),MTU是定义网络中报文的最大尺寸。如果报文大小超过MTU,则网络栈/网卡会自动将包拆分成多个分片进行发送,保证每个分片都小于MTU。
TCP协议会在三次握手时协商确认MSS(最大报文段长度),MSS选项是TCP协议定义的一个选项,MSS选项用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度。因此TCP报文通常不会被分片。
UDP协议面向无连接,没有协商等机制,依赖MTU来进行分片传输。当发送的数据大于MTU时,由网络栈/网卡会自动将包拆分成多个分片进行发送。
TCP协商MSS与数据流
TCP握手协商MSS
TCP流,大的数据TCP会分包发送
TCP每个分包都有完整TCP头
UDP分片
UDP第一个分片,有源端口、目的端口、checksum等信息
UDP后面的分片,IP头后面全是数据了
坑
在抓包的时候,如果过滤了端口,如:tcpdump -i any udp port 5000。从上面的分析得到,UDP分片中,只有第一个分片是带有源端口、目的端口,因此只能抓取到第一个分片。
解决
把分片包全部抓取下来,使用:tcpdump -i any -s 0 udp port 5000 or 'ip[6:2] & 0x3fff != 0'