简介:pcapsipdump 是一款基于 libpcap 的开源 SIP 抓包工具,面向网络运维、VoIP 排障与安全分析人员。它监听指定网卡,将 SIP 信令与 RTP 媒体流按会话拆分,各自保存为独立命名的 .pcap 文件,可直接用 tcpdump、Wireshark 等工具打开分析,适合排查呼叫建立失败、媒体不通、信令异常等场景,也便于对 VoIP 流量做取证与归档。资源包共 16 个文件,约 15KB,以 cpp 与 h 源码为核心,辅以 Makefile、makefile-helpers 等构建脚本,并附带 RedHat、Debian、Solaris 等平台的 init、spec、sysconfig 配置及 README、ChangeLog、LICENSE 等说明文档,覆盖编译、打包与部署所需材料。目前已有 298 人学习下载。借助这份源码,读者可理解基于 libpcap 的会话识别与分流逻辑,掌握从抓包到落盘的完整实现思路,并参考多平台打包脚本完成本地编译与部署,为二次开发或定制抓包策略提供基础。
1. pcapsipdump-0.2.tar.gz 到底解决什么问题:把 SIP 通话抓成可回放的单流 pcap
线上 SIP 语音出问题的时候,最难受的不是没日志,而是日志和抓包对不上。你手里有一个 tcpdump 抓下来的大 pcap,里面混着几十路并发通话、RTP 媒体流、SIP 信令,Wireshark 打开卡到怀疑人生,想单独看某一通电话的完整交互,只能靠 ip.addr 和端口硬过滤,过滤条件写错一次就得重来。pcapsipdump-0.2.tar.gz 这个包,解决的就是这件事:它把混杂的 SIP 流量按「每一通对话」拆成独立的 pcap 文件,一通电话一个文件,信令和媒体都在里面,直接拖进 Wireshark 就能顺着 SIP 流程看完整通话。
它适合谁?做 VoIP 运维、SIP 网关对接、呼叫中心排障、软交换测试的工程师。你不需要改业务代码,只要在链路上跑一个抓包进程,它自己解析 SIP 的 Call-ID、From tag、To tag,把属于同一通对话的包归到一个文件里。0.2 这个版本号说明它是个早期但已经能用的工具,功能聚焦,没有花哨的界面,编译出来就是一个命令行程序。下面从编译、参数、抓包逻辑到排错,按我实际部署的顺序讲一遍,能照着复现。
2. 编译 pcapsipdump-0.2:依赖、命令和三个必调参数
2.1 先看清它依赖什么,别急着 make
pcapsipdump 的核心依赖是 libpcap,因为它要直接读网卡或者读已有 pcap 文件。0.2 这个版本的构建系统是经典的 autotools 三件套:configure、make、make install。拿到 tar.gz 之后先解压,看目录里有没有 configure 脚本,如果没有,说明需要先跑 autoreconf。常见做法是:
tar -zxvf pcapsipdump-0.2.tar.gz cd pcapsipdump-0.2 ls -la如果看到 configure 就直接用;如果只有 configure.ac 和 Makefile.am,就先执行 autoreconf -i。这一步翻车的点在于 autoconf、automake、libtool 的版本不匹配,报错通常是「possibly undefined macro」或者「required file not found」。解决办法是装齐 build-essential、autoconf、automake、libtool、pkg-config,再确认 libpcap-dev 已经装上,因为 configure 会去探测 pcap.h 和 -lpcap。
sudo apt-get install build-essential autoconf automake libtool pkg-config libpcap-dev autoreconf -i ./configure --prefix=/usr/local make sudo make installconfigure 阶段重点看输出里 pcap 相关的检查项,如果显示「checking for pcap_open_live... no」,说明 libpcap 头文件或库没找到,后面编译一定失败。参数上 --prefix 决定安装路径,我一般装到 /usr/local,二进制落在 /usr/local/bin/pcapsipdump。如果系统里 libpcap 装在非标准路径,加 CPPFLAGS 和 LDFLAGS 指过去。
2.2 抓包参数怎么设:-i、-r、-w 和端口过滤
pcapsipdump 的运行方式分两种:实时抓网卡,或者离线读一个已有的大 pcap 再拆分。实时抓包用 -i 指定接口,离线拆分用 -r 指定输入文件。输出目录用 -w 或者位置参数指定,具体看版本,0.2 里常见的是把输出目录作为参数传进去。下面这条是实时抓包的典型命令:
sudo pcapsipdump -i eth0 -w /data/sip_capture -v-i eth0 是抓包网卡,-w 是输出目录,-v 打开详细输出,能看到它识别到的每一通对话和对应文件名。离线拆分更适合事后分析,因为线上直接抓容易丢包:
pcapsipdump -r /data/full_capture.pcap -w /data/sip_split -v这里有个关键参数是 SIP 端口。默认它认 5060,如果你的 SIP 跑在非标端口,比如 5080,就得在命令里显式指定端口过滤,否则它会把所有 UDP 包都当候选,效率低还容易误判。0.2 版本对端口的处理比较直接,通常通过 -p 或者过滤表达式传入,具体以 configure 后的 usage 输出为准,跑一次 pcapsipdump -h 看清楚它支持哪些选项,不要凭记忆写。
提示:实时抓包一定要用 sudo 或者给二进制 cap_net_raw 能力,否则 pcap_open_live 会返回权限错误,程序直接退出。
2.3 输出文件命名和 Call-ID 的关系
拆分出来的文件名通常和 SIP Call-ID 或者内部生成的会话 ID 挂钩。Call-ID 里可能带 @、点号、冒号这些字符,直接做文件名在部分文件系统上会出问题,所以工具一般会做转义或者截断。你看到输出目录里一堆 .pcap 文件,每个文件对应一通对话。验证方法很简单:随便挑一个文件,用 tcpdump 读一下,看里面 SIP 包的 Call-ID 是不是同一个。
tcpdump -r /data/sip_split/xxxx.pcap -nn -A | grep -i "Call-ID"如果发现某个文件里混了多个 Call-ID,说明会话匹配逻辑没对上,常见原因是 NAT 环境下 SIP 信令里的地址和实际包的五元组不一致,或者对话中途换了端口。这时候要回到抓包点,确认是不是在 NAT 设备两侧都抓了,导致同一通电话出现两套地址。
3. 会话匹配逻辑:它怎么判断哪些包属于同一通电话
3.1 SIP 对话标识:Call-ID 加 tag 的组合
SIP 协议里,一通对话由 Call-ID、本地 tag、远端 tag 三者共同标识。Call-ID 在一次对话里不变,但 tag 在 INVITE 和响应里会变化。pcapsipdump 要做的就是把 INVITE、100 Trying、180 Ringing、200 OK、ACK、BYE 这一串包归到同一个文件。它解析 SIP 头部,提取 Call-ID,再结合 From 和 To 里的 tag 建立映射表。新对话进来时建一条记录,后续包根据 Call-ID 和 tag 找到对应记录,写入对应 pcap 文件。
这个逻辑听起来简单,实际有两个边界。第一,Call-ID 相同的并发对话极少,但 tag 必须参与判断,否则同一 Call-ID 下的 re-INVITE 或者多段对话会混。第二,SIP over TCP 的情况下,一个 TCP 连接里可能跑多通对话,按包拆分时要正确处理流边界,不能把 TCP 分段拆散。0.2 版本对 TCP 的支持要看编译时是否启用,UDP 场景是它的主战场。
3.2 媒体流怎么关联:SDP 里的端口信息
光有 SIP 信令还不够,排障时经常要看 RTP 有没有单向、有没有丢包。pcapsipdump 会解析 SDP 里的 m=audio 行,拿到 RTP 端口,然后把对应五元组的 RTP 包也写进同一个对话文件。这样你打开一个 pcap,既能看到信令交互,也能看到媒体流。判断媒体有没有关联上,看输出文件大小:如果只有几 KB,多半只有信令;如果几百 KB 到几 MB,说明 RTP 也进来了。
ls -lh /data/sip_split/ | head -20如果发现某通对话文件特别小,但你知道这通电话通了很久,那就要检查 SDP 里的媒体地址是不是经过了 NAT 改写,导致实际 RTP 五元组和 SDP 描述不一致。这种情况在跨网关场景很常见,工具按 SDP 端口过滤就会漏掉媒体包。
3.3 离线拆分和实时抓包的取舍
实时抓包的好处是能配合 ring buffer 做长期运行,坏处是高并发下用户态解析可能跟不上,导致 pcap 丢包。离线拆分的好处是先把流量完整落盘,再用 pcapsipdump 慢慢拆,不丢包,坏处是需要额外磁盘空间。我一般这么选:排障窗口短、并发低,直接实时抓;要长期留存或者并发高,先用 tcpdump 按天滚动抓,再用 pcapsipdump 离线拆。
tcpdump -i eth0 -s 0 -w /data/raw_%Y%m%d.pcap -G 86400 -Z root-s 0 表示抓完整包,-G 86400 表示每 86400 秒换一个文件,避免单文件过大。注意 tcpdump 抓包本身也可能丢包,看它的「packets dropped by kernel」统计,如果非零,说明内核缓冲区不够,调 -B 参数加大。
4. 避坑与排查:五个真实踩过的坑
4.1 抓出来的文件是空的
现象:命令跑起来没报错,输出目录里也生成了文件,但每个文件都是 0 字节或者只有 pcap 头。原因通常是抓包点没流量,或者过滤条件把 SIP 包排除了。先确认网卡上确实有 SIP 流量,用 tcpdump 单独抓 5060 端口验证。如果 tcpdump 能看到包而 pcapsipdump 看不到,检查它监听的端口和实际 SIP 端口是否一致。解决:显式指定端口,或者先用 tcpdump 抓一个确认有 SIP 的 pcap,再用 -r 离线喂给 pcapsipdump,排除实时抓包环节的问题。
4.2 一通电话被拆成多个文件
现象:明明是一通电话,输出目录里出现好几个相关文件,Call-ID 相同但被分开。原因多半是 tag 处理有偏差,或者对话中间发生了 re-INVITE 导致端口变化,工具把它当成新对话。解决:先确认是不是真的同一通对话,看 SIP 流程里有没有新的 INVITE 带不同 tag。如果是 NAT 导致地址变化,考虑在 NAT 内侧抓包,或者在工具里配置地址映射规则。0.2 版本对复杂 NAT 场景支持有限,必要时换更成熟的抓包方案做补充。
4.3 编译时报 pcap 相关符号找不到
现象:make 阶段报 undefined reference to pcap_open_live 或者 pcap_next_ex。原因是链接时没带上 -lpcap,或者 libpcap 装在了非标准路径。解决:确认 configure 输出里 pcap 检查通过,检查 Makefile 里的 LIBS 是否包含 -lpcap。如果 libpcap 是手动编译安装的,用 LDFLAGS=-L/usr/local/lib 和 CPPFLAGS=-I/usr/local/include 重新 configure。另外确认动态库路径在 ldconfig 里,否则运行时会报 cannot open shared object file。
4.4 高并发下丢包严重
现象:实时抓包时,Wireshark 里看 SIP 重传很多,但 pcapsipdump 输出文件里缺包。原因是用户态程序处理速度跟不上网卡收包速度,内核缓冲区溢出。解决:加大 pcap 缓冲区,或者改用 tcpdump 先落盘再离线拆分。实时抓包时把 -i 换成更靠近流量的网卡,减少中间设备。如果必须实时,考虑用 PF_RING 或者 AF_PACKET 的 fanout 做多进程分摊,但 0.2 版本本身不一定支持这些高级特性,别硬上。
4.5 输出文件名乱码或者覆盖
现象:输出目录里文件名带奇怪字符,或者后一通对话覆盖了前一通。原因是 Call-ID 里包含文件系统不支持的字符,或者会话 ID 生成逻辑有碰撞。解决:检查 Call-ID 内容,看是否有 /、\、: 这些字符。如果是工具直接拿 Call-ID 做文件名,考虑在文件系统层面用支持更多字符的类型,或者改代码做转义。覆盖问题要看是不是同一 Call-ID 的对话被重复处理,确认输入 pcap 里没有重复包。
5. 进阶用法:把 pcapsipdump 接进日常排障流程
5.1 配合 tshark 做自动巡检
拆出来的单对话 pcap,最适合做批量自动检查。比如你想知道哪些对话出现了 4xx 或 5xx 响应,可以用 tshark 遍历输出目录,提取 SIP 状态码,生成一份异常清单。这样不用人工一个个打开 Wireshark。
for f in /data/sip_split/*.pcap; do code=$(tshark -r "$f" -Y "sip.Status-Code >= 400" -T fields -e sip.Status-Code 2>/dev/null | head -1) if [ -n "$code" ]; then echo "$f -> $code" fi done这段脚本的逻辑是:对每个拆分文件跑 tshark,用显示过滤器筛出状态码大于等于 400 的包,取第一个状态码。如果非空,就打印文件名和状态码。参数上 -Y 是显示过滤器,-T fields -e 指定输出字段。注意 tshark 版本不同,SIP 字段名可能略有差异,先用 tshark -G fields | grep sip 确认字段名。
5.2 用 mergecap 把信令和媒体合并回看
有时候你需要把一通对话的信令和媒体分开看,或者把多通对话合并成一个文件做对比。mergecap 是 Wireshark 套件里的工具,能把多个 pcap 按时间戳合并。比如把同一时间段的所有对话合并,看整体流量趋势。
mergecap -w /data/merged.pcap /data/sip_split/*.pcap合并后的文件可能很大,建议只合并你关心的几通对话。参数 -w 指定输出文件,后面跟输入文件列表。如果输入文件时间戳跨度大,合并后按时间排序,Wireshark 打开时注意调整时间显示格式。
5.3 长期运行的文件管理策略
如果让 pcapsipdump 长期跑,输出目录会迅速膨胀。我的习惯是按天建目录,配合 cron 做清理,只保留最近 7 天。同时监控磁盘使用率,超过 80% 就告警。
# 每天凌晨把前一天的抓包目录归档,删除 7 天前的 find /data/sip_split -type d -mtime +7 -exec rm -rf {} \;这条命令删除 7 天前的目录,-mtime +7 表示修改时间超过 7 天。执行前先用 -print 确认要删的路径,避免误删。归档可以用 tar 压缩后转到冷存储,压缩比通常不错,因为 pcap 里重复头部多。
5.4 一个我常犯的错误
早期我图省事,直接在核心网关上跑 pcapsipdump 实时抓,结果高峰期把网关 CPU 拖高了,语音质量反而下降。后来改成在镜像口或者旁路抓,网关本身不装抓包程序。这个教训是:抓包工具再轻量,也是额外负载,别在生产节点上硬扛。现在我的习惯是,任何抓包动作先问一句「会不会影响业务」,确认旁路可行再动手。希望帮到你。
本文还有配套的精品资源,点击获取