Wireshark 网络抓包工具:从原理到实践
📋 目录
- 一、概述与历史演进
- 二、核心原理与架构
- 三、抓包过滤器(Capture Filter)与 BPF
- 四、显示过滤器(Display Filter)
- 五、关键概念图示与流程
- 六、应用场景与实战
- 七、高级应用与扩展
- 八、伪代码与算法说明
- 参考文献
一、概述与历史演进
1.1 工具简介
Wireshark 是一款开源的网络协议分析器(Network Protocol Analyzer),支持实时抓包(Live Capture)与离线分析(Offline Analysis),可对数百种协议进行深度解析(Deep Inspection),运行于 Windows、Linux、macOS 等平台,被业界与教育机构广泛用于网络排障、安全分析、协议学习与性能调优 [1][2]。
与 Charles、Fiddler 等应用层代理不同,Wireshark 工作在网卡/驱动层,可捕获本机及经本机转发的原始报文(含二层以太网帧、IP、TCP/UDP 及各类应用层协议),不依赖应用配置代理,适用于全栈协议分析与非 HTTP(S) 流量 [3]。
1.2 历史与版本脉络
| 时期 | 事件 |
|---|---|
| 1997 年底 | Gerald Combs 为解决工作中的网络问题并学习网络知识,开始编写 Ethereal(Wireshark 前身)[1][4] |
| 1998 年 7 月 | Ethereal 0.2.0 首次发布;Gilbert Ramirez、Guy Harris、Richard Sharpe 等贡献底层解析器与协议支持 [4] |
| 2006 年 | 项目迁移基础设施并更名为 Wireshark [1][4] |
| 2008 年 | Wireshark 1.0 发布,标志着「最低可用功能」完成;首届 SharkFest 开发者与用户大会举办 [4] |
| 2015 年 | Wireshark 2.0 发布,采用全新 UI [4] |
| 2023 年 | 项目由 Wireshark Foundation(美国 501(c)(3) 非营利组织)接管,负责基础设施、SharkFest 与网络教育推广 [4] |
社区贡献模式以「所需协议驱动」为主:开发者复制现有解析器、实现新协议后回馈上游,使 Wireshark 支持的协议数量持续增长(如 4.x 版本已支持数千种协议、数十万字段)[1][2][5]。
1.3 典型应用场景
- 网络排障:定位连接超时、丢包、重传、RST、DNS 解析失败等,结合协议栈与时间轴分析根因。
- 协议学习与逆向:查看真实报文结构、字段含义、状态机行为(如 TCP 握手/挥手、TLS 握手)。
- 安全与取证:检测异常流量、分析攻击载荷、配合 TLS 密钥日志解密 HTTPS 以审计内容(需合规授权)。
- 性能分析:统计往返时延、重传率、吞吐量,配合 IO 图形化与专家信息系统(Expert Info)。
- 嵌入式与物联网:抓取串口/蓝牙/BLE 等经适配器转换后的报文,或配合远程抓包(SSH、rpcapd)分析设备侧流量。
二、核心原理与架构
2.1 抓包在 OS 中的位置
抓包需要网卡驱动或内核模块将流经网卡的报文复制一份交给用户态。在 Unix/Linux/macOS 上,Wireshark 使用 libpcap:应用通过 libpcap 打开设备或文件,由 libpcap 与内核交互(如 Linux 的 PF_PACKET、BPF 过滤器),把满足条件的报文拷贝到用户空间 [6][7]。在 Windows 上,早期依赖 WinPcap(基于 libpcap 1.0.0,支持至 Windows 8,已停止维护);现代 Wireshark(3.0+)默认使用 Npcap:由 Nmap 项目维护,采用 NDIS 6 Light-Weight Filter 驱动,支持环回(loopback)抓包、原始 802.11、x86/x64/ARM,并随 Wireshark 安装包分发;相比 WinPcap 性能与安全性更优 [6][8]。
flowchart TB
subgraph 用户态
W[Wireshark / tshark]
L[libpcap / Npcap]
end
subgraph 内核
K[内核网络栈 / NDIS]
D[抓包驱动]
end
subgraph 硬件
N[网卡]
end
N --> K
K --> D
D --> L
L --> W
2.2 抓包过滤器与显示过滤器的分工
- 抓包过滤器(Capture Filter):在抓包前由驱动/内核或 libpcap 应用,只将符合条件的报文写入捕获文件或交给 Wireshark,未匹配的报文直接丢弃。语法为 Berkeley Packet Filter (BPF),与 tcpdump、WinDump 等一致;抓包过程中不可更改 [5][9]。
- 显示过滤器(Display Filter):在已抓取的报文上做二次过滤,仅影响界面展示与统计,不改变捕获文件内容;可随时修改,基于 Wireshark 自有的字段与协议树 [5][10]。
因此:抓包过滤器用于减负与聚焦(如只抓某主机或某端口),在抓包前设置且抓包过程中不可修改,可减少落盘与内存占用;显示过滤器用于分析时的精筛(如只看 HTTP 请求、某状态码、某字段值),不改变捕获文件内容,仅隐藏包列表中的报文,可随时修改。二者语法不同:例如「某主机 Telnet」抓包过滤写 tcp port 23 and host 10.0.0.5,显示过滤写 tcp.port == 23 and ip.addr == 10.0.0.5 [9][17][18]。
2.3 协议解析(Dissection)与协议树
每个报文进入 Wireshark 后,由解析器(Dissector)按协议栈逐层解析:先由 Frame 解析器处理捕获元数据(时间戳、长度等),再依次调用数据链路层(如 Ethernet)、网络层(IP/ARP)、传输层(TCP/UDP)、应用层(HTTP、TLS、DNS 等)解析器,形成协议树。解析器可内置或通过插件加载;支持协议与字段的完整列表可通过「View → Internals → Supported Protocols」查看,显示过滤器可基于任意已注册字段 [5][11]。
三、抓包过滤器(Capture Filter)与 BPF
3.1 BPF 语法概述(官方语法 [9][12])
抓包过滤器采用 libpcap 过滤器语言(即 BPF),与 tcpdump、WinDump 等使用同一语法。形式为若干原语(primitive) 通过 and / or 连接,并可加 not:
[not] primitive [and|or [not] primitive ...]
原语由限定符(qualifier) + ID 组成。根据 pcap-filter man page 与 Wireshark User's Guide §4.10,常见原语包括:
| 原语 | 含义 | 示例 |
|---|---|---|
| [src|dst] host | 按主机 IP 或主机名过滤 | host 10.0.0.5、src host 192.168.1.1;不写 src/dst 时表示源或目的任一匹配即可 |
| ether [src|dst] host | 按以太网(MAC)地址过滤 | ether host aa:bb:cc:dd:ee:ff |
| gateway host | 以 host 为网关的报文(以太网源/目的为 host,但 IP 源/目的不是 host) | gateway 192.168.1.1 |
| [src|dst] net [mask|len] | 按网络号过滤,可写掩码或 CIDR 长度 | net 192.168.0.0/24、net 192.168.0.0 mask 255.255.255.0 |
| [tcp|udp] [src|dst] port | 按 TCP/UDP 端口过滤;tcp/udp 须在 src/dst 前 | tcp port 80、udp dst port 53 |
| portrange | 端口范围(libpcap 0.9.1+) | tcp portrange 1501-1549 |
| less | greater length | 按报文长度 ≤ 或 ≥ 某值 | greater 128、less 64 |
| ip | ether proto | 按 IP 或以太网层协议类型过滤 | ip proto 6(TCP)、ether proto 0x888e(EAPOL) |
| ether | ip broadcast | multicast | 广播或组播 | not broadcast and not multicast |
| relop | 按字节或字节范围选择(复杂表达式) | 见 pcap-filter man page |
注意:抓包过滤器不是显示过滤器;前者在抓包前应用、语法更受限,后者在已抓包上过滤、可随时修改 [17]。
3.2 常用抓包过滤器示例(官方与 Wiki [9][12][17])
host 172.18.5.4 # 与某 IP 双向流量
src host 192.168.1.1 / dst host 192.168.1.1 # 仅源或仅目的
net 192.168.0.0/24 # 某网段;或 net 192.168.0.0 mask 255.255.255.0
src net 192.168.0.0/24 # 源网段
tcp port 23 and host 10.0.0.5 # 发往/来自 10.0.0.5 的 Telnet
tcp port 23 and not src host 10.0.0.5 # Telnet 且源非 10.0.0.5
port 53 # DNS(TCP+UDP)
port not 53 and not arp # 排除 DNS 与 ARP
tcp portrange 1501-1549 # TCP 端口区间
ether host aa:bb:cc:dd:ee:ff # 以太网地址
ether proto 0x888e # 仅 EAPOL
ip # 仅 IPv4,可排除 ARP/STP 等
not broadcast and not multicast # 仅单播
host www.example.com and not (port 80 or port 25) # 排除 HTTP/SMTP
dst host ff02::1 # IPv6 全节点组播(如 RA)
完整语法见 pcap-filter man page 与 Wireshark Wiki CaptureFilters [9][12][17]。
3.3 抓包前设置与 Capture Options 界面(官方 [9])
- 入口:菜单 Capture → Options…(或主工具栏对应项),打开 「Capture Options」 对话框 [19]。
- 抓包过滤器输入位置:在 Input 标签页中,Interface 表格里每块网卡有一列 Capture Filter;可双击该列编辑该接口的 BPF;也可在表格上方「Capture filter for selected interfaces」为多块接口统一设置。设置完成后点击 Start 开始抓包。
- Input 标签页:除 Capture Filter 外,还可配置每块接口的 Promiscuous(混杂模式)、Snaplen(每包捕获字节数)、Buffer(内核缓冲区大小)、Link-layer header type(链路层类型)、Monitor mode(无线 802.11 原始头,可能断网)等;悬停或展开接口可看到其 IPv4/IPv6 地址。
- Output 标签页:可设置 Capture to a permanent file(保存路径、pcapng 默认格式)、Create a new file automatically(按时间/时长/大小/包数切换文件)、Ring buffer(多文件循环)。
- Options 标签页:Update list of packets in real-time(实时更新包列表)、Automatically scroll during live capture(自动滚动)、Name Resolution(解析 MAC/网络/传输层名称)、Stop capture automatically after…(按时长/大小/包数自动停止)。
- Compile Selected BPFs:可查看当前 BPF 编译后的字节码,便于理解与排错。
- 自动排除远程会话流量:当 Wireshark 在远程环境运行(如 SSH、X11、终端服务器)时,会检测环境变量并自动生成一条抓包过滤器以排除远程连接流量,减少无关包。检测变量包括:
SSH_CONNECTION、SSH_CLIENT、REMOTEHOST、DISPLAY(X11)、SESSIONNAME(终端服务器);Windows 下会检测是否在 Remote Desktop Services 环境 [9][17]。
Linux 提示:开启 BPF JIT 可加速过滤:echo 1 >/proc/sys/net/core/bpf_jit_enable(需 root);持久化可借助 sysfsutils [9]。
四、显示过滤器(Display Filter)
显示过滤器用于在已抓取的报文上精确控制显示哪些包;与抓包过滤器不同,可随时修改且基于协议树字段。完整语法见 User's Guide §6.4;协议与字段列表见 View → Internals → Supported Protocols 与 Display Filter Reference [10][18][20]。
4.1 按协议/字段过滤与比较运算符(官方 [10])
- 最简单:在显示过滤器栏输入协议名(如
tcp)或字段名(如http.request),只显示包含该协议或该字段的报文。 - 比较运算符(User's Guide Table 6.6):
| 英文/别名 | C 风格 | 含义 | 示例 |
|---|---|---|---|
| eq / any_eq | == | 相等(多值字段时任一匹配即成立) | ip.src == 10.0.0.5 |
| ne / all_ne | != | 不相等(多值字段时全部不匹配才成立;Wireshark 3.6+ 语义) | ip.src != 10.0.0.5 |
| all_eq | === | 相等(多值字段时全部匹配才成立) | ip.src === 10.0.0.5 |
| any_ne | !== | 不相等(多值字段时任一不匹配即成立) | ip.src !== 10.0.0.5 |
| gt / lt / ge / le | > < >= <= | 大于/小于/大于等于/小于等于 | frame.len > 100、frame.len le 0x100 |
| contains | — | 协议、字段或切片包含某值 | sip.To contains "a1762"、udp contains 81:60:03 |
| matches | ~ | 协议或文本字段匹配 Perl 兼容正则 | http.host matches "acme\\.(org|com|net)" |
注意:ip.addr、tcp.port 等为多值字段(同时含源与目的);== 表示「任一匹配」,要排除某地址应写 !(ip.addr == 10.43.54.65) 而非 ip.addr != 10.43.54.65(后者语义为「至少一个不等于」,易误用)[18]。
示例:
ip.addr == 192.168.0.1
ip.src == 10.0.0.5 and tcp.flags.fin
frame.len > 100
http.request.uri contains "api"
http.host matches "acme\.(org|com|net)"
tcp.flags.syn == 1
tcp.flags & 0x02
4.2 字段类型(官方 [10])
| 类型 | 说明与示例 |
|---|---|
| 无符号/有符号整数 | 可 8/16/24/32/64 位;可写十进制、八进制(0)、十六进制(0x)、二进制(0b)。例:ip.len le 1500、ip.len le 0x5dc |
| 布尔 | 1 或 True、0 或 False。字段存在即参与过滤;要匹配 SYN 置位须写 tcp.flags.syn == 1 |
| 以太网地址 | 6 字节,分隔符可为 :、.、-。例:eth.dst == ff:ff:ff:ff:ff:ff |
| IPv4 | ip.addr == 192.168.0.1;支持 CIDR:ip.addr == 129.111.0.0/16 |
| IPv6 | ipv6.addr == ::1,也可匹配子网 |
| 字符串 | 双引号;可用 \xhh、\ddd 转义。例:http.request.uri == "https://www.wireshark.org/";原始字符串前缀 r 或 R 使反斜杠按字面处理 |
| 日期时间 | 字符串格式,如 frame.time == "Sep 26, 2004 23:18:04.954975" 或 frame.time < "2022-01-01";小数秒可选,无时区后缀 |
4.3 逻辑、集合与算术
- 逻辑(Table 6.7):
and(&&)、or(||)、not(!)、xor(^^);子序列用[]。 - 集合(Membership):
field in { 值1, 值2 }或范围field in {443, 4430..4434};等价于多个==的 or,但集合对单字段求值,避免多值字段歧义。例:tcp.port in {80, 443, 8080}、http.request.method in {"HEAD", "GET"}、ip.addr in {10.0.0.5..10.0.0.9, 192.168.1.1..192.168.1.9}。 - 算术:
+、-(减号前需空格)、*、/、%、&(按位与)。例:frame.cap_len < { 14 + ip.hdr_len + tcp.hdr_len }可找被截断的 TCP 选项。
4.4 切片、层操作符与 @ 操作符(官方 [10])
- 切片(Slice):在字段或协议名后加
[范围]。范围格式:n:m(从偏移 n 起长度 m)、n-m(从 n 到 m inclusive)、:m(从头到 m)、n:(从 n 到结尾)、单字节[n];负偏移表示从末尾算起。例:eth.src[0:3] == 00:00:83、frame[-4:](最后 4 字节)、frame[-4:4] == 0.1.2.3。字符串切片按 UTF-8 码点边界。 - 层操作符 #:限定到协议栈某一层。例:
ip.addr#2 == 192.168.30.40只匹配第二层 IP(如隧道内层);tcp.port#[2-4]表示第 2、3、4 层。 - @ 操作符:用
@前缀表示按原始字节比较,不经过解码。例:@browser.comment == 73:74:72:69:6e:67:...用于有解码错误时的精确匹配。
4.5 函数(官方 [10])
| 函数 | 说明 | 示例 |
|---|---|---|
| upper / lower | 字符串大小写转换 | lower(http.server) contains "apache" |
| len | 字符串或字节长度(字节数) | len(http.request.uri) > 100 |
| count | 帧中某字段出现次数 | count(ip.addr) > 2 |
| string | 将字段转为字符串(可与 matches 等配合) | string(frame.number) matches "[13579]$" |
| vals | 将字段转为「值字符串」(若有定义) | 用于与枚举名比较 |
| dec / hex | 整数转十进制/十六进制字符串 | — |
| float / double | 转为浮点;double 可处理时间(自 epoch 秒) | — |
| max / min | 参数中的最大/最小值 | max(tcp.srcport, tcp.dstport) <= 1024 |
| abs | 绝对值 | — |
4.6 字段引用(Field References)
${proto.field} 表示当前选中报文中该字段的值,用于动态过滤。例:自当前包起前 5 分钟:frame.time_relative >= ${frame.time_relative} - 300;或 HTTP 且目的 IP 等于当前帧 DNS A 记录:http && ip.dst eq ${dns.a} [10]。
4.7 正则与多值字段注意点
- matches 的字符串会先经 Wireshark 解析再交给 PCRE,转义可能需双重(如括号
\\();用原始字符串r"..."可减少问题 [10]。 - 协议名歧义:如
fc可能被解析为协议 Fibre Channel 或十六进制 0xFC;用.fc强制协议名、:fc强制字节序列 [10]。 - 协议更名:如 bootp → dhcp,旧名可能仍可用但会提示 deprecated;新写过滤器建议用新名 [10]。
五、关键概念图示与流程
5.1 从网卡到界面的数据流
flowchart LR
subgraph 捕获
A[网卡] --> B[驱动/Npcap]
B --> C[BPF 抓包过滤]
C --> D[捕获缓冲区/文件]
end
subgraph 解析与展示
D --> E[Frame 解析器]
E --> F[各层 Dissector]
F --> G[协议树]
G --> H[显示过滤器]
H --> I[包列表/详情/字节]
end
5.2 抓包过滤器 vs 显示过滤器
flowchart TD
subgraph 抓包阶段
P1[所有经过网卡的报文] --> CF{抓包过滤器 BPF}
CF -->|匹配| P2[写入捕获]
CF -->|不匹配| P3[丢弃]
end
subgraph 分析阶段
P2 --> DF{显示过滤器}
DF -->|匹配| Q1[列表中显示]
DF -->|不匹配| Q2[隐藏,仍存在于文件]
end
5.3 协议解析栈(概念)
flowchart TB
F[Frame] --> E[Ethernet]
E --> I[IP / ARP]
I --> T[TCP / UDP / ICMP]
T --> A[HTTP / TLS / DNS / ...]
A --> B[应用数据]
六、应用场景与实战
6.1 HTTP/HTTPS 调试
- HTTP:显示过滤
http、http.request、http.response.code == 404;右键报文 → Follow → HTTP Stream 可查看完整请求/响应体 [13]。 - HTTPS:默认仅能看到 TLS 握手与加密载荷。若需查看明文,需提供会话密钥:在浏览器或 curl 侧设置
SSLKEYLOGFILE环境变量导出密钥日志,在 Wireshark 中 Edit → Preferences → Protocols → TLS → (Pre)-Master-Secret log filename 指向该文件,重新抓包或重放后即可解密(依赖 TLS 1.2 等支持密钥导出;PFS 场景下必须用密钥日志,仅私钥不足)[14][15]。
6.2 TLS 握手与证书问题
- 过滤:
tls或ip.addr == 1.2.3.4 and tls,查看 Client Hello / Server Hello / Certificate / Alert 等。 - 典型问题:版本或套件不匹配、证书链不完整、主机名不匹配、Alert 告警等,可在 Expert Info 与 TLS 解析树中定位 [14][16]。
6.3 连接与性能问题
- TCP:过滤
tcp,关注 SYN/ACK/RST/FIN、重传、窗口;统计 → 往返时延、流图,辅助判断延迟与丢包。 - DNS:过滤
dns,查看请求与响应、响应码与解析结果,排查解析失败或污染。
6.4 TLS 解密配置步骤(摘要)
- 导出密钥日志:在客户端(浏览器/curl)设置环境变量
SSLKEYLOGFILE指向一可写文件;完成 TLS 会话后,该文件会包含 NSS 格式的会话密钥。 - Wireshark 配置:Edit → Preferences → Protocols → TLS → 在「(Pre)-Master-Secret log filename」中指定上述文件路径。
- 抓包或重放:重新建立 TLS 连接并抓包,或对已有 pcap 重新打开;若密钥匹配,应用层载荷会以明文显示在 TLS 解析树下。
- 限制:仅持有服务器私钥无法解密使用 ECDHE/DHE 的会话(PFS);必须依赖客户端导出的密钥日志 [14][15][16]。
6.5 企业与实践参考
- Cisco 等厂商文档中常推荐使用 Wireshark 进行 TLS 与通用网络故障排查,并说明如何配合密钥日志解密 HTTPS [16]。
- 实践中常采用「先抓包过滤缩小范围 + 再显示过滤精查 + Follow Stream / 统计 / 专家信息」的组合流程;大流量环境优先用 BPF 减少落盘与内存占用。
6.6 典型通讯场景抓包与数据包分析 SOP
以下针对 Socket TCP、Socket UDP、音视频直播、WebRTC P2P 等典型通讯场景,给出从抓包配置 → 显示过滤 → 关键字段解读 → 调试与排错的完整 SOP,便于按场景落地使用。
6.6.1 Socket TCP 抓包与分析 SOP
场景说明:基于 TCP 的 Socket 通讯(自定义协议、长连接、游戏/IM 等),需观察连接建立、数据传输、重传、挥手与 RST 等。
| 阶段 | 操作 | 说明 |
|---|---|---|
| 1. 抓包前配置 | 若已知对端 IP 或端口,在 Capture Options → Capture Filter 中设置 BPF,减少无关流量 | 例:host 192.168.1.100、tcp port 9000、tcp portrange 8000-8010;未知时可先不设过滤,抓包后用显示过滤器精查 |
| 2. 选择接口 | 选择实际收发流量的网卡(有线/无线/环回) | 本机压测选 loopback;真机/远程选对应物理或虚拟接口 |
| 3. 开始抓包 | 启动抓包后,在客户端/服务端触发 TCP 连接与数据收发 | 建议在问题复现前开始抓,复现后尽快停止,便于定位时间窗口 |
| 4. 显示过滤 | 在显示过滤器栏输入表达式,精确定位目标流 | 常用:tcp.port == 9000、ip.addr == 192.168.1.100、tcp.stream eq 0(按流索引);组合示例:tcp and ip.addr == 192.168.1.100 and tcp.port == 9000 |
| 5. 定位单条连接 | 在包列表中选中该连接任意一包 → 右键 → Follow → TCP Stream | 弹出窗口显示该连接重组后的双向数据(可看明文或十六进制);窗口内可切换「仅显示/仅请求/仅响应」与编码方式 |
| 6. 分析连接状态 | 查看 TCP 握手与挥手 | 握手:过滤 tcp.flags.syn == 1 and tcp.flags.ack == 0 找 SYN,再找对应 SYN+ACK、ACK;挥手:过滤 tcp.flags.fin == 1 或 tcp.flags.rst == 1;异常:大量 tcp.analysis.retransmission 或 tcp.analysis.fast_retransmission 表示重传,需结合 RTT 与丢包排查 |
| 7. 统计与 RTT | Statistics → Flow Graph 或 Statistics → Round-Trip Time | Flow Graph 可看时序;RTT 可看往返时延分布;Statistics → Conversations → TCP 可看每条连接的字节数、包数,辅助判断是否有半开、僵死连接 |
关键字段与调试要点:
- tcp.flags:syn、ack、fin、rst、push 等;RST 表示连接被重置,需结合前后包分析是哪一端发起。
- tcp.seq / tcp.ack:序列号与确认号,用于判断丢包、乱序与重传。
- tcp.len: payload 长度;0 表示纯 ACK 或控制包。
- tcp.window_size_value:接收窗口,过小可能限制吞吐。
- Expert Info:Analyze → Expert Information 可汇总重传、重复 ACK、零窗口等,便于快速定位问题。
常见问题排查:
- 连接超时/建连失败:过滤 SYN,看是否有 SYN 无 SYN+ACK(对端未响应或防火墙拦截),或 SYN+ACK 无 ACK(本机未回 ACK)。
- 数据丢包/应用收不到:看是否有重传(
tcp.analysis.retransmission)、对端 RST(tcp.flags.rst == 1)、或中间设备分片/MTU 问题(看 IP 分片与 ICMP 不可达)。 - 连接被重置:过滤
tcp.flags.rst == 1,看 RST 来自哪一侧、在哪个 seq 之后,结合应用日志判断是服务端主动关闭、超时还是异常断开。
6.6.2 Socket UDP 抓包与分析 SOP
场景说明:基于 UDP 的 Socket 通讯(DNS、QUIC、游戏、音视频 RTP、自定义协议等),无连接状态,需按五元组或 payload 特征过滤。
| 阶段 | 操作 | 说明 |
|---|---|---|
| 1. 抓包前配置 | 若已知端口或主机,在 Capture Filter 中设置 BPF | 例:udp port 53(DNS)、udp port 5000、host 10.0.0.1 and udp;UDP 流量大时可加 udp 避免抓过多 TCP |
| 2. 选择接口 | 同 TCP,选实际收发流量的接口 | 本机/容器/远程按需选择 |
| 3. 开始抓包 | 触发 UDP 收发后抓包 | UDP 无握手,需在业务触发期间抓取 |
| 4. 显示过滤 | 按端口、IP、长度等过滤 | 常用:udp.port == 5000、udp and ip.addr == 192.168.1.100、udp.length > 100;若 Wireshark 解析了上层协议(如 DNS、RTP),可用 dns、rtp 等 |
| 5. 按流重组(若支持) | 部分协议支持「Follow → UDP Stream」或按 RTP 重组 | 对裸 UDP 可右键 → Follow → UDP Stream 看该五元组下双向 payload;RTP 可用 Telephony → RTP → Stream Analysis |
| 6. 分析 payload | 查看 Packet Bytes 或解析后的应用层字段 | UDP 无重传标识,需结合应用逻辑判断丢包;可统计同一目的端口包数/字节与时间间隔,判断发送频率与是否被丢弃 |
关键字段与调试要点:
- udp.srcport / udp.dstport:源/目的端口,区分服务与流。
- udp.length:UDP 段总长度(含 8 字节头);大包需关注是否 IP 分片(ip.fragments)。
- ip.addr:确认五元组,便于区分多路流。
- 无连接状态:不能像 TCP 那样用「流」概念直接看握手;需通过时间序、端口、payload 模式关联请求与响应(若协议有请求/响应结构)。
常见问题排查:
- 收不到包:确认抓包接口正确、BPF 未过滤掉目标端口;对端是否真的发送(可在对端或中间设备抓包对比)。
- 丢包:UDP 本身不保证可靠,Wireshark 只能看到「到达本机网卡」的包;若应用层发现丢包,可对比包序号(若协议带序号)或统计包数。
- 分片:过滤
ip.fragments或ip.flags.mf,看是否有多片;分片丢失会导致重组失败,应用收不到完整报文。
6.6.3 音视频直播场景抓包与分析 SOP
场景说明:音视频直播涉及多种传输方式——基于 TCP 的 HTTP(HLS、HTTP-FLV、DASH 等)、基于 UDP 的 RTP/RTCP、RTSP 控制 + RTP 承载、以及 WebRTC(见 6.6.4)。此处覆盖 RTP/RTCP、RTSP 及 HTTP 直播拉流。
| 阶段 | 操作 | 说明 |
|---|---|---|
| 1. 抓包前配置 | 按协议类型选用 BPF,缩小范围 | RTP/RTCP:udp portrange 5000-6000 或已知端口;RTSP:tcp port 554 或 udp port 554;HLS/HTTP-FLV:tcp port 80 or tcp port 443,或先不过滤在显示层再筛 |
| 2. 开始抓包 | 在播放端开始拉流/播放的同时启动抓包 | 确保从「起播」或「卡顿/花屏发生前」开始,便于做时序与丢包分析 |
| 3. 显示过滤 | 按协议与端口过滤 | RTP:rtp、rtp.payload_type == 96(H.264 常见);RTCP:rtcp;RTSP:rtsp;HLS:http.request.uri contains ".m3u8" 或 http.request.uri contains ".ts";HTTP-FLV:http.request.uri contains ".flv" |
| 4. RTP 流分析 | Telephony → RTP → RTP Streams 或 Statistics → Flow Graph | RTP Streams 可列出所有 RTP 流,选中某流后可 Analyze;可看丢包数、抖动、 delta 等;Follow → RTP Stream 可看 payload 与解码尝试(若支持) |
| 5. RTCP 分析 | 过滤 rtcp,查看 SR/RR、丢包率与抖动报告 | RTCP 携带接收端统计(丢包、抖动),可与 RTP 侧对比,判断是网络丢包还是对端发送问题 |
| 6. RTSP 分析 | 过滤 rtsp,右键 Follow → TCP Stream(若 RTSP 走 TCP) | 看 OPTIONS、DESCRIBE、SETUP、PLAY 等信令与 SDP;可确认媒体端口、编码格式与 URL |
| 7. HTTP 直播(HLS/DASH/FLV) | 过滤 http,按 URI 或 Host 筛 | 看 .m3u8/.mpd 请求与 200 响应、.ts/.m4s 分片请求顺序与状态码;Follow → HTTP Stream 看完整请求/响应;关注 4xx/5xx 与超时 |
关键字段与调试要点:
- RTP:
rtp.ssrc、rtp.seq、rtp.timestamp、rtp.payload_type;丢包会导致 seq 不连续或 RTCP 报告高丢包率。 - RTCP:SR(Sender Report)含发送端 NTP/RTP 时间与包数/字节数;RR(Receiver Report)含丢包数、最高接收 seq、抖动。
- RTSP:CSeq、Session、Transport(含端口与 RTP/RTCP 端口对)。
- HTTP 直播:状态码、Content-Length、Range 请求;分片请求间隔与响应时间可辅助判断卡顿是否与拉流延迟有关。
常见问题排查:
- 花屏/卡顿:先看 RTP 或 HTTP 分片是否有丢包或重传;再看 RTCP RR 的丢包率与抖动;最后看应用层是否频繁重试或切换码率。
- 无法起播:RTSP 检查 DESCRIBE/SETUP/PLAY 是否均 200、SDP 与 Transport 端口是否可用;HTTP 检查 m3u8/mpd 与首条分片是否 200、CDN 是否可达。
- 延迟大:看 RTP 时间戳与接收时间差、HTTP 分片请求间隔;缓冲与 GOP 大小也会影响延迟,需结合播放器与服务器配置。
6.6.4 WebRTC P2P 场景抓包与分析 SOP
场景说明:WebRTC 包含 信令(多通过 HTTP/WebSocket)、媒体(SRTP/SRTCP over UDP)、以及 NAT 穿透用的 STUN/TURN。抓包可分析 ICE 候选、DTLS 握手、SRTP 流与信令交互;媒体内容为加密,解密需密钥(见下)。
| 阶段 | 操作 | 说明 |
|---|---|---|
| 1. 抓包前配置 | 建议先宽抓再显示过滤;若已知端口可收窄 | 常用 BPF:udp(STUN/RTP 多为 UDP)或 tcp port 443 or tcp port 80(信令);WebRTC 端口动态,常不事先过滤端口 |
| 2. 开始抓包 | 在浏览器或 App 中完成「加入房间/呼叫」至「建立音视频」全过程 | 从点击「开始」前即开始抓,便于捕获完整 ICE 与 DTLS |
| 3. 显示过滤(信令) | 信令多为 HTTPS/WSS | http 或 tls 过滤信令域名;若已配 SSLKEYLOGFILE 并解密 TLS,可看到 WebSocket 或 HTTP 上的 SDP/ICE 等 |
| 4. 显示过滤(STUN) | STUN 用于 NAT 探测与保活 | stun 或 stun.type;可看 Binding Request/Response、XOR-MAPPED-ADDRESS(即 NAT 映射地址) |
| 5. 显示过滤(DTLS) | WebRTC 媒体使用 DTLS 协商密钥,再以 SRTP 传媒体 | dtls;可看 Client Hello/Server Hello、Certificate、Finished;无法仅凭私钥解密 DTLS,需在端点导出 DTLS/SRTP 密钥(见下) |
| 6. 显示过滤(RTP/媒体) | 解密前仅能见 SRTP 密文;解密后可识别为 RTP | 解密前:udp.port == 9xxx(媒体端口在 SDP 中);解密后:可用 rtp 过滤并做 RTP 流分析 |
| 7. 解密 WebRTC 媒体(可选) | 在 Chrome/Chromium 中启用 SSL 日志,导出密钥供 Wireshark 解密 SRTP | Chrome 启动参数加 --ssl-key-log-file=<path> 并指定路径;Wireshark:Edit → Preferences → Protocols → TLS,在 (Pre)-Master-Secret log filename 填该路径;部分版本需在 Protocols → RTP 中启用「Decrypt SRTP」并依赖 DTLS 密钥;Chrome 的 NSS 格式密钥日志对 DTLS 有效,解密后可见 RTP 流 |
关键字段与调试要点:
- STUN:
stun.type(0x0001 Binding Req、0x0101 Binding Resp);stun.att.xor_mapped_address为服务器看到的客户端公网地址,用于 ICE 候选。 - SDP(在信令中):
m=video/m=audio、c=IN IP4、a=rtcp-mux、a=ice-ufrag/a=ice-pwd、a=fingerprint(DTLS);可确认媒体端口、ICE 与 DTLS 参数。 - ICE:在信令中交换 candidate(host/srflx/relay);抓包可验证 candidate 是否与 STUN 响应一致、是否走 TURN(relay)。
- DTLS:握手成功后才会有 SRTP;若 DTLS 失败,无媒体流或报错。
常见问题排查:
- P2P 不通、仅 TURN 能通:看 STUN Binding 是否有响应;若只有 relay candidate 可用,说明 NAT 对称或策略限制,需 TURN 中继。
- 无音频/无视频:看信令中 SDP 是否含对应 m= 与 codec;看 DTLS 是否握手成功;看是否有对应端口的 UDP 包(防火墙/安全组可能拦媒体端口)。
- 媒体解密失败:确认密钥日志在握手前已配置、浏览器确实写入了该文件;Wireshark 需同时支持 TLS 密钥日志与 RTP 的 SRTP 解密(部分版本需在 RTP 偏好中勾选解密选项)。
WebRTC 抓包与解密流程简图:
flowchart LR
subgraph 抓包
A[抓 UDP/TCP] --> B[显示过滤 STUN/DTLS/TLS]
B --> C[信令看 SDP/ICE]
end
subgraph 解密
D[浏览器 ssl-key-log] --> E[Wireshark TLS 密钥]
E --> F[DTLS/SRTP 解密]
end
C --> G[分析候选与媒体端口]
F --> G
6.6.5 场景与过滤器速查表
| 场景 | 建议抓包过滤(BPF) | 常用显示过滤 | 分析入口 |
|---|---|---|---|
| Socket TCP | tcp port 端口 或 host IP | tcp.port == 端口、tcp.stream eq 流索引 | Follow TCP Stream、Expert Info、Flow Graph |
| Socket UDP | udp port 端口 或 host IP and udp | udp.port == 端口、udp.length > 0 | Follow UDP Stream、Packet Bytes |
| 音视频 RTP | udp portrange 5000-6000 等 | rtp、rtcp、rtp.payload_type == 96 | Telephony → RTP Streams、RTP Stream Analysis |
| RTSP | tcp port 554 或 udp port 554 | rtsp | Follow TCP Stream(信令)、RTP 同音视频 |
| HLS/HTTP 直播 | tcp port 80 or tcp port 443 | http.request.uri contains ".m3u8"、http.request.uri contains ".ts" | Follow HTTP Stream、看状态码与顺序 |
| WebRTC 信令 | tcp port 443 | http/tls(解密后看 WSS/SDP) | Follow HTTP Stream、看 SDP/ICE |
| WebRTC STUN/媒体 | udp | stun、dtls、rtp(解密后) | STUN 看 XOR-MAPPED;RTP 同音视频 |
七、高级应用与扩展
7.1 官方文档与界面操作导读
| 内容 | 官方入口 | 说明 |
|---|---|---|
| 抓包 | Capture → Options;User's Guide Ch.4 | 接口选择、Capture Filter、Output/Options 标签 |
| 抓包过滤语法 | §4.10 Filtering while capturing;Wiki CaptureFilters | BPF 原语、自动远程过滤 |
| 显示过滤语法 | §6.4 Building Display Filter Expressions;Wiki DisplayFilters | 比较/逻辑/切片/函数/字段引用 |
| 协议与字段列表 | View → Internals → Supported Protocols;Display Filter Reference | 各协议可过滤字段名 |
| 跟随流 | 右键包 → Follow → TCP/TLS/HTTP Stream | 见下 |
| 统计 | Statistics 菜单 | Conversations、Endpoints、Protocol Hierarchy、RTT、IO Graph |
| 专家信息 | Analyze → Expert Information | 重传、重复 ACK、错误等汇总 |
| 开发/解析器 | Developer's Guide | 编写 Dissector、插件 |
7.2 跟随流(Follow Stream)
对 TCP、TLS、HTTP 等协议,右键报文选择 Follow → TCP Stream / TLS Stream / HTTP Stream,可在一个窗口中看到该连接上的重组应用数据(明文或解密后),便于分析单会话内容 [13]。
7.3 统计与 IO 图
- Statistics:Conversations、Endpoints、Protocol Hierarchy、Round-Trip Time 等,用于宏观把握流量与延迟。
- IO Graphs:按时间轴绘制报文数、字节数或自定义显示过滤器计数,便于观察突发、重传与趋势。
7.4 命令行 tshark
tshark 为 Wireshark 的命令行版本,使用相同的抓包与显示过滤器,适合脚本化与 CI 环境,例如:
tshark -i eth0 -f "tcp port 80" -w capture.pcapng
tshark -r capture.pcapng -Y "http.request" -T fields -e http.request.uri
7.5 自定义解析器与插件
新协议可通过编写 Dissector(C 或 Lua)注册到 Wireshark,实现 proto_register_XXX 与 proto_reg_handoff_XXX,将协议与字段挂入协议树并参与显示过滤;详见 Wireshark Developer's Guide [11]。
八、伪代码与算法说明
8.1 抓包过滤器(BPF)求值概念
BPF 在内核或用户态对每个报文执行布尔表达式求值,仅当结果为真时交付给上层;原语通常对应「偏移 + 长度 + 掩码 + 比较」,例如「IPv4 且目的端口为 80」会编译为对帧内特定偏移处字节的测试。完整语义见 BPF 论文与 man page [12]。
8.2 显示过滤器求值
对每条已解析的报文,根据当前显示过滤器表达式遍历协议树:若字段存在且满足比较/逻辑/集合条件则保留显示,否则隐藏。字段类型与运算符需匹配(如整数用 ==、字符串用 contains/matches),类型不匹配会导致过滤无效或报错。多值字段(如 ip.addr 同时有源与目的)下,== 表示「任一匹配即成立」(any_eq),若需「全部匹配」可使用 ===(all_eq)[10]。
8.3 协议解析器调用顺序(概念)
对每个捕获的 frame:
1. Frame dissector 写入时间戳、长度等元数据
2. 根据链路层类型(如 Ethernet type)选择下一层解析器
3. 递归:每个解析器解析本层头部,根据「下一层协议」字段(如 IP 的 protocol、TCP 的 port)调用子解析器
4. 直至无子协议或数据结束,协议树与字段注册完成,供显示过滤器使用
参考文献
[1] Wireshark. About Wireshark. www.wireshark.org/about.html
[2] Wireshark. Wireshark User's Guide. www.wireshark.org/docs/wsug_h…
[3] 与 Charles 等代理工具的差异:Charles 为应用层代理,Wireshark 为底层抓包与协议解析。
[4] Wireshark. 1.4. A Brief History Of Wireshark. www.wireshark.org/docs/wsug_h…
[5] Wireshark. Filtering while capturing / Building Display Filter Expressions. User's Guide.
[6] Wireshark Wiki. libpcap. wiki.wireshark.org/libpcap
[7] Wireshark Wiki. Packet capture. wiki.wireshark.org/CaptureSetu…
[8] Npcap. Npcap: Windows Packet Capture Library & Driver. npcap.org/
[9] Wireshark. 4.10. Filtering while capturing. www.wireshark.org/docs/wsug_h…
[10] Wireshark. 6.4. Building Display Filter Expressions. www.wireshark.org/docs/wsug_h…
[11] Wireshark. Chapter 9. Packet Dissection. Developer's Guide. www.wireshark.org/docs/wsdg_h…
[12] tcpdump. pcap-filter man page. www.tcpdump.org/manpages/pc…
[13] Wireshark. Following Protocol Streams. User's Guide.
[14] Wireshark Wiki. TLS. wiki.wireshark.org/TLS
[15] SSLTrust / 第三方. Wireshark troubleshoot network SSL TLS.
[16] Cisco Community. Troubleshoot TLS using Wireshark. community.cisco.com/t5/security…
[17] Wireshark Wiki. CaptureFilters. wiki.wireshark.org/CaptureFilt…
[18] Wireshark Wiki. DisplayFilters. wiki.wireshark.org/DisplayFilt…
[19] Wireshark. 4.5. The "Capture Options" Dialog Box. User's Guide. www.wireshark.org/docs/wsug_h…
[20] Wireshark. Display Filter Reference. www.wireshark.org/docs/dfref/