资讯动态

pcapsipdump:按SIP会话自动切割RTP媒体流的VoIP抓包工具

发布时间:2026/10/20 22:27:19 来源:尧图企业网站定制
简介基于 libpcap 的开源 SIP 抓包工具 pcapsipdump 提供了一种轻量级会话捕获方案适合网络工程师、VoIP 开发者与安全分析人员在 Linux 环境快速部署。它监听指定网络接口将不同 SIP/RTP 会话分别写入命名清晰的 .pcap 文件可直接用 Wireshark、tcpdump 打开分析省去从大流量文件中手工筛选的麻烦。压缩包约 15KB共 16 个文件核心代码以 C/C 源文件.cpp/.h为主并包含 Makefile、libpcap 检测脚本、RedHat/Debian/Solaris 平台初始化脚本以及 README、ChangeLog、LICENSE 等文档便于跨平台编译与定制工程结构完整、可读性较好。已有 299 人学习下载体量虽小但五脏俱全。读者可从中学习 calltable 管理、RTP 流识别、SIP 信令关联等实现思路同时参考各平台打包配置对需要自行编写 VoIP 抓包工具或排查 SIP 信令异常的人来说是一份很有参考价值的开源样例。1. pcapsipdump 是什么把 SIP 信令和 RTP 媒体自动归到同一个文件的抓包工具排查 VoIP 通话质量问题时最让人头疼的不是抓不到包而是抓下来的 pcap 文件里 SIP 信令和 RTP 媒体流全部混在一起通话一多根本分不清哪段属于哪路。pcapsipdump 就是来解决这个痛点的它实时监听网卡识别 SIP 会话把一路通话的信令和媒体自动归类到同一个 pcap 文件里。pcap sip dump 这三个词恰好概括了它的工作方式——读 pcap、认 SIP、按会话 dump。这份源码包适合搞 SIP 网关运维、话务质量分析、VoIP 协议调试的开发和网工能把「按通话切流量」这件事从半小时手工过滤变成一条命令。2. 核心机制与编译SIP 会话如何映射 RTP 流源码包三步装完2.1 为什么必须按会话抓包SIP 信令默认走 UDP 5060 端口这个端口是固定的但媒体流 RTP 的端口完全是动态协商出来的。我见过不少同事直接用 tcpdump 抓 5060 端口以为这样就能拿到完整通话结果抓了半天只有 INVITE 和 BYE真正的语音包一个都没有。原因就在 SDP 协商里INVITE 的消息体里带了一行类似maudio 40000 RTP/AVP 0的字段40000 才是这路通话媒体流的实际端口而这个端口每路通话都不一样。pcapsipdump 的核心机制是在内存里维护一张会话映射表。捕获到 INVITE 之后它解析出 SDP 里的 IP 和端口把这条 call-id 对应的后续所有包——不管是信令还是媒体——都写进同一个输出文件。这个动作在 0.2 版本里实现得比较朴素但它恰好抓住了 VoIP 抓包最核心的矛盾媒体端口是动态的只有跟着信令走才能找得准。不少人问为什么不用 Wireshark 的 Telephony - VoIP Calls 功能那个功能是事后分析你得先把整个大 pcap 存下来再打开、再加载、再过滤。pcapsipdump 的价值在于实时切割磁盘上直接就是按会话整理好的文件对 7×24 小时持续抓包的场景友好得多。而且它每一步处理都是流式的不需要把整个 pcap 读进内存内存占用很稳定。2.2 源码包编译依赖 libpcap 和 libosip2pcapsipdump-0.2.tar.gz 解压后就是一个标准的源码目录没有 configure 脚本直接 make 就能编译。它依赖两个开发库libpcap抓包底层库和 libosip2SIP 协议解析库。在 Debian/Ubuntu 系系统上先装依赖再编译sudo apt-get install -y libpcap-dev libosip2-dev tar zxvf pcapsipdump-0.2.tar.gz cd pcapsipdump-0.2 make sudo make install这里第二行解压源码包第三行进入解压出来的目录make编译整个工程。如果编译报错说找不到pcap.h说明 libpcap-dev 没装成功如果报错说找不到osip.h说明 libosip2-dev 有问题。make install会把二进制安装到/usr/local/bin/pcapsipdump装完可以用which pcapsipdump验证一下路径。2.3 跑通最小抓包命令一条命令开始切割会话装完之后先跑一个最简单的命令验证工具能正常工作sudo pcapsipdump -i eth0 -w /data/capture-i指定监听网卡-w指定输出目录。这里必须以 root 身份运行或者给二进制授权否则 libpcap 打不开网卡。启动之后用软电话或者 SIP 压测工具发起一路呼叫然后到/data/capture目录下看你会发现多了一个新的 pcap 文件。用 Wireshark 打开这个文件里面既有 INVITE 信令也有后面的 RTP 媒体包一路通话被完整地归到了一个文件里。3. 参数选型与典型场景抓 10 分钟还是抓 7×24 小时3.1 常用参数逐个拆解先看最重要的-t参数。默认情况下生成的文件名用的是 pcapsipdump 进程启动的时间这意味着如果你抓 7 天所有文件名看起来都差不多根本分不清是哪一路通话。加上-t之后文件名取的是每个会话的 INVITE 到达时间这样按文件名排序就是按通话开始时间排序长时间抓包必须加这个参数。-m是镜像模式。它的作用是让工具自动学习通话双方的 MAC 地址并据此把两个方向上行和下行的流量归到同一个文件。在交换机镜像口抓包时如果只镜像了单向流量没有-m的话工具就分不清方向容易把会话文件写残。我一般只要是在镜像口抓包就会加上-m代价很小收益很实在。-c是只抓信令不抓媒体。排查注册失败、呼叫未接通这类问题时媒体流分析没有意义只抓 5060 端口的信令能大幅降低磁盘占用和 CPU 消耗。-T是 RTP 不活动超时单位是秒。意思是一路通话的媒体流超过这个时间没有新包就认为通话结束关闭当前文件。常见默认值是 120 秒。如果你希望会话文件尽快落盘、方便实时消费可以调成 30 秒如果担心长通话被误切就保持默认。-s是抓包长度。默认 65535 字节可以抓完整包但如果只关心会话切割质量不需要解析 RTP 负载内容改成 2048 就够用了磁盘占用能省不少。最后是-o指定运行日志文件。长时间后台运行的工具日志一定要落到文件里不然出错时什么都查不到。3.2 典型场景一单网卡镜像口抓全量话务最常见的部署方式是交换机把上游网关的流量镜像到一个网卡上pcapsipdump 在这块网卡上长期运行。完整命令如下sudo pcapsipdump -t -m -i eth0 -w /data/pcap -o /var/log/pcapsipdump.log我一般在生产环境会加上-b参数配合 BPF 过滤把无关流量挡在内核态。首推的组合是只在 5060 端口和可能用到的 RTP 端口段上做过滤因为 pcapsipdump 要从信令里学媒体端口所以不能把 RTP 端口段给过滤掉否则媒体流就进不来了。后台运行建议配合 nohup 或者 systemd service这样终端断开不影响抓包进程日志由-o单独管理。3.3 典型场景二离线分析已有的 pcap 大文件另一种更省事的用法是用-r参数对已经抓好的 pcap 文件做离线重放。比如某天一台网关上 tcpdump 抓了一个 2GB 的大文件里面既有 SIP 又有各种杂七杂八的流量手工用 Wireshark 过滤会崩溃。直接把文件喂给 pcapsipdumppcapsipdump -r /data/mixed.pcap -t -w /data/split这个命令不涉及网卡抓包是纯用户态重放把大文件按 SIP 会话自动切分成一个个小文件。注意-r和-i不能同时用读取源是离线文件就不需要网卡了。离线重放的好处是没有丢包压力而且可以反复用不同参数跑同一个文件非常适合调参和排查历史问题。3.4 参数组合参考场景推荐参数组合说明长期 7×24 抓全量-t -m -i eth0 -w /data/pcap -o dump.log镜像口双向流量按会话时间命名只排信令故障-c -t -i eth0 -w /data/sig不写媒体磁盘占用小离线拆大文件-r /path/to/old.pcap -t -w /data/split反复调整-T观测会话边界磁盘紧张的嵌入式设备-t -s 2048 -i eth0 -w /data/cap抓包长度改短只留包头发话质4. 避坑排查抓不到包、单向流、超大文件的五个现场4.1 权限不足网卡打不开直接退出现象执行 pcapsipdump 后一句话没输出就退出日志里出现pcap_open_live failed或Permission denied。原因libpcap 从网卡抓原始报文需要CAP_NET_RAW权限。普通用户运行或者 sudo 没加对都会碰到这个问题。解决用 root 运行或者给二进制加 capabilitiessudo setcap cap_net_raw,cap_net_admineip /usr/local/bin/pcapsipdumpsetcap给二进制文件直接绑定网络抓包能力之后普通用户运行就不用再加 sudo 了。注意重新 make install 之后需要重新设置一次因为安装过程会覆盖二进制文件。4.2 高并发下丢会话文件数量对不上呼叫数现象话务高峰期过后生成的文件数明显少于实际呼叫数或者某个文件里只有 INVITE 没有后续媒体包。原因用户态处理速度跟不上网卡到达速率libpcap 环形缓冲区溢出丢包。这个在流量超过工具处理能力时会出现。解决先用 BPF 把过滤下沉到内核态不让无关流量进用户态。先把过滤规则写入文件echo udp port 5060 or (udp portrange 10000-20000) /etc/pcapsipdump.bpf sudo pcapsipdump -b /etc/pcapsipdump.bpf -t -i eth0 -w /data/pcap-b参数指定 BPF 规则文件内核只把 SIP 信令和指定范围媒体端口放进来用户态压力小很多丢包率明显下降。如果还丢就考虑换更强的机器或者用多网卡分流。4.3 抓下来的文件几乎全是单向流现象生成的会话文件里只有 A 发给 B 的包B 回给 A 的包完全不存在。这不是工具故障是镜像口配置的问题。原因交换机上的 SPAN 会话只镜像了入方向或者出方向没有把双向流量都引到镜像口。解决先确认交换机侧 SPAN/RSPAN 配置把 ingress 和 egress 方向都开。然后启动时加-m让 pcapsipdump 自动学习 MAC 方向即便镜像口上流量顺序混乱它也能按 MAC 把上下行归到同一会话。加了-m还是单边基本可以确定是交换机配置问题换用抓包旁路器或调整镜像配置。4.4 文件句柄耗尽抓两天后进程无声退出现象进程跑了两三天突然消失日志最后一行是Too many open files。原因每一路活动的 SIP 会话对应一个打开的输出文件。系统默认的ulimit -n通常只有 1024一路长通话占一个 fd加上系统其他进程消耗很容易触顶。解决调大进程的文件句柄上限。临时生效用ulimit -n 65535用 systemd 管理就在 service 文件里写LimitNOFILE65535。另一个思路是调低-T超时值让不活跃会话更快关闭文件释放 fd。4.5 文件名里的时间戳和真实通话时间对不上现象生成的 pcap 文件名时间比实际呼叫时间差好几个小时或者差一天。原因-t参数取的是会话开始时间来源依赖系统时钟。系统时区没设置正确或者 NTP 校时发生跳变都会让文件时间戳错乱。解决启动长时抓包之前先校准时间sudo timedatectl set-timezone Asia/Shanghai sudo chronyc makestep确认timedatectl显示的时间和当前一致再启动抓包。我习惯在抓包服务起来之后脚本里顺手打印一下当前时间和 pid 到日志文件事后对时间线时有个参照。5. 进阶离线重放与会话完整性校验5.1 离线重放的两个隐藏用法-r参数很多人以为只是把大文件切小其实它还有一个更实用的价值用不同的超时参数反复分析同一个文件反推网络质量。比如先用默认 120 秒拆一遍文件数量比较少再用 15 秒拆一遍pcapsipdump -r /data/mixed.pcap -t -T 15 -w /data/replay_15s对比两次结果如果 15 秒超时拆出了大量额外文件说明原来那批会话里媒体流频繁中断超过 15 秒。这些断档往往对应网络抖动、丢包或者 NAT 超时是一个不用看 RTP 详情就能快速发现异常的信号。另一个用法是做回归验证。每当你改了抓包参数拿同一份历史 pcap 重放一遍对比两次生成的文件数量和会话起止时间就能确认参数改动没有破坏切割逻辑。这个习惯帮我避免过好几次「抓了一整天才发现参数不生效」的尴尬。5.2 用一个小脚本做会话完整性校验拆完文件不是终点得确认每个文件里确实同时含有信令和媒体。写个简单的 Python 脚本批量体检#!/usr/bin/env python3 from pathlib import Path from scapy.all import rdpcap, UDP def stat_file(path): pkts rdpcap(str(path)) sip_cnt, rtp_cnt 0, 0 for pkt in pkts: if UDP not in pkt: continue sport, dport pkt[UDP].sport, pkt[UDP].dport if sport 5060 or dport 5060: sip_cnt 1 elif sport 10000 or dport 10000: rtp_cnt 1 return sip_cnt, rtp_cnt for pcap_file in sorted(Path(/data/split).glob(*.pcap)): sip, rtp stat_file(pcap_file) print(f{pcap_file.name}: SIP{sip} RTP{rtp})脚本用 Scapy 的rdpcap读文件遍历每个包判断 UDP 端口5060 是信令高位端口粗略计为 RTP。这是粗略体检方法不解析 RTP 负载的 payload type但做快速筛查足够了。输出的文件如果 SIP 有值而 RTP 是 0说明媒体流没抓到如果 RTP 包数异常大而 SIP 只有 1 到 2 个可能是单方向媒体风暴值得打开看看。参数上可以改Path(/data/split)换成自己的输出目录判定阈值按实际流量调整。5.3 验证思路和 Wireshark 的 VoIP Calls 对照脚本统计只能告诉你每个文件里有什么验证切割是否准确还得靠 Wireshark。随便打开一个拆出来的 pcap点 Telephony - VoIP Calls能看到这个文件里的完整通话列表。如果列出来的通话数正好是 1而且流的开始时间和 INVITE 时间对得上说明切割正确。我习惯在批量拆完之后挑三个典型的文件短通话、长通话、有转接的会话做人工抽查再和脚本输出对照。这三类覆盖了最常见的会话边界类型抽查过了基本就能放心批量处理大批 pcap 文件。6. 最后一个技巧把抓包思路固化成脚本与其每次敲一长串参数不如把固定动作收进一个函数里function voip_dump() { local OUT${1:-/data/pcap} local IFACE$(ip route get 1.1.1.1 | awk {print $5; exit}) sudo mkdir -p $OUT sudo pcapsipdump -t -m -i $IFACE -w $OUT -o /var/log/voip_dump.log }ip route get 1.1.1.1是拿默认路由网卡的常用技巧避免手写网卡名出错。调用时voip_dump /data/weekly即可不传参数就用默认目录。这个函数适合放在.bashrc里上服务器第一件事就是执行它保证所有会话文件目录一致、命名规范。需要提醒的是抓包服务要跑长周期最好还是写成 systemd service把LimitNOFILE65535、Restartalways都配上否则终端会话一关抓包进程也跟着退。从那以后我每次排查通话质量前都强制自己先跑一遍 2 分钟模拟呼叫确认工具能正确切出文件再上真业务顺手把历史 pcap 重放一次做回归。这两步动作加起来不到五分钟但帮我在正式抓包前拦截了绝大多数参数和配置问题。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑