简介pcapsipdump是一款基于libpcap的开源SIP抓包工具面向VoIP运维与网络分析人员用于监听指定网络接口并将SIP/RTP会话按呼叫分别保存为独立的pcap文件便于用Wireshark、tcpdump等工具分析。此版本为0.2源码包共16个文件以C源文件.cpp/.h、init初始化脚本、README等文本说明以及Makefile/spec等构建打包配置为主整体仅15KB结构紧凑。压缩包内提供Red Hat、Debian、Solaris等平台的适配脚本与文档Linux/Unix环境下可直接参考编译与配置。已有299人学习下载适合需要深入理解SIP信令抓包原理或扩展抓包工具的开发者阅读源码、复用其会话划分与文件名生成逻辑。1. 认识 pcapsipdump它专门治「大 pcap 文件没法用」的毛病做 VoIP 运维或者信令分析的人十有八九都经历过这种场景在某网关上抓了一下午的包pcap 文件动辄几个 GB拿到 wireshark 里一开机器先卡半分钟再输入 sip.Call-ID 过滤手一抖就把想要的那几路通话淹没在上万条 SIP 消息里。pcapsipdump 就是冲着这个痛点来的——它不是一个包分析器而是一个按呼叫会话把 pcap 拆成小文件的工具核心逻辑一句话讲清楚监听 SIP 信令提取 Call-ID把属于同一通电话的 SIP 和 RTP 包写进同一个独立 pcap 文件。适合谁用抓包量大的信令运维、语音质量分析、SIP 网关调试的工程师。它解决的不只是「能不能找到包」而是「能不能在几分钟内把某一路通话从几 GB 的包里完整捞出来」。2. 核心原理与选型理由它不是普通抓包器而是「会话级归档器」2.1 为什么按 Call-ID 拆文件比事后过滤更靠谱先理解 pcapsipdump 的工作方式你会发现它跟 tcpdump -w 完全是两个物种。tcpdump 做的事是「把流量原样写进一个大文件」分析交给 wiresharkpcapsipdump 做的事是「边抓边归类」它在内存里维护一张会话表表的主键就是 SIP 消息里的 Call-ID 字段。每抓到一条 SIP 消息它解析出 Call-ID然后把这个包追加到以该 Call-ID 命名的文件里同时把后续关联的 RTP 包也追加进去。这里有个关键点RTP 包本身没有 Call-ID它是靠五元组源 IP、源端口、目的 IP、目的端口、协议去反向匹配 SIP 信令里协商出来的 SDP 媒体地址。pcapsipdump 通过解析 INVITE 和 200 OK 里的 SDP c 和 m 字段建立起「Call-ID 到 RTP 五元组」的映射后续的媒体包进来就能精确归属。换句话说它把「事后在 wireshark 里做协议关联」这件事提前到了抓包过程中。市面上同类工具我也试过几个有的只拆 SIP 不拆 RTP拆完你还得手动找媒体流有的靠 SIP 会话的 Via 分支参数做匹配遇到某些网关注入的怪异头域就失灵。pcapsipdump 选 Call-ID 做主键的好处在于它是 RFC 3261 里定义的端到端标识符中间任何代理都不会改写它只要不是网关上故意做 Call-ID 重写匹配稳定性在绝大多数场景下没问题。2.2 关键参数逐个拆解-m、-c、-r、-w 怎么配才不误拆这个工具的可用性很大程度上取决于你对几个时间窗口参数的理解这也是最容易翻车的地方。先列一张常用参数表再逐个讲坑。参数作用典型值影响-i指定抓包网卡eth0实时抓包时必须-r读取离线 pcap 文件capture.pcap离线拆包时使用-w指定输出目录./split拆出的文件会写到这里-m通话超时窗口分钟5超过该时间内无新包则结束会话-c子窗口秒10控制内存中会话的重访频率-T额外 SIP 端口5061识别非标准端口的 SIP 流量-E按 SSRC 细分 RTP 流无同一会话多路媒体时拆成不同流-v版本信息无确认编译是否成功-m这个参数我单独说一下。SIP 会话不是只包含 INVITE 和 BYE 两条消息中间还有 re-INVITE、UPDATE、100/180/183 这些临时响应它们之间可能间隔几十秒甚至几分钟。默认的超时窗口如果不调大一个稍长的通话会被拆成好几个文件后面的 SDP 协商被分到新会话里RTP 对应不上分析时特别容易误判。我一般做长时间通话质量分析时会把-m设到 10 以上宁可文件里多一点静默期也不要中间断一刀。-c子窗口参数理解成「内存会话扫描频率」更合适。pcapsipdump 不是每收一个包就去检查一次所有会话是否超时而是在每个子窗口结束时统一扫一遍。这个值设得太小比如 1CPU 会被无谓的轮询消耗掉设得太大会话超时判断就不够及时文件关闭会延迟。经验值取 510 秒比较平衡。2.3 什么时候该用它什么时候别硬扛pcapsipdump 不是万能的。它适用的是「信令 媒体混流」的完整抓包场景——比如在 SIP 代理和网关之间的汇聚链路、软交换出口、SBC 前后端。在这些位置上流量里既有信令又有媒体而且通话量较大才值得按会话归档。反过来如果你只关心信令交互时序对媒体内容不感兴趣那 tshark 加 -Y 过滤再导出就足够了没必要引入额外的拆包层。另一个不适合的场景是加密的 SIP-TLS 流量。pcapsipdump 解析的是明文 SIP 消息一旦流量是 TLS 加密的SIP over TLS 通常走 5061 端口它只能看到加密数据提取不出 Call-ID会话表完全建不起来。这时候需要先用某种方式解密比如在网关侧配置日志里有 TLS 密钥或者换用其他支持 TLS 会话分析的方案硬用 pcapsipdump 只会得到一堆没法归类的孤儿包。实时抓包时还要想清楚一个问题磁盘 IO 能不能扛住。pcapsipdump 每路通话对应一个文件意味着 N 路并发通话就有 N 个文件句柄同时打开而且每个包都要做一次 write() 系统调用。如果通话并发数上千普通机械硬盘的文件句柄和 IOPS 会很容易被打满丢包率直线上升。我一般建议用固态盘做输出目录或者先用 tcpdump 抓原始大文件事后再用 pcapsipdump -r 离线拆这样最稳。3. 从源码到落地编译、实时抓包、离线拆包的完整流程3.1 依赖检查与编译安装pcapsipdump 是 C 写的依赖只有 libpcap 的开发头文件。编译过程本身不复杂但依赖没装好的话configure 那一步就会卡住而且报错信息不太直观。先确认基础工具链# Debian/Ubuntu 系 sudo apt-get install build-essential libpcap-dev # CentOS/RHEL 系 sudo yum install gcc make libpcap-devel装完依赖后解压源码包进入目录依次执行标准的三步曲tar zxvf pcapsipdump-0.2.tar.gz cd pcapsipdump-0.2 ./configure make sudo make install./configure主要做两件事检测系统里 libpcap 的头文件和库文件位置以及检查 socket 编程相关的函数是否可用。如果它报checking for pcap_open_dead... no这类错误十有八九是libpcap-dev没装或者版本太老。在极少数情况下老版本 libpcap 缺少pcap_set_immediate_mode这类较新的 APIconfigure 会给出替代路径或者直接报错这时候把 libpcap 升级到 1.x 的新版本就能过。编译成功后二进制默认装到/usr/local/bin/pcapsipdump。这里我建议先跑一下pcapsipdump -v确认链接的 libpcap 版本因为这个工具对 libpcap 的版本兼容性相当敏感——有些发行版自带的是裁剪版 libpcap某些抓包特性会被阉割掉。3.2 实时抓包与离线拆包两条路线实时抓包的命令长这样sudo pcapsipdump -i eth0 -w /data/sip_capture -m 10 -c 5 -T 5061这个命令的意思是监听 eth0 网卡把拆好的会话文件写到/data/sip_capture目录会话超时窗口 10 分钟内存扫描周期 5 秒额外识别 5061 端口上的 SIP 流量。命令跑起来后你 ls 输出目录会看到一堆以 Call-ID 命名的文件文件名就是 SIP 消息里的 Call-ID 字符串其中不符合文件名字符集的部分比如和.会被替换成下划线。每路通话结束后文件会 finalize 关闭通话进行中也能看到文件在实时变大。离线拆包适合的场景是你已经用 tcpdump 或者硬件探针抓好了大文件不想再去现场重抓一遍。命令更简单mkdir -p /tmp/split_out pcapsipdump -r /data/raw/big_capture.pcap -w /tmp/split_out -m 10 -c 5离线模式的好处是你可以反复试不同的-m值看拆出来的会话完整性不用再跑一趟现场。坏处是如果原始 pcap 里丢包严重SIP 事务的关键消息比如 INVITE 或 BYE丢了会话可能无法正确关闭文件会一直停在「未结束」状态。遇到这种情况我一般先小规模试拆一段抽样数据确认拆分效果再全量处理。3.3 拆出来的文件怎么验证拆完包第一步不是开 wireshark而是先用 tshark 的快速统计验证会话完整性。每个拆出来的文件理论上应该包含一路完整通话的全部 SIP 消息和 RTP 包。验证方式是用 capinfos 看每个文件的包数量和时间跨度for f in /tmp/split_out/*.pcap; do capinfos $f | grep -E Filename|Number of packets|First packet time|Last packet time done正常的情况下一路 2 分钟的通话文件里应该既有 INVITE、200 OK、ACK 这些信令消息也有成百上千个 RTP 包时间跨度应该与通话实际时长吻合。如果发现某个文件只有几条 SIP 消息而没有 RTP大概率是 SDP 协商解析出了问题或者-E参数没开导致媒体流被并到了别的文件。对 RTP 完整性的更细验证用 tshark 检查序列号连续性tshark -r /tmp/split_out/xxxxx.pcap -Y rtp -T fields -e rtp.seq | head -50序列号如果断断续续、大范围跳变说明原始抓包就丢了媒体包不是拆分工具的问题。这里要分清责任——拆包不会丢包它只是把本就在原始流量里的包重新归档丢包要回源头找原因。4. 避坑指南SIP 拆包的常见问题与排查4.1 通话被拆成多个文件同一路电话前后对不上现象一通 20 分钟的电话在输出目录里出现了两个文件一个只有前半段信令和 RTP另一个从中间某条 re-INVITE 开始。原因-m参数默认值太小两次信令交互之间的间隔超过了超时窗口导致 pcapsipdump 认为旧会话已经结束把后续消息归到新会话里。这种情况在 long-call 场景特别常见尤其是通话中发生了静音抑制、媒体改路等触发 re-INVITE 的操作。解决把-m调大到通话可能的最大信令间隔以上。我一般在做通话质量回溯时直接设 30宁可在内存里多挂一会儿会话也不要误拆。如果已经拆坏了用离线模式重新拆原始 pcap换大窗口再跑一遍。4.2 文件名里的 Call-ID 被转义脚本匹配不上现象wireshark 里看到的 Call-ID 是3a7f4b192.168.1.100但拆出来的文件名是3a7f4b_192.168.1.100自己写的处理脚本按原始 Call-ID 去文件系统里找对应 pcap怎么也找不到。原因pcapsipdump 做文件名消毒时会把、/、:等非安全字符替换成下划线避免创建非法文件名。这是文件系统的安全限制但不是所有使用者的预期。解决脚本里做一次映射把原始 Call-ID 里的特殊字符替换成下划线后再去匹配路径。更稳妥的方式是解析拆出文件里的 SIP 消息重新取 Call-ID而不是依赖文件名——用 tshark 读第一个包取sip.Call-ID字段这才是权威值。4.3 大量会话被合并到同一个文件Call-ID 碰撞现象某个输出文件特别大打开一看里面有两条完全无关的通话记录SIP 消息交织在一起。原因某些代理服务器或网关会复用 Call-ID 前缀甚至有设备错误地把本应唯一的 Call-ID 设成了固定值。pcapsipdump 以 Call-ID 为主键遇到碰撞就全塞进一个文件。解决先确认是不是源设备的问题——在网关侧抓包看原始 Call-ID如果源头就是重复的那怎么拆都一样只能换分析思路。如果只是极少数碰撞可以加大-m也不行因为碰撞跟时间窗口无关。我一般会改在拆包前用 tshark 做一次预处理把异常 Call-ID 的唯一性修复后再喂给 pcapsipdump。4.4 SIP over TCP 完全没有被识别现象抓包前明确知道有 SIP over TCP 流量比如某些中继网关用 TCP 5060 传信令但拆出来的文件里只有 UDP 的 SIP 会话TCP 信令完全没有独立成文件。原因pcapsipdump 默认只解析 UDP 5060 端口上的 SIP 消息对 TCP 流需要额外的端口参数显式声明。TCP 上的 SIP 消息是流式的可能存在跨分片边界处理逻辑跟 UDP 不同。解决启动时加-T 5060如果你确认 TCP 信令也走 5060或者把额外的 TCP SIP 端口都挂上去。需要注意-T只能识别端口不能自动适配 SCTP 之类的传输层后者得靠其他工具。4.5 编译报错找不到 pcap.h现象./configure跑到一半报fatal error: pcap.h: No such file or directory。原因只装了 libpcap 的运行时库libpcap0.8没有装开发包libpcap-dev / libpcap-devel。运行库提供动态链接.so文件但没有头文件编译阶段自然过不去。解决按发行版补装开发包即可。Debian 系是apt-get install libpcap-devRHEL 系是yum install libpcap-devel。装完重新跑 configure注意先make clean再重来避免残留的编译缓存。5. 进阶用法把拆包流程接进自动化巡检脚本当你手头有一堆历史 pcap 需要按会话归档时手工一条条跑命令不现实。我的做法是写个简单的批处理脚本把离线拆包、完整性校验、结果汇总三步串起来。核心脚本大致长这样#!/bin/bash # split_and_verify.sh RAW_DIR/data/raw OUT_DIR/data/split mkdir -p $OUT_DIR # 第一步按文件批量拆包每个原始文件独立输出子目录 for pcap in $RAW_DIR/*.pcap; do name$(basename $pcap .pcap) mkdir -p $OUT_DIR/$name pcapsipdump -r $pcap -w $OUT_DIR/$name -m 30 -c 10 -T 5061 done # 第二步统计每路会话的文件大小和包数量输出摘要 echo call_id,file_size,packet_count summary.csv for sess in $OUT_DIR/*/*.pcap; do info$(capinfos -c -s $sess | tr \n ) echo $(basename $sess),$info summary.csv done这个脚本的关键点是-m 30和-c 10的搭配——批量处理时我倾向用较大的超时窗口确保漏拆概率降到最低代价是内存占用稍高但对离线处理来说无所谓。第二步的 summary.csv 可以直接喂给后续的质量分析脚本按文件名、包数量、时长做初步筛选把异常会话比如只有信令没有媒体的挑出来单看。更进一步可以把 tshark 的 RTP 质量统计接在拆包之后对每路会话做 MOS 估算for sess in $OUT_DIR/*/*.pcap; do tshark -r $sess -q -z rtp,streams 2/dev/null | grep -A5 Packet Loss | head -10 done这样一轮跑下来哪些会话有丢包、哪些有抖动异常一眼就能定位不用再开图形界面一个个翻文件。这套流程最初是我在排查某运营商网关语音断续问题时搭的当时几个 GB 的抓包文件靠手工翻了一整天没头绪后来把拆包脚本跑完五分钟就锁定了那路丢失的 re-INVITE 导致的媒体中断。从那以后我每次抓大包都会强制自己先过一遍拆包再分析省下来的时间不止一倍。希望这个流程对你也一样适用。本文还有配套的精品资源点击获取