linux - libpcap setfilter() 函数和丢包

标签 linux sip rtp pcap libpcap

这是我在这里@stackoverflow 的第一个问题。

我正在为一些 VoIP 生产服务器编写一个监控工具,特别是一个嗅探工具,它允许使用 Perl 中的 pcap 库捕获与给定模式匹配的所有流量(VoIP 调用)。

我不能使用糟糕的选择性过滤器,例如“udp”,然后在我的应用程序代码中进行所有过滤,因为这会涉及太多流量并且内核无法处理报告数据包丢失。

然后我要做的是在捕获期间迭代地构建更具选择性的过滤器。一开始我只捕获(所有)SIP 信令流量和 IP 片段(在任何情况下模式匹配都必须在应用程序级别完成)然后当我在 SIP 数据包中找到一些关于 RTP 的信息时,我将“或”子句添加到具有特定 IP 和端口的实际过滤器字符串,并使用 setfilter() 重新设置过滤器。

所以基本上是这样的:

  1. 初始过滤器:“(udp 和端口 5060)或(udp 和 ip[6:2] & 0x1fff != 0)”-> 捕获所有 SIP 流量和 IP 片段

  2. 更新过滤器:“(udp 和端口 5060)或(udp 和 ip[6:2] & 0x1fff != 0)或(主机 IP 和端口 PORT)”-> 还捕获特定 IP 上的 RTP ,端口

  3. 更新过滤器:“(udp 和端口 5060)或(udp 和 ip[6:2] & 0x1fff != 0)或(主机 IP 和端口 PORT)或(主机 IP2 和端口 PORT2)”-> 也捕获第二个 RTP 流

等等。

这工作得很好,因为我能够获得 RTP 流的“真实”数据包丢失以用于监控目的,而使用我的工具的选择性过滤器版本较差,RTP 数据包丢失百分比不可靠,因为有由于内核丢弃数据包而丢失了一些数据包。

但让我们来看看这种方法的缺点。

捕获时调用 setfilter() 涉及这样一个事实,即 libpcap 会丢弃“在更改过滤器时”收到的数据包,如函数 set_kernel_filter() 的代码注释中所述,将其放入 pcap-linux.c(已检查 libpcap 版本 0.9 和 1.1)。

所以发生的事情是,当我调用 setfilter() 并且一些数据包以 IP 碎片到达时,我确实丢失了一些碎片,而 libpcap 统计数据最后没有报告这一点:我发现它正在挖掘痕迹。

现在,我明白了为什么这个 Action 是由 libpcap 完成的,但在我的例子中,我绝对不需要有任何数据包丢弃(我不关心获得一些不相关的流量)。

您知道如何解决这个不修改 libpcap 代码的问题吗?

最佳答案

使用更具体的过滤器启动一个新进程怎么样?您可以同时进行两个并行的 pcap 捕获。一段时间后(或检查两者是否收到相同的数据包),您可以停止原始数据包。

关于linux - libpcap setfilter() 函数和丢包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4335757/

相关文章:

linux - 链接共享库 g++ 时出现奇怪的符号

linux - 如何一起使用 mysqldump、pv 和 zip 命令?

python - 苹果机 : OSError: [Errno 1] Operation not permitted: '/tmp/pip-XcfgD6

Java JAIN SIP 状态

android - RTSP、RTCP 和 RTP 端口号

android - VoIP 应用程序开发问题(SIP 等)

linux - Docker Overlay2 资源繁忙

java - Android SipManager : android.net.sip.SipException : SipService. createSession() 返回 null

android - Android 中的 RTSP 客户端

linux - 如何将带空格的参数传递给 sed 命令?