tcpdump 在捕获整个数据包时不捕获所有 TCP 数据包

网络工程 通讯协议 包分析 数据包丢失 转储
2021-07-23 10:29:43

我在不同的机器和不同的位置有一个服务器和一个客户端。我正在尝试在服务器机器的接口上使用 tcpdump 捕获 TCP 数据包。我在数据包的有效载荷中注入了一个标识符,以便在显示 tcpdump 的输出时可以识别这些数据包。

我正在使用的完整命令是:

tcpdump -l  -AnXSs 0 -i eth0 -tt tcp port 7778 | tee tcpdump_test 

如果我给 tcpdump 选项-s 0(显示整个数据包)连同上面显示的其他选项,tcpdump 似乎错过了到达接口的数据包。

但是,如果我给 tcpdump 选项-s 100(显示数据包的前 100 个字节)以及上面的其他选项,tcpdump 似乎给了我我期望的所有数据包。

我通过 TCP 发送的数据包越大,我遇到的丢失数据包的比率就越高。一个导入说明是,我收到了客户端和服务器上的所有 tcp 数据包,正如我所期望的,如果我将标志指定-s 0为 tcpdump ,我只是看不到它们都到达接口

在我丢失数据包并关闭 tcpdump 的情况下,我从 tcpdump 得到以下输出:

126639 packets captured                                                                    
1544770 packets received by filter                                                           
1416694 packets dropped by kernel 

但是,当我在不丢失数据包的情况下关闭 tcpdump 时,我从 tcpdump 得到以下输出:

2006 packets captured
2006 packets received by filter
0 packets dropped by kernel

为什么它不捕获所有 TCP 数据包,我该怎么做才能使它捕获所有 TCP 数据包?

我在 Linux SUSU 上使用 tcpdump 4.5.1 版和 libpcap 1.5.3 版运行它

1个回答

在@Guy Harris 的帮助和提示下找到了我自己问题的解决方案。由于 tcpdump 使用的缓冲区在捕获整个 TCP 数据包时溢出,内核正在丢弃数据包。

从 tcpdump 手册页:

内核丢弃的数据包(这是由于缺少缓冲区空间而被运行 tcpdump 的操作系统中的数据包捕获机制丢弃的数据包数量,如果操作系统将该信息报告给应用程序;如果没有,它将报告为 0)。

内核将捕获的数据包放在固定大小的捕获缓冲区中。如果 tcpdump 没有足够快地清空缓冲区,内核将开始覆盖缓冲区中的旧数据包,并相应地增加丢弃的计数器。该计数器的值就是您所看到的“被内核丢弃”的值。

通过提供以 KiB 为单位指定新缓冲区大小tcpdump-B选项,可以重新调整捕获缓冲区的大小