1. 为什么要把 DHCP 放到 Wireshark 里重新看一遍
1.1 服务器日志永远只告诉你一半真相
先说个我实际遇到的场景。某天早上办公室陆续有人报"上不了网",Windows 右下角网络图标一直在转圈,最后弹出"续订接口以太网时出错,无法联系 DHCP 服务器,请求超时"。我登录 DHCP 服务器看了一眼,租约文件里近半小时确实有新分配记录,服务器日志也是"all normal"。从服务端看一切正常,但客户端就是拿不到地址。
这就是 DHCP 排障最磨人的地方:服务端日志只记录"我分配了什么",不会告诉你"客户端到底有没有收到"、"广播有没有穿过 VLAN"、"中间交换机是不是把 UDP 68 给丢了"。想看明白整条链路,唯一的办法就是在关键节点抓包。而抓包这件事,Wireshark 几乎是不二之选。
这篇文章我会从协议原理讲到动手实验,带着你在 Wireshark 里把 DHCP 的四步握手彻底看透,再亲手搭一台 DHCP 服务器和一套中继环境,最后用真实故障案例演示怎么通过过滤器和统计功能定位问题。适合三类人:刚学网络协议的学生、被 DHCP 故障折磨过的运维、以及想系统掌握抓包分析思路的工程师。
1.2 一个能跑通全部案例的实验拓扑
为了后面讨论起来不抽象,先约定一套实验环境。你可以用真机,也可以像我一样全部用虚拟机完成:
- DHCP 服务器:Linux(Ubuntu 或 CentOS 系都行),网卡地址 192.168.10.5/24,安装 DHCP 服务。
- 客户端:一台独立的虚拟机或物理机,处于 192.168.20.0/24 网段,用来验证跨网段分配。
- 中继设备:一台三层交换机或者 Linux 路由器,分别配置 VLAN 10 和 VLAN 20,接口地址是 192.168.10.1 和 192.168.20.1。
- 抓包点:Wireshark 装在服务器和客户端上,分别抓各自网卡上的流量;排查中继问题时,在服务器端抓包最有效。
DHCP 本身是个广播协议,客户端在没有任何 IP 配置时用 0.0.0.0 去和服务器通信,所以抓包时网卡模式、过滤规则都需要特别注意,这些我在下一节详细展开。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 抓包前的准备工作:网卡、权限和过滤器
2.1 安装 Wireshark 时容易忽略的两个选项
很多新手装 Windows 版 Wireshark 时一路点 Next,回头发现抓不到包。原因多半是没装对抓包驱动。Wireshark 在 Windows 上依赖 Npcap 或 WinPcap,安装包默认会勾选,但如果你本机已经装了旧版 WinPcap,新版本可能会跳过安装步骤,导致接口列表里显示不出数据。
我的建议是:先卸载掉所有老的抓包驱动,再重装 Wireshark,Npcap 安装时勾选"I'm fine with this and want to install Npcap 1.xx"。另外,抓包本身需要系统权限,Windows 上要右键"以管理员身份运行",Linux 上要么用 root,要么把用户加入 wireshark 组:
bash复制sudo usermod -aG wireshark $USER
不然后续抓包要么一片空白,要么只能看到自己这台的流量。
2.2 选对抓包网卡,比选对工具更重要
Wireshark 打开后会列出所有网卡接口,很多人随手选一个"以太网"就开始抓,结果在虚拟机里抓了半天,全是虚拟网卡的广播包。
判断依据很简单:看 IP 地址。抓 DHCP 客户端流量,就选 IP 为 192.168.20.x 那块网卡;抓服务器流量,就选 IP 为 192.168.10.5 那块。如果你用的是 VMware,客户端网卡要选"桥接模式"或者"自定义 VMnet"并明确对应到实验网络,否则虚拟机根本收不到真实交换机的广播,所有实验现象都会失真。
一个小技巧:Wireshark 主界面接口列表中,每一行会实时显示收包速率。抓包前先随便点开一个网页看看对应接口有没有跳动,先把"通的网卡"确认下来,再开始抓 DHCP。
2.3 过滤器:捕获过滤器与显示过滤器别搞混
这是使用 Wireshark 最核心的一个概念,我见过太多人在两个输入框里用错了表达式。捕获过滤器(Capture Filter)在开始抓包前设置,作用是不让无关流量进入内存;显示过滤器(Display Filter)在抓包后设置,只是从已经抓到的包里筛出需要看的。
抓 DHCP 时的推荐配置:
| 类型 | 输入位置 | 推荐表达式 | 说明 |
|---|---|---|---|
| 捕获过滤器 | 抓包前设置 | udp port 67 or udp port 68 |
只抓 DHCP 相关端口 |
| 显示过滤器 | 抓包后设置 | dhcp 或 bootp |
显示所有 DHCP/BOOTP 报文 |
| 显示过滤器 | 抓包后设置 | bootp.option.dhcp == 1 |
只看 DISCOVER 报文 |
| 显示过滤器 | 抓包后设置 | bootp.option.dhcp == 2 |
只看 OFFER 报文 |
注意,Wireshark 里所有 DHCP 包显示的协议名称是 BOOTP,因为 DHCP 基于 BOOTP 协议格式,所以在显示过滤器里输入 dhcp 和 bootp 效果基本一样。搞清楚这一点,看报文时就不会被"协议这一列写的是 BOOTP"吓到。
2.4 让报文时间线和着色规则更好用
默认情况下 Wireshark 的时间戳显示的是"抓包开始后的相对时间",建议改成"当天具体时间"。方法是:View -> Time Display Format -> Date and Time of Day。排查租约续期问题时,这个细节能帮你快速判断客户端是在哪个时间点开始发起 DISCOVER 的。
Wireshark 自带了一套 DHCP 着色规则,正常分配过程的四个报文通常是不同颜色。如果颜色没生效,可以到 View -> Coloring Rules 里确认是否有 BOOTP/DHCP 相关的规则,没有就手动加一条,比如让 DISCOVER 显示成浅黄色、ACK 显示成浅绿色。颜色不是装饰,是为了让你在长抓包里一眼找出异常节点。
3. 四步握手的报文拆解:从 DISCOVER 到 ACK 的每个关键字段
3.1 DISCOVER:客户端在广播里喊出第一句话
一个空闲的客户端不会默默等待,它会先发出一个 DISCOVER 报文。这个报文的目标 MAC 是 ff:ff:ff:ff:ff:ff,目标 IP 是 255.255.255.255,源 IP 是 0.0.0.0。UDP 源端口是 68,目标端口是 67——记住这两个端口号,后面所有过滤和防火墙放行策略都靠它们。
报文里最关键的是 Transaction ID(xid)字段。客户端会随机生成一个 xid,服务器响应时必须携带相同的 xid,客户端根据这个字段识别"这是给我的回复"。在 Wireshark 里,同一个分配流程的所有包可以通过右键 -> Follow -> UDP Stream 串起来看,也可以直接按 xid 过滤,格式类似:
text复制bootp.id == 0x1a2b3c4d
抓包时你会发现一个细节:客户端在 DISCOVER 里携带了 Option 55(Parameter Request List),它把自己想要的路由器、子网掩码、DNS、域名、租约时间等参数列了个清单。服务器分配时会尊重这个清单,返回的 OFFER 里大部分选项就是从它这个"购物车"里挑出来的。
3.2 OFFER:服务器先提供一份报价单
收到广播的服务器如果地址池里有可用地址,会回一个 OFFER。这个报文有两个容易看错的点:第一,它不一定是广播。如果客户端当前已经有 IP(比如续租场景),OFFER 会直接单播给客户端;如果是全新获取,服务器通常会把 OFFER 广播出去,因为客户端现在还没有可用的 IP 来接收单播。
OFFER 里最核心的是 yiaddr(Your IP Address),这就是服务器准备租给你的地址。同时服务器在 Option 54(Server Identifier)里填上自己的 IP,客户端后续请求会用它来区分"是哪台服务器在报价"。另外还有一长串配置参数,比如 Option 1 子网掩码、Option 3 路由器、Option 6 DNS、Option 51 租约时间、Option 58/59 续租和重绑定时间。你可以在 Wireshark 的报文详情面板里展开 Bootstrap Protocol -> Option 逐项看,比看配置文档直接一百倍。
3.3 REQUEST:客户端确认选择,并通知其他服务器
收到多个 OFFER 时,客户端只会选择其中一个(通常选第一个到达的),然后广播一个 REQUEST。很多人不理解为什么 REQUEST 不用单播——客户端要顺带通知其他服务器"我没选你,把地址留作他用",单播办不到这件事。
REQUEST 报文里有两个值得深挖的字段:Option 50(Requested IP Address)填了它选中的那个地址,Option 54(Server Identifier)填了它选中的服务器 IP。这两项的组合,就是客户端在说"我决定租 192.168.20.50,成交对象是 192.168.10.5"。如果其中任何一项和服务器预期不一致,服务器可能会回 NAK 拒绝这次请求。
3.4 ACK 与租约:一切确认之后的真正生效时刻
最后一步,服务器回复 ACK。客户端收到 ACK 后,把 yiaddr 配置到网卡上,整个获取流程完成。在 Wireshark 里你能看到 ACK 同样携带完整的租约参数。
此后租约进入三个关键时间点:50% 租约时间(T1)时发起单播 REQUEST 续租,如果没收到响应,在 87.5% 租约时间(T2)时广播 REQUEST 寻找任意可用的服务器,直到租约到期。抓续租流量时你会发现它只有 REQUEST/ACK 两步,没有 DISCOVER/OFFER,因为客户端已经有 IP,可以直接单播。
这里顺手整理了一张报文关键字段对照表:
| 阶段 | 源->目的 | xid | 关键 IP 字段 | 关键选项 |
|---|---|---|---|---|
| DISCOVER | 0.0.0.0:68 -> 255.255.255.255:67 | 随机 | ciaddr 为空 | Option 55 请求参数 |
| OFFER | 服务器:67 -> 255.255.255.255:68 | 同 DISCOVER | yiaddr 为候选 IP | Option 54 服务器标识 |
| REQUEST | 0.0.0.0:68 -> 255.255.255.255:67 | 同 DISCOVER | ciaddr 可能为空 | Option 50 请求 IP |
| ACK | 服务器:67 -> 目标:68 | 同 DISCOVER | yiaddr 为最终 IP | 完整租约参数 |
3.5 一条命令快速过滤出完整分配流程
在实际分析中,我不会一个个点开报文看,而是用显示过滤器直接定位。要看某台客户端完整的获取过程,可以用:
text复制bootp.hw.mac_addr == aa:bb:cc:dd:ee:ff
或者只看所有包含 DISCOVER 或 ACK 的报文:
text复制bootp.option.dhcp == 1 || bootp.option.dhcp == 5
记住这些过滤表达式,后面排查时能省下一大半时间。DHCP 的 Option 53 取值里,1 是 DISCOVER,2 是 OFFER,3 是 REQUEST,5 是 ACK,6 是 NAK,7 是 RELEASE,8 是 INFORM。数字记熟,看到报文不用展开也知道它是什么。
4. 搭建一个能复现全流程的 DHCP 服务器实验环境
4.1 服务器选型:dnsmasq 还是 isc-dhcp-server
实验之前先定方案。家用路由器、Windows Server、Linux 上跑的 DHCP 服务都能分配地址,但学习抓包最好用 Linux。Linux 下两个主流选择:
| 服务 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| dnsmasq | 配置极简,同时能做 DNS,几行就能跑 | 功能相对少,不太贴近生产 | 快速验证、内网小规模环境 |
| isc-dhcp-server | 企业级,配置细粒度,几乎什么都支持 | 配置文件相对复杂 | 学习协议细节、生产环境模拟 |
我的建议是实验阶段两个都试一遍。先用 dnsmasq 快速把流程跑通,建立"原来 DHCP 分配就这么回事"的体感;再换 isc-dhcp-server 深入体验生产级配置项的完整度。以下配置均为基于常见实践的方案,具体服务名称和路径在不同发行版上可能有差异,按你的系统做对应调整。
4.2 用 dnsmasq 五分钟跑通一条分配流程
安装 dnsmasq:
bash复制# Ubuntu/Debian
sudo apt update && sudo apt install -y dnsmasq
# CentOS/RHEL
sudo yum install -y dnsmasq
dnsmasq 默认配置会加载 /etc/dnsmasq.conf,为了不动默认文件,我习惯在 /etc/dnsmasq.d/ 下新建一个实验配置:
ini复制# /etc/dnsmasq.d/dhcp-lab.conf
interface=eth0
dhcp-range=192.168.10.100,192.168.10.200,255.255.255.0,12h
dhcp-option=option:router,192.168.10.1
dhcp-option=option:dns-server,114.114.114.114,8.8.8.8
dhcp-leasefile=/var/lib/dnsmasq/dnsmasq.leases
重启服务:
bash复制sudo systemctl restart dnsmasq
这时把一个客户端虚拟机切到和服务器同一网段,Wireshark 里选客户端网卡抓包,就能看到完整的四步握手。dnsmasq 好就好在不用配置 subnet 块,几个参数就够了。如果客户端一直拿不到地址,优先检查防火墙是否放行了 UDP 67/68。
4.3 用 isc-dhcp-server 走一遍生产级配置
isc-dhcp-server 的配置文件是 /etc/dhcp/dhcpd.conf,核心结构是 subnet 声明:
ini复制# /etc/dhcp/dhcpd.conf
default-lease-time 600;
max-lease-time 7200;
option domain-name "lab.local";
option domain-name-servers 114.114.114.114, 8.8.8.8;
option routers 192.168.10.1;
subnet 192.168.10.0 netmask 255.255.255.0 {
range 192.168.10.100 192.168.10.200;
}
写完配置先做语法检查,这一步必须养成习惯:
bash复制sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf
确认无报错后启动服务:
bash复制sudo systemctl restart isc-dhcp-server
租约文件默认在 /var/lib/dhcp/dhcpd.leases,里面记录了每一条分配的历史。这个文件在排查"地址到底给谁了"的时候非常好用,比你翻日志直观得多。
4.4 用 Python 脚本统计抓包结果,顺便把 Python 环境配好
抓完包,我通常会用脚本快速统计一下四类报文的数量,验证实验是否符合预期。这里直接用 Python 3,不用 Anaconda,用系统自带的虚拟环境就够了:
bash复制# 用 venv 创建独立环境,避免污染系统
python3 -m venv ~/pkt-env
source ~/pkt-env/bin/activate
pip install pyshark
下面这个脚本读取 pcapng 文件,按 DHCP 消息类型统计报文数量:
python复制import pyshark
def count_dhcp_messages(pcap_path):
cap = pyshark.FileCapture(pcap_path, display_filter='dhcp')
counter = {'DISCOVER': 0, 'OFFER': 0, 'REQUEST': 0, 'ACK': 0}
for pkt in cap:
dhcp_type = int(pkt.bootp.option.dhcp)
if dhcp_type == 1:
counter['DISCOVER'] += 1
elif dhcp_type == 2:
counter['OFFER'] += 1
elif dhcp_type == 3:
counter['REQUEST'] += 1
elif dhcp_type == 5:
counter['ACK'] += 1
cap.close()
return counter
if __name__ == '__main__':
print(count_dhcp_messages('dhcp-lab.pcapng'))
测试环境里跑一遍,正常情况下四种报文的计数应该接近 1:1:1:1。如果 OFFER 数量明显少于 DISCOVER,说明服务器在某个环节丢了请求,这时候回到 Wireshark 里去对比两个方向的抓包结果,很快就能定位。
4.5 实验中几个绕不开的坑
第一个坑是系统防火墙。很多 Linux 默认开着 firewalld 或 ufw,UDP 67 和 68 被挡得死死的。实验前先放行:
bash复制sudo ufw allow 67/udp
sudo ufw allow 68/udp
第二个坑是虚拟机网络模式。我在 VMware 里第一次搭实验时,客户端和服务器都选的 NAT,结果两边都不在一个广播域里,DISCOVER 根本到不了服务器。换成桥接或者自定义 VMnet 并手动配置同网段 IP 后,问题立刻消失。
第三个坑是网卡上配置了多个 IP 或启用了 NetworkManager 的自动连接,容易导致 DHCP 请求从错误的网卡发出。抓包前先 ip addr 确认一次接口 IP,别等抓了一堆包才发现抓错了口。
5. DHCP 中继的原理与配置:跨网段分配的关键在 giaddr
5.1 广播过不了三层,所以必须有中继
前面实验里客户端和服务器在同一个网段,广播直接就能互通。但实际网络里客户端分布在各个 VLAN,服务器不可能每个网段都放一台。而 DISCOVER 是广播包,路由器默认不会把广播从一个网段转发到另一个网段。DHCP 中继(DHCP Relay)就是为解决这个矛盾设计的。
中继的工作流程是这样的:客户端的广播 DISCOVER 到达三层设备的接口后,中继功能把报文抓起来,把中继接口的 IP 填进 giaddr(Gateway IP Address)字段,然后以单播方式转发给远端的 DHCP 服务器。服务器看到 giaddr 非空,就知道这个请求来自哪个网段,从对应的地址池选地址,并把 OFFER/ACK 单播回给 giaddr,由中继转交给客户端。
说白了,giaddr 就是服务器判断"该给哪个子网分配地址"的路标。没有这个字段,服务器只能靠请求报文到达的接口来判断,跨网段分配根本无从谈起。这也是为什么 Wireshark 抓中继流量时,giaddr 是第一个要看的字段。
5.2 三层交换机上的中继配置实列
以常见的华为交换机和思科交换机为例,配置思路是一致的:先让 VLAN 的虚接口作为网关,再在中继接口上指向 DHCP 服务器。
华为交换机上的配置片段(使用系统视图和接口视图):
text复制# 全局开启 DHCP 中继
dhcp enable
# 创建 VLAN 并配置接口
vlan batch 10 20
interface Vlanif10
ip address 192.168.10.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 192.168.10.5
interface Vlanif20
ip address 192.168.20.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 192.168.10.5
思科交换机上的对应配置:
text复制interface Vlan10
ip address 192.168.10.1 255.255.255.0
ip helper-address 192.168.10.5
interface Vlan20
ip address 192.168.20.1 255.255.255.0
ip helper-address 192.168.10.5
华为的 dhcp select relay 加上 dhcp relay server-ip,和思科的 ip helper-address,本质都是做同一件事:把该接口收到的 DHCP 广播转成单播发到指定服务器。注意 ip helper-address 会转发多种协议,不只是 DHCP,所以生产环境要结合需求评估。
5.3 用 Linux 当软件中继,适合实验室复现
如果手头没有三层交换机,拿一台双网卡 Linux 主机也能模拟中继。安装 isc-dhcp-relay:
bash复制sudo apt install -y isc-dhcp-relay
配置时通过修改 /etc/default/isc-dhcp-relay 指定上游服务器和中继接口:
text复制# /etc/default/isc-dhcp-relay
SERVERS="192.168.10.5"
INTERFACES="eth1 eth2"
eth1 接客户端网段(192.168.20.0/24),eth2 接服务器网段(192.168.10.0/24),重启服务后它就会在这两个接口之间转化广播和单播。
这种软中继方案非常适合学习,因为所有报文都在 Linux 主机上过一遍,你可以同时在 eth1 和 eth2 上抓包,非常直观地看到"广播进来、单播出去"的转换过程。我在实验里建议至少跑一遍这种方式,对理解 giaddr 的作用帮助很大。
5.4 用 Wireshark 验证中继是否真的生效
配置完中继,怎么判断生效了?在服务器网卡上抓包,看 DISCOVER 到达服务器时的样子。正常情况应该看到:
- 报文的源 IP 是中继接口地址,而不是客户端的 0.0.0.0。
- giaddr 字段为中继接口地址,比如 192.168.20.1。
- 服务器回复的 OFFER/ACK 目标 IP 是中继接口,而不是广播地址。
在 Wireshark 中过滤 bootp.option.dhcp == 1,展开 Bootstrap Protocol 里的 Gateway IP Address 字段,如果显示 0.0.0.0,说明中继没把报文处理好,请求会被服务器当成"来自未知网段",分配自然失败。
再看服务器回复,giaddr 非空时服务器会把 OFFER 单播给中继,再由中继转发给客户端。如果你在服务器上只看到请求看不到回复,多半是服务器的地址池里没有对应 giaddr 网段的配置,回去检查 dhcpd.conf 里的 subnet 块。
5.5 中继场景里最容易踩的两个坑
第一个坑是服务器的地址池覆盖不全。实验时我曾在服务器上只配了 192.168.10.0/24 的 subnet,结果客户端在 192.168.20.0/24 网段请求时,服务器收到 giaddr 为 192.168.20.1 的 DISCOVER,但找不到对应的 subnet 定义,直接忽略。Wireshark 里的现象就是客户端拼命发 DISCOVER,服务器端一个响应都没有。
第二个坑是中间设备把单播给过滤了。配置中继之后,OFFER/ACK 是服务器到中继的单播,如果中途有 ACL 或安全策略只放行了广播、没放行 67/68 端口的单播流量,客户端同样拿不到地址。排查时在服务器和中继两个点分别抓包,对比就能看出丢在哪一段。
6. 实际网络中常见的 DHCP 故障与 Wireshark 定位法
6.1 "续订接口以太网时出错"到底是哪里断了
这是 Windows 客户端最常见的一个报错。看到它,第一反应不是去点"修复",而是打开 Wireshark 抓包。抓包后你会看到两种情况之一:要么客户端一直在广播 DISCOVER 没人回应,要么客户端发起了 REQUEST 但服务器回了 NAK。
如果是第一种,问题大概率在链路上:客户端所在 VLAN 的三层接口没配中继、服务器防火墙没放行、或者广播根本没有到达服务器。排查办法是沿着"客户端 -> 接入交换机 -> 网关 -> 服务器"逐段抓包,看 DISCOVER 消失在哪个节点。
如果是第二种,服务器回 NAK 通常是因为客户端请求的地址已经不在合法范围,常见原因是租约过期后 IP 被分配给其他设备,或者 VLAN 配置变更导致客户端拿着旧网段的地址在新的 VLAN 里续租。NAK 报文在 Wireshark 里很好找,过滤 bootp.option.dhcp == 6 即可。
6.2 只有 DISCOVER 看不到 OFFER/ACK 的分层排查法
我把这个场景总结成一张对照表,实际排查时按表逐项验证,比自己瞎猜高效得多:
| 现象 | 可能原因 | 定位手段 |
|---|---|---|
| 客户端疯发 DISCOVER,服务器看不到 | 广播域隔离,中继没生效 | 在服务器端抓包看是否有请求到达 |
| 服务器收到 DISCOVER,但不回 OFFER | 地址池耗尽或缺少对应 subnet | 检查 dhcpd.conf 和租约文件 |
| 服务器回 OFFER,客户端收不到 | 交换机端口安全或 VLAN 配置问题 | 在客户端抓包看是否收到 OFFER |
| 客户端收到 OFFER,REQUEST 后没 ACK | 地址冲突检测失败或服务器丢弃 | 看服务器日志有没有 address conflict |
| 客户端收到 NAK | 请求的 IP 不在合法范围内 | 过滤 NAK,检查租约历史 |
这套方法的核心是先确定"卡在哪一步",再围绕那一步展开。不要一上来就怀疑服务器配置,先看数据面,再谈控制面。
6.3 DHCP Snooping 与仿冒服务器识别
大型网络里,DHCP 还有个常见安全隐患:有人私接了一台小路由器,它自己开了 DHCP,导致整个 VLAN 的用户拿到错误网关、断网。Wireshark 抓包时,如果你发现同一份 DISCOVER 回了两三个不同的 OFFER,而且 Server Identifier 不是你自己的服务器 IP,就要警惕仿冒 DHCP 服务器。
防御手段是交换机上的 DHCP Snooping。配置思路是:把连接合法 DHCP 服务器的端口设为信任口,其余端口为非信任口,非信任口收到的 OFFER 一律丢弃。以华为交换机为例:
text复制dhcp snooping enable
interface GigabitEthernet0/0/1
dhcp snooping trusted
全局开启后默认所有端口都是非信任口,只有明确指定的信任口才能接收服务器报文。开启前先在 Wireshark 里抓一轮确认服务器连接在哪个端口,避免把合法服务器也禁了。
6.4 用 Wireshark 的统计功能和 tshark 做批量分析
图形界面适合逐包分析,但遇到几万包的抓包文件,我更喜欢用命令行工具 tshark(Wireshark 自带)做批量统计。比如统计整个 pcap 里各类 DHCP 消息的数量:
bash复制tshark -r dhcp-lab.pcapng -Y "bootp.option.dhcp" -T fields -e bootp.option.dhcp | sort | uniq -c
结果中数字 1 到 8 对应不同消息类型,只看 1、2、3、5 的数量就能快速判断分配流程是否完整。再比如提取所有 REQUEST 报文的客户端 MAC 和请求 IP:
bash复制tshark -r dhcp-lab.pcapng -Y "bootp.option.dhcp == 3" -T fields -e bootp.hw.mac_addr -e bootp.option.requested_ip_address
图形界面里的 Statistics -> Protocol Hierarchy 也能看到 DHCP 报文占比,适合快速判断大流量里是否混入大量异常的 DISCOVER 重传。这种"命令行批量统计 + 图形界面逐包深挖"的组合,是我处理所有抓包任务的固定流程。
6.5 排障之外:几个能少走弯路的小习惯
最后分享几个我在实际运维中沉淀下来的操作习惯。第一个是抓包文件命名,我统一用"日期_设备_接口_故障现象"的格式,比如 20250112_core-sw_Vlan20_no-ip.pcapng。排查问题经常要回看历史抓包,没有规范命名的话,三天之后你自己都分不清哪个文件对应哪个故障。
第二个是抓包时长不要太长,DHCP 问题一般抓 30 秒到一分钟就够。文件太大反而影响分析效率,小文件才能让我把注意力集中在关键时间窗口上。
第三个是养成"多抓点对照"的习惯。排查中继问题时,我会同时在服务器端和中继设备上抓包,而不是只抓一端。因为只抓一端只能看到"有没有包",同时抓两端才能看出"包在哪一段被丢弃"。这件事看起来麻烦,但每次都能帮我快速缩小排查范围。
