【发布时间】:2011-05-19 03:46:09
【问题描述】:
这是我在这里@stackoverflow 的第一个问题。
我正在为一些 VoIP 生产服务器编写一个监控工具,特别是一个嗅探工具,它允许使用 Perl 中的 pcap 库捕获与给定模式匹配的所有流量(VoIP 呼叫)。
我不能使用选择性较差的过滤器,例如“udp”,然后在我的应用程序代码中进行所有过滤,因为这会涉及过多的流量,并且内核无法处理报告数据包丢失。
然后我要做的是在捕获过程中迭代地构建更具选择性的过滤器。一开始我只捕获(所有)SIP信令流量和IP片段(模式匹配必须在任何情况下在应用程序级别完成)然后当我在SIP数据包中找到一些关于RTP的信息时,我添加'或'子句到具有特定 IP 和 PORT 的实际过滤器字符串,并使用 setfilter() 重新设置过滤器。
所以基本上是这样的:
初始过滤器:“(udp and port 5060) or (udp and ip[6:2] & 0x1fff != 0)” -> 捕获所有 SIP 流量和 IP 片段
更新过滤器:“(udp 和端口 5060)或(udp 和 ip[6:2] & 0x1fff != 0)或(主机 IP 和端口 PORT)”-> 还捕获特定 IP 上的 RTP ,端口
更新过滤器:“(udp 和端口 5060)或(udp 和 ip[6:2] & 0x1fff != 0)或(主机 IP 和端口 PORT)或(主机 IP2 和端口 PORT2)” - > 也捕获第二个 RTP 流
等等。
这很好用,因为我能够获得 RTP 流的“真实”数据包丢失以用于监控目的,而使用我的工具的选择性过滤器版本较差,RTP 数据包丢失百分比不可靠,因为存在由于内核丢弃数据包而丢失了一些数据包。
但是让我们来看看这种方法的缺点。
在捕获时调用 setfilter() 涉及到 libpcap 将“在更改过滤器时”收到的数据包丢弃,如函数 set_kernel_filter() 的代码 cmets 中所述,将其放入 pcap-linux.c(检查 libpcap 版本 0.9 和 1.1)。
所以发生的情况是,当我调用 setfilter() 并且某些数据包以 IP 分段方式到达时,我确实丢失了一些分段,而 libpcap 统计信息最后没有报告这一点:我发现它正在挖掘痕迹。
现在,我明白了这个动作由 libpcap 完成的原因,但在我的情况下,我绝对不需要丢包(我不关心获得一些不相关的流量)。
您对如何解决这个不修改 libpcap 代码的问题有任何想法吗?
【问题讨论】:
标签: linux sip rtp pcap libpcap