简介:pcapsipdump 是一款基于 libpcap 的开源 SIP 抓包工具,面向网络协议分析、VoIP 运维与安全研究等场景,适合具备一定抓包与协议基础的中高级读者使用。它监听指定网络接口,将捕获到的 SIP/RTP 会话按会话拆分,分别保存为命名规范的独立 .pcap 文件,可直接用 tcpdump、Wireshark 等工具打开分析,便于定位呼叫流程与媒体流问题。资源包共 16 个文件,以 cpp 与 h 源码为核心,辅以 Makefile、makefile-helpers 等构建脚本,并附带 RedHat、Debian、Solaris 等平台的 init 与 sysconfig 配置、spec 打包描述、LICENSE 及 ChangeLog 等文档,压缩包约 15KB,体量轻便。目前已有 300 人学习下载。借助完整源码与多平台部署脚本,读者可快速完成编译安装,理解会话表管理与抓包落盘逻辑,并在此基础上做二次开发或排错参考。
1. 从一次抓包翻车说起:pcapsipdump 0.2 到底装的是什么
去年排查一套跨平台语音网关的注册异常,我在核心网出口挂了三天 tcpdump,抓回来 40 多个 G 的 pcap,Wireshark 一开就卡死,过滤 SIP 还得靠sip显示过滤器慢慢筛,一个呼叫流程要翻十几分钟。后来换成 pcapsipdump,同样的流量它按 Call-ID 直接切成一个个独立文件,每个呼叫一个 pcap,打开就是完整信令,这才叫干活。pcapsipdump 0.2 是个很老的 C 程序,靠 libpcap 读包、按 SIP 的 Call-ID 分流落盘,装起来不难,难在依赖版本和编译参数——装不好要么编译报错,要么跑起来一个文件都不出。这篇记录的是我在 Debian/Ubuntu 和 CentOS 两套环境里把它从源码装到能跑通的完整过程,适合正在做 SIP 信令分析、VoIP 排障的开发者照着走。
2. 装前把环境列清:依赖、版本与目录规划
2.1 这套程序依赖什么,为什么版本要对
pcapsipdump 0.2 的源码非常轻,核心依赖只有两个:libpcap(读包)和 libpcap 的开发头文件。它不依赖 libsip 之类的协议库,SIP 解析是程序自己写死的字符串匹配,所以对 libpcap 的 ABI 比较敏感。常见做法是直接用发行版仓库里的 libpcap-dev(Debian 系)或 libpcap-devel(RHEL 系),不要自己去编最新版 libpcap 再静态链,否则容易出现undefined reference to pcap_...这类链接错误。
编译器用 gcc 就行,0.2 的代码是 C89 风格,gcc 9 以上、clang 12 以上都能过。我一般还会装make、autoconf、automake,因为源码包里的 configure 脚本偶尔需要重新生成。另外建议装tcpdump用来做对照验证,装tshark用来检查切出来的文件是否完整。
| 组件 | Debian/Ubuntu 包名 | RHEL/CentOS 包名 | 说明 |
|---|---|---|---|
| 抓包库 | libpcap-dev | libpcap-devel | 必须,提供 pcap.h 和链接库 |
| 编译器 | gcc / build-essential | gcc / make | 必须 |
| 构建工具 | autoconf automake | autoconf automake | 建议,configure 异常时用 |
| 验证工具 | tcpdump、tshark | tcpdump、wireshark-cli | 建议,用于对照 |
2.2 目录和权限怎么放
我习惯把源码放/usr/local/src,编译产物装到/usr/local/bin,抓包输出目录单独建/data/pcapdump。原因是 pcapsipdump 运行时要写大量小文件,放在系统盘容易把 inode 吃满,单独挂一块盘更稳。权限上,抓包需要 root 或 CAP_NET_RAW 能力,但输出目录不要让 root 独占,否则后续分析工具读不了。常见做法是建一个专用用户,把输出目录属主给它,运行时用setcap给二进制加抓包能力,避免全程 root。
# 建目录与专用用户(Debian/Ubuntu 示例) sudo mkdir -p /usr/local/src /data/pcapdump sudo useradd -r -s /sbin/nologin pcapuser sudo chown -R pcapuser:pcapuser /data/pcapdump这段命令做了三件事:源码目录、输出目录、专用运行用户。-r表示系统用户,-s /sbin/nologin禁止登录,降低误操作风险。输出目录属主给 pcapuser,后面程序以该用户运行时才有写权限。
2.3 版本选择的取舍
0.2 是 pcapsipdump 比较稳定的一个老版本,功能上够用:按 Call-ID 分文件、支持 BPF 过滤、支持实时抓包和读离线文件。它没有后来一些分支的多线程和 IPv6 增强,但胜在代码简单、编译依赖少。如果你只是做 SIP 信令分流,0.2 完全够;如果要做大规模并发抓包,得考虑别的方案。这里不展开,先把 0.2 装稳。
3. 源码编译安装:从解包到 make install 的每一步
3.1 解包与检查 configure
拿到pcapsipdump-0.2.tar.gz后先解包,进目录看有没有 configure。0.2 的发布包一般自带 configure,如果没有就得先autoreconf -fi生成。解包后建议先./configure --help看一眼支持的参数,别急着编。
cd /usr/local/src tar -zxvf pcapsipdump-0.2.tar.gz cd pcapsipdump-0.2 ls -l configure Makefile.in 2>/dev/nulltar -zxvf里z是 gzip 解压,x解包,v显示过程,f指定文件。ls那行是确认 configure 和 Makefile.in 是否存在,缺了就得走 autoreconf 路线。这一步看着简单,但很多人解包到错误目录,后面 make 找不到头文件,白折腾。
3.2 configure 参数怎么给
pcapsipdump 0.2 的 configure 支持--prefix指定安装路径,其余参数基本走默认。我一般显式给 prefix,避免装到/usr/local下和系统包混在一起。如果 libpcap 装在非标准路径(比如自己编到了/opt/libpcap),要加CPPFLAGS和LDFLAGS。
# 标准路径安装 ./configure --prefix=/usr/local # 若 libpcap 在非标准路径,用环境变量指过去 # CPPFLAGS="-I/opt/libpcap/include" LDFLAGS="-L/opt/libpcap/lib" ./configure --prefix=/usr/local--prefix=/usr/local决定make install后二进制落在/usr/local/bin。CPPFLAGS是编译期头文件搜索路径,LDFLAGS是链接期库搜索路径,两个都要给,只给一个照样报错。configure 跑完会输出一行checking for pcap_open_live... yes,看到 yes 才算依赖找对了。
3.3 make 与 make install 的细节
configure 通过后直接make。0.2 的 Makefile 比较简单,正常十几秒编完。如果报pcap.h: No such file or directory,说明 libpcap-dev 没装或路径没给对;报undefined reference to pcap_compile,说明链接阶段没找到库,检查 LDFLAGS。编完make install把二进制装到 prefix 下。
make sudo make install # 确认安装结果 which pcapsipdump pcapsipdump -h 2>&1 | head -20make只编译不安装,make install才落盘。which确认 PATH 里能找到,-h看帮助输出,能打出用法说明就说明二进制可执行、动态库链接正常。如果-h报error while loading shared libraries: libpcap.so.1,说明运行期找不到 libpcap,需要ldconfig或把库路径加进/etc/ld.so.conf.d/。
3.4 RHEL/CentOS 下的差异
RHEL 系包名是libpcap-devel,安装命令用yum install -y libpcap-devel gcc make。configure 和 make 步骤一样,唯一要注意的是 SELinux 可能拦住写/data/pcapdump,常见做法是先setenforce 0验证是不是 SELinux 的锅,确认后再用semanage fcontext给目录打标签,而不是长期关 SELinux。
# CentOS 7/8 示例 sudo yum install -y libpcap-devel gcc make sudo setenforce 0 # 仅用于验证,确认后应恢复并配置策略setenforce 0是临时把 SELinux 切到宽容模式,重启失效。它只用来判断问题是不是 SELinux 引起,不是长期方案。生产环境应该用semanage fcontext -a -t bin_t之类给二进制和目录打正确标签。
4. 运行参数与配置:让 pcapsipdump 按你的规则切文件
4.1 核心参数逐个说清
pcapsipdump 0.2 的参数不多,但每个都影响输出结果。最常用的是-i指定网卡、-r读离线 pcap、-w指定输出目录、-f给 BPF 过滤表达式。它默认按 Call-ID 命名文件,文件名里带时间戳和 Call-ID,方便回溯。
# 实时抓包,只抓 5060 端口,输出到指定目录 sudo pcapsipdump -i eth0 -w /data/pcapdump -f "port 5060" # 读离线文件,按同样规则切分 pcapsipdump -r /data/input.pcap -w /data/pcapdump -f "port 5060"-i eth0指定抓包网卡,需要 root 或 CAP_NET_RAW。-w是输出目录,必须存在且可写。-f "port 5060"是 BPF 过滤,只把 SIP 信令流量交给程序处理,减少无关包干扰。-r用于离线分析,此时不需要 root。注意-f的表达式要加引号,否则 shell 会把空格拆开。
4.2 输出文件命名与目录结构
程序会在-w目录下按呼叫生成文件,命名通常包含时间、源目地址和 Call-ID 片段。文件多了以后目录会很乱,我一般按天建子目录,用 cron 或脚本每天切一次输出路径。这样既避免单目录文件过多,也方便按时间归档。
# 按日期建目录并启动抓包(示例脚本片段) DAY=$(date +%Y%m%d) OUT="/data/pcapdump/$DAY" mkdir -p "$OUT" sudo pcapsipdump -i eth0 -w "$OUT" -f "port 5060"date +%Y%m%d生成当天日期,mkdir -p保证目录存在。把输出路径按天分开,后续清理和检索都简单。这个脚本可以放进 systemd 服务或 supervisor 里跑,避免终端断开就停。
4.3 用 setcap 降低权限风险
长期以 root 跑抓包程序不是好习惯。常见做法是给二进制加cap_net_raw,cap_net_admin能力,然后用普通用户运行。注意加能力后二进制路径不能随便换,换了要重新加。
sudo setcap cap_net_raw,cap_net_admin+eip /usr/local/bin/pcapsipdump # 以 pcapuser 运行 sudo -u pcapuser pcapsipdump -i eth0 -w /data/pcapdump -f "port 5060"cap_net_raw允许原始套接字抓包,cap_net_admin允许网卡相关操作,+eip表示生效、可继承、允许执行。sudo -u pcapuser切到专用用户运行,输出目录属主已给它,写文件没问题。这样即使程序有漏洞,影响面也比 root 小。
5. 避坑与排查:装完跑不起来时先看这几条
5.1 编译报 pcap.h 找不到
现象:make时报fatal error: pcap.h: No such file or directory。原因:只装了运行库没装开发包,或者 libpcap 装在非标准路径没给 CPPFLAGS。解决:Debian 系装libpcap-dev,RHEL 系装libpcap-devel;非标准路径则在 configure 时加CPPFLAGS="-I/路径/include"。
5.2 运行报 libpcap.so 找不到
现象:pcapsipdump -h报error while loading shared libraries: libpcap.so.1。原因:编译时链接到了某个路径的 libpcap,但运行期动态链接器搜不到。解决:sudo ldconfig刷新缓存;若库在非标准路径,在/etc/ld.so.conf.d/下加一行库目录再ldconfig。
5.3 抓包有流量但一个文件都不出
现象:程序在跑,网卡有 SIP 流量,输出目录空。原因:BPF 过滤写错(比如端口不是 5060)、抓的网卡不对、或者流量里根本没有完整 SIP 信令(只有 RTP)。解决:先用tcpdump -i eth0 -nn port 5060 -c 10确认能看到 SIP 包,再对照-f表达式;确认 Call-ID 在包里存在,因为程序靠它分文件。
5.4 输出目录写不进去
现象:程序启动后报权限错误或静默退出。原因:运行用户对-w目录没有写权限,或 SELinux 拦截。解决:ls -ld看目录属主,chown给运行用户;SELinux 环境用ausearch -m avc看拒绝记录,再针对性打标签,别直接长期关 SELinux。
5.5 文件切得太碎或太少
现象:一个正常呼叫被切成多个文件,或多个呼叫混在一个文件。原因:Call-ID 在信令中被改写、或者抓包点跨了 NAT 导致 Call-ID 不一致。解决:换抓包点到 NAT 同侧,或先用 tshark 确认 Call-ID 是否稳定;必要时放宽过滤,把相关信令都抓进来再人工归并。
6. 装完怎么验证跑通:三步对照法
装完不能只看-h有输出就完事,得用真实流量验证切分逻辑对不对。我一般走三步对照:先抓一小段已知呼叫的 pcap,用 pcapsipdump 切,再用 tshark 检查每个输出文件的 Call-ID 是否唯一、信令是否完整,最后和原始 pcap 的呼叫数对账。
# 第一步:准备一段测试 pcap(含至少两个完整呼叫) tcpdump -i eth0 -nn -w /tmp/test.pcap -c 2000 port 5060 # 第二步:用 pcapsipdump 切分 pcapsipdump -r /tmp/test.pcap -w /tmp/split -f "port 5060" # 第三步:统计输出文件数与每个文件的 Call-ID ls /tmp/split | wc -l for f in /tmp/split/*; do echo "== $f" tshark -r "$f" -Y sip -T fields -e sip.Call-ID 2>/dev/null | sort -u done第一步用 tcpdump 抓 2000 个包做样本,-c限制数量避免抓太多。第二步-r读离线文件、-w输出到/tmp/split。第三步先数文件个数,再逐个用 tshark 提取 Call-ID 并去重。正常情况下每个文件应该只有一个唯一 Call-ID;如果某个文件出现多个,说明切分逻辑在这个场景下不适用,得回头查抓包点或过滤条件。
| 验证项 | 命令 | 通过标准 |
|---|---|---|
| 二进制可执行 | pcapsipdump -h | 正常打印用法 |
| 动态库链接 | ldd $(which pcapsipdump) | 无 not found |
| 切分文件数 | ls /tmp/split | wc -l | 与呼叫数大致一致 |
| Call-ID 唯一性 | tshark 提取去重 | 每文件一个 Call-ID |
对账时如果文件数明显少于呼叫数,先怀疑 BPF 过滤把部分信令挡掉了;如果文件数明显多,怀疑 Call-ID 被中间设备改写。这两种情况我都遇到过,前者改过滤表达式,后者只能换抓包位置。验证通过后再把命令固化成 systemd 服务或启动脚本,加上日志重定向,方便出问题时回看。
从那以后我每次装完 pcapsipdump,都强制走一遍「抓样本、切分、tshark 对账」这三步,不看到每个文件 Call-ID 唯一就不算装完。这套流程看着笨,但能挡住大部分“装上了却不出活”的玄学问题。希望帮到你。
本文还有配套的精品资源,点击获取