【问题标题】:libpcap setfilter() function and packet losslibpcap setfilter() 函数和丢包
【发布时间】:2011-05-19 03:46:09
【问题描述】:

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

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

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

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

所以基本上是这样的:

  1. 初始过滤器:“(udp and port 5060) or (udp and 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() 的代码 cmets 中所述,将其放入 pcap-linux.c(检查 libpcap 版本 0.9 和 1.1)。

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

现在,我明白了这个动作由 libpcap 完成的原因,但在我的情况下,我绝对不需要丢包(我不关心获得一些不相关的流量)。

您对如何解决这个不修改 libpcap 代码的问题有任何想法吗?

【问题讨论】:

    标签: linux sip rtp pcap libpcap


    【解决方案1】:

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

    【讨论】:

    • 您好,感谢您的回答。每次需要“新过滤器”时,我都会考虑生成进程,但我最终会得到相当多的进程,最后还要完成合并捕获的任务。所以老实说,这是我会避免的......:P
    【解决方案2】:

    你能捕获所有的 RTP 流量吗?

    来自capture filters的RTP流量建议是:

    udp[1] & 1 != 1 && udp[3] & 1 != 1 && udp[8] & 0x80 == 0x80 && length < 250
    

    正如链接指出的那样,您会得到一些误报,其中 DNS 和可能的其他 UDP 数据包偶尔包含 RTP 数据包使用的标头字节 0x80,但是该数字应该可以忽略不计,并且不足以导致内核丢弃。

    【讨论】:

    • 您好,感谢您的回答。不幸的是,在生产服务器上有大量的调用,所有的 RTP 流量意味着几乎所有的流量,而且很多。不过,很高兴了解这种过滤器,将来可能会有用。
    【解决方案3】:

    圆孔,方钉。

    您的工具不太适合您的需要。

    另一种选择是做一个一级过滤器(如上所述,它捕获的比想要的多得多)并将它输送到另一个工具中,该工具实现你想要的更精细的过滤器(直到每次调用的情况)。如果由于 RTP 流量过大,第一级过滤器对内核来说太多了,那么您可能需要执行其他操作,例如保持稳定的进程以捕获单个调用(因此您不会更改“主”上的过滤器过程;它只是指示其他人如何设置过滤器。)

    是的,这可能意味着在运行中(将它们全部传递给“保存捕获”过程)或事后合并捕获。

    您确实意识到,如果您不安装过滤器fast,您很可能会错过 RTP 数据包。不要忘记 RTP 数据包可能会在 200 OK 到来之前(或一起)进入发起者,并且它们可能会在 ACK 之前(或在它之上)返回给应答者。也不要忘记没有 SDP 的邀请(在 200 OK 中提供,在 ACK 中回答)。等等等等:-)

    【讨论】:

    • 关于媒体流,如果我在开始/结束时错过了一些数据包,这不是一个大问题,只要我在中间得到完整的真实流:它应该足以检测 real 丢包(即当没有内核丢包发生时)。我最终认为多进程也是唯一的解决方案。尽管我实现了一个修补 libpcap 的版本并且它工作得很好,尽管并不总是很不幸。
    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2016-02-28
    • 2011-02-05
    • 1970-01-01
    • 2013-05-23
    相关资源
    最近更新 更多