DHCP、NAT、ICMP、IGMP:四协议分工与网络故障排查
1. 把四个协议摆回各自的位置一次网页打不开背后的四层分工很多人第一次系统接触DHCP、NAT、ICMP、IGMP是在面试题或者教材目录里。四个缩写排成一排看起来像是同一个层级的东西实际上它们干的活差得很远。我早年排查一个“能ping通但网页打不开”的故障时就是因为把这四者混着看先怀疑DHCP没发地址又怀疑NAT没做映射折腾了两个多小时才发现问题出在ICMP的MTU通告被中间设备丢掉了。那次之后我给自己立了个规矩遇到网络问题先判断它属于“地址怎么来的”“地址怎么被改写”“链路上谁在报错”“谁在加入群组”哪一类再动手。这篇文章想讲清楚的就是这四件事。DHCP解决的是主机如何自动获得IP地址、掩码、网关和DNS本质是一个“租约分发系统”NAT解决的是私有地址与公网地址之间的复用与改写本质是一张会话表ICMP是IP层的差错与控制信使它不传数据专管“出事了通知你”IGMP是组播场景下主机与路由器之间的成员关系维护协议只在“一对多”传输里出现。适合谁看写过一点网络代码、配过路由器、抓过包但总觉得这四个协议在心里是散的读者以及需要在真实环境里定位连通性问题的运维和开发。1.1 从“能ping通但打不开网页”这个经典现象说起这个现象之所以经典是因为它天然把四个协议拆开了。ping能通说明ICMP的Echo Request和Echo Reply这条路径是通的同时说明IP层可达、目的主机活着、路由没断。但网页打不开问题可能落在三个地方一是DNS没解析出来这通常和DHCP下发的option 6有关二是TCP的443端口连不上可能是NAT会话没建立或者被策略拦了三是TCP握手完成了但TLS握手卡住这时候往往是MTU问题而MTU问题的发现机制恰恰依赖ICMP的“需要分片”报文。提示判断顺序建议是“先看地址来源再看三层可达再看端口可达最后看传输层细节”。顺序颠倒会让你在无关的层里反复打转。我见过不少人一上来就抓包抓了几百兆的pcap然后在Wireshark里用ip.addr过滤越过滤越糊涂。其实更省时间的做法是先问三个问题这台机器的IP是谁给的这个IP出网时被改写成了什么链路上有没有设备在回ICMP差错这三个问题分别对应DHCP、NAT、ICMP而IGMP只有在涉及直播、视频会议、IPTV这类一对多流量时才需要拉进来。1.2 四个协议在协议栈里的坐标和职责边界把它们放到协议栈上看位置关系就清楚了。DHCP跑在UDP之上服务端用67端口客户端用68端口它属于应用层协议但它配置出来的东西是网络层的参数。NAT不是一个独立协议它是路由器转发路径上的一个动作工作在IP层和传输层之间因为它要改IP头很多实现还要改TCP/UDP头的端口号。ICMP严格来说和IP是同层的它被封装在IP报文里协议号是1IPv6下对应的是ICMPv6协议号58。IGMP同样封装在IP报文里协议号是2只在IPv4组播里用IPv6下这个职能被MLD承担了。协议传输承载关键端口/协议号核心职责典型触发场景DHCPUDP67/68动态分配地址与配置参数主机接入网络、租约到期NAT无转发行为无地址与端口改写、会话复用私网访问公网、端口映射ICMPIP直接封装协议号1差错报告与路径探测TTL耗尽、端口不可达、MTU超限IGMPIP直接封装协议号2组播组成员管理加入/离开组播组这张表我建议贴在工位上。它最大的价值不是记住端口号而是让你在抓包时知道“这个东西应该出现在哪一层”。比如你在抓包文件里看到UDP 68端口的包那基本可以断定是DHCP流程不用再猜看到协议号1的包先看type字段type 3多半是某个设备在告诉你“我这里过不去”。1.3 为什么把这四个放在一起学反而更容易乱教材喜欢把它们并列是因为它们都是“IP协议的配套机制”但对实操的人来说并列会制造一种错觉好像它们在同一层、解决同一类问题。实际上它们的时间尺度完全不同DHCP是分钟到小时级别的租约事件NAT是毫秒级的每个连接都要过一遍的转发动作ICMP是事件驱动的偶发报文IGMP是几十秒到几分钟一次周期性查询。把不同时间尺度的东西放在一张图里脑子自然会糊。另一个容易混的点是“谁在发起”。DHCP由客户端主动发起DISCOVERNAT是转发路径上被动发生的ICMP两个方向都有可能差错报文由路由器发查询报文由主机发IGMP由主机发报告、由路由器发查询。搞清楚发起方你就知道出了问题该去哪台设备上看日志。我在实际排查中形成了一个习惯先在客户端侧确认DHCP租约再在网关侧确认NAT会话再在路径中间确认ICMP是否被丢最后才在组播场景下看IGMP。这个顺序不是死的但它覆盖了八成以上的常见故障。2. DHCP地址从来不是“配”上去的是“租”回来的很多人对DHCP的理解停留在“自动获取IP”这个说法没错但太浅。DHCP的本质是一个带租期的、可续约的、支持中继的配置分发系统。理解“租”这个字很关键因为它决定了一整套行为什么时候续租、续租失败怎么办、租约到期后地址会不会被别人拿走。我在一个跨网段的项目里吃过亏当时以为地址配上去就固定了结果租约到期没续上服务在半夜切换了IP上游的白名单全部失效。2.1 四步握手每一步到底在交换什么标准的DHCP交互是四步DISCOVER、OFFER、REQUEST、ACK。DISCOVER是客户端广播出去的源地址0.0.0.0目的地址255.255.255.255源端口68目的端口67因为此时它还没有地址只能靠广播找服务器。报文里会带上客户端标识通常是MAC、主机名、以及一个参数请求列表告诉服务器“我需要子网掩码、网关、DNS、域名这些”。OFFER是服务器的回应里面包含一个候选地址、租约时长、服务器标识以及客户端请求的那些参数。这里有个细节值得注意如果网络里有多台DHCP服务器客户端可能收到多个OFFER它会选第一个到达的然后在REQUEST阶段广播“我要的是某一台服务器给的地址”这个广播的意义在于让其他服务器撤回它们的offer。REQUEST之后是ACKACK里带着最终确认的参数。除此之外还有几个不常用但很关键的报文NAK表示服务器拒绝通常发生在客户端请求的地址已经不属于这个网段DECLINE是客户端发现拿到的地址冲突了主动告诉服务器“这个地址别给我了”RELEASE是客户端主动释放INFORM是客户端已有地址只想拿其他参数。抓包时可以用过滤器快速定位# 只抓DHCP相关的四个阶段 tcpdump -i eth0 -n -vv udp port 67 or udp port 68输出里你会看到DHCP-Message (53), length 1: DHCP-Discover这样的字段option 53就是报文类型。我一般还会关注option 54服务器标识和option 51租约时间这两个决定了后续续租行为。2.2 租约时间的两个关键节点T1和T2租约不是到期才续而是在一半和八分之七的位置各续一次。假设租约是24小时T1就是12小时T2是21小时。到了T1客户端会发一个单播的REQUEST给原来那台服务器请求续约如果服务器没回应它会继续用等到T2时改成广播REQUEST向任意一台DHCP服务器请求续约如果到租约完全到期还没续上客户端必须放弃这个地址重新走DISCOVER流程。这个机制的实际意义在于单播续约不打扰整个广播域只有出问题了才升级为广播。所以你在抓包时如果看到大量广播DHCP请求往往意味着原来的DHCP服务器不可达了或者中继配置出了问题。注意生产环境里把租约设得过短是常见错误。有人为了“地址回收快”把租约设成10分钟结果终端频繁续约DHCP服务器和广播域压力陡增。一般办公网8小时到1天终端流动大的访客网络可以设2到4小时。服务端侧的配置我也踩过坑。有个环境里地址池配了254个地址但实际在线终端有300多台结果新接入的设备一直拿不到地址。这种问题的表现是客户端反复发DISCOVER但收不到OFFER从客户端侧看像是“网络没通”实际是池子满了。检查方法很直接在服务器上看地址池使用率。2.3 跨网段分配DHCP中继到底改了什么DHCP依赖广播而广播不跨网段。如果客户端和服务器不在同一个二层域里就需要中继。中继设备通常是网关路由器或三层交换机收到广播的DHCP报文后把它转成单播发给服务器同时把自己的接口地址填进giaddr字段。服务器收到后根据giaddr判断客户端属于哪个网段从对应的地址池里分配地址再把回应交给中继中继再转发回客户端。这里有个非常容易忽略的点服务器选择地址池依据的是giaddr不是报文里的其他字段。所以如果中继接口地址配错了网段客户端会拿到一个完全不属于自己网段的地址表现就是“有IP但上不了网”。我遇到过一次中继指向的是一个管理口地址结果终端全都拿到了管理网段的地址网关指向管理网关自然不通。另外中继还可以插入option 82携带接入端口信息服务器可以据此做更精细的分配策略比如按楼层、按端口分配不同地址段。这个功能在园区网里很有用但要注意有些老设备不支持option 82插入后可能导致报文被丢弃。2.4 169.254开头的地址意味着什么如果你看到某台机器拿到的是169.254.x.x不用怀疑它没有拿到DHCP地址这是链路本地地址系统在没有DHCP响应时自动给自己配的。这个地址只能在同一个二层内通信出不了网关。排查路径很固定先看物理链路和VLAN是否正常再看DHCP服务器是否可达再看中继配置最后看地址池是否耗尽。这四步里最容易出问题的是VLAN配置——端口划到了错误的VLANDHCP请求广播出去根本到不了中继。我一般的做法是在客户端抓包确认DISCOVER确实发出去了然后在服务器侧抓包确认是否收到两边一对比就能定位是“没发出去”还是“发出去了没人回”。还有个隐蔽情况某些安全策略会把DHCP报文当成攻击流量丢弃特别是DISCOVER的广播包。这类问题在客户端侧完全看不出来只能在中继或服务器侧看计数器。3. NAT一张会话表撑起的地址复用NAT这个词被用得极广但真正理解它的人在排查问题时优势明显。它的核心不是“转换地址”这么简单而是“为每一个连接维护一条映射记录并在回程时按记录还原”。这张表有容量、有老化时间、有冲突可能这三点决定了绝大多数NAT相关问题。3.1 源NAT与目的NAT改的是不同的字段源NATSNAT改的是出方向报文的源地址典型场景是私网主机访问公网把私网源地址换成公网地址同时往往还要改源端口因为多台内网主机可能用同一个源端口。目的NATDNAT改的是入方向报文的目的地址典型场景是把公网地址的某个端口映射到内网某台服务器的某个端口。两者可以同时存在。比如一个内网服务器既要对外提供服务又要主动访问外网那它出方向走SNAT入方向走DNAT路由器需要同时维护两套映射。这里要强调一个容易误解的点NAT设备判断“这条回程报文属于哪个会话”靠的是五元组匹配即源IP、源端口、目的IP、目的端口、协议。所以端口在NAT里不是可有可无的装饰它是复用地址的关键资源。一个公网IP理论上可用的端口约6.4万个这就是单IP能承载的并发会话上限。3.2 端口分配策略与会话老化时间不同实现的端口分配策略差别很大。有的设备是“按需分配”每建立一个新连接就从端口池里取一个有的是“端口块预分配”一次给一台内网主机分配一段端口减少分配开销。前者的表项数量多但分配灵活后者在高并发场景下性能更好。老化时间是另一个重点。TCP会话有明确的建立和拆除过程设备可以据此判断会话结束UDP没有连接概念只能靠超时。常见的默认值大致是TCP已建立连接几小时到几天TCP半开连接几十秒UDP几十秒到几分钟ICMP十几秒。这些值可以调但调整要谨慎。我处理过一个即时通讯类应用的问题客户端每隔一段时间就掉线重连。查下来是NAT设备的UDP老化时间只有30秒而应用的心跳间隔是45秒会话在两次心跳之间就被回收了回程报文找不到映射直接被丢弃。解决办法要么缩短心跳间隔要么在网关上把这个应用的UDP老化时间调长。3.3 手工查看和验证NAT会话表会看会话表NAT问题基本就解决一半。在Linux网关上通常用conntrack# 查看当前所有会话 conntrack -L # 只看某个内网主机的会话 conntrack -L -s 192.168.10.25 # 统计会话数量判断是否接近上限 conntrack -C输出里会明确写出原始五元组和转换后的五元组形如src192.168.10.25 dst203.0.113.10 sport51234 dport443 src198.51.100.7 dst203.0.113.10 sport40001 dport443。前半段是内网视角后半段是公网视角一一对应。在一些商用设备上查看方式不同通常是命令行里查会话表或者Web界面看连接数。不管哪种设备验证思路是一样的从内网发起一个连接然后在设备上查这条连接对应的公网映射是否存在再从外部发起回程测试。3.4 NAT带来的副作用为什么有些应用总是“时好时坏”NAT对纯IP层是无感的但对在载荷里携带地址信息的协议就不友好。典型的是FTP的主动模式服务端要主动连回客户端的一个端口而客户端在私网里服务端拿到的地址是私网地址根本连不回来。解决办法是用被动模式或者在网关上做应用层网关ALG解析载荷里的地址并改写。SIP、H.323这类VoIP协议也有同样的问题载荷里带着SDP描述的IP和端口。很多设备的ALG实现质量参差不齐开着反而出问题关掉又通不了这是运维里很烦的一类情况。我的经验是能用应用层自己解决的就不要依赖ALG比如让客户端配置对外通告的地址比让网关去改载荷更可控。另一类副作用是连接跟踪表被打满。某些P2P类应用或者扫描行为会瞬间建立大量会话表满了之后新连接全部失败表现是“网络时断时续”。这时候看conntrack计数就能确认conntrack -C接近上限值就是它。临时办法是清理老化会话长期办法是限制单IP会话数或者扩容。4. ICMP不只是ping它是IP层的信使把ICMP等同于ping是很多人网络知识里的一个大坑。ping只是ICMP里最简单的一对报文type 8请求、type 0回应而ICMP真正的价值在于差错报告——当IP报文送不到时它是唯一能告诉你“为什么送不到”的机制。4.1 type和code的组合语义ICMP报文头里有两个字段type和code。type表示大类code表示细分原因。常用的组合不多但每一条都有明确的排查含义。typecode含义排查提示00Echo应答ping通三层可达30网络不可达路由表里没有到目的网段的路由31主机不可达网段可达但目的主机不响应ARP33端口不可达目的主机回了RST或没有监听该端口34需要分片但DF置位典型MTU问题必须处理80Echo请求主动发起探测110TTL超时traceroute的原理来源111分片重组超时分片丢失常见于大包50-3重定向有更优下一跳通常应关闭type 3 code 3端口不可达特别值得说。UDP没有连接当你往一个没有监听的UDP端口发包时对方主机的协议栈会回一个端口不可达。有些工具就是靠这个判断主机是否存活。但也正因为如此如果防火墙把这类报文丢了工具就会误判为“主机不在线”。4.2 PMTU发现大包不通的真正原因这是ICMP在实际环境里最重要的用途也是最容易被防火墙误伤的地方。路径MTU发现的工作机制是发送方把IP头的DF不分片位置1按自己接口的MTU发包路径中间某台设备的出接口MTU更小包发不出去又不能分片它就回一个type 3 code 4并在报文里带上它支持的MTU值发送方收到后调小自己的发送尺寸重传。如果这个ICMP报文被中间设备丢弃发送方永远收不到通知就会一直重传大包表现出来就是“小包能通、大包不通”“网页能打开但图片加载不出来”“SSH能登录但一执行大命令就卡死”。我做压力测试时遇到过典型症状HTTP GET小文件正常下载稍大的文件就挂住最后确认是链路上有一段MTU是1400而ICMP被策略拦了。常见的MTU换算以太网标准1500减去IP头20和TCP头20TCP载荷最大1460如果走PPPoE还要再减8变成1492/1452。ping可以用来验证# 测试路径MTU-M do 表示禁止分片-s 指定载荷大小 ping -M do -s 1472 203.0.113.10 # 1472 8(ICMP头) 20(IP头) 1500正好等于标准以太网MTU # 如果这个尺寸不通而1472以下能通说明路径MTU小于1500注意很多云环境和隧道环境的基础MTU不是1500而是1450或1400。部署服务前先用上面的命令确认一遍比出问题后再查省事得多。4.3 防火墙该不该放行ICMP这是个老生常谈的问题。完全的“禁ping”看似安全实则破坏了PMTU发现和traceroute这两个诊断能力。我的建议是分类型处理Echo请求可以在边界上限制速率而不是完全禁止type 3 code 4必须放行否则MTU问题无解type 11可以放行type 5重定向建议直接关闭因为现代网络拓扑下它带来的风险大于收益。内网侧我一般全放行ICMP只在边界做速率限制。原因很简单内网里禁ping之后一旦出问题排查时间会成倍增加而收益几乎为零。4.4 用TTL递增做路径探测traceroute的原理就是利用ICMP的TTL超时报文。发送方先发TTL1的包第一跳路由器收到后TTL减到0回一个type 11 code 0再发TTL2的包第二跳回超时如此递增直到到达目的主机。每一跳的地址就是从这些超时报文里提取的。Linux下默认用UDP高端口发包Windows下用ICMP Echo。两者在被防火墙拦截时的表现不同所以有时候同一个目标在两种系统上追踪结果不一致不必惊讶。如果中间某几跳显示星号通常是对应设备不回应或限速了ICMP超时报文不代表路径断了。# 指定用ICMP模式追踪-I 参数 traceroute -I 203.0.113.10 # 指定最大跳数和每跳探测次数 traceroute -m 20 -q 3 203.0.113.10路径探测的结果要结合网络拓扑看。有一次我看到第5跳到第9跳都在同一个网段里来回一开始以为是路由环路后来发现是那几台设备用了同一个管理地址段实际是正常的多路径转发。这类“看起来像问题其实不是”的情况只能靠对拓扑的了解来判断。5. IGMP组播成员关系的维护者组播是四个协议里最少被日常接触到的但只要涉及视频直播、视频会议、桌面推送、监控视频流就绕不开它。IGMP的职责非常单一让主机告诉路由器“我要加入某个组”让路由器知道“这个网段上还有没有人关心这个组”。5.1 组播地址与MAC地址的映射关系组播IP地址范围是224.0.0.0到239.255.255.255其中224.0.0.0/24是本地链路范围TTL通常为1不被转发。几个固定地址要记住224.0.0.1是所有主机224.0.0.2是所有路由器224.0.0.22是IGMPv3报告224.0.0.251是mDNS。239.0.0.0/8是管理范围地址企业内部分配组播地址一般从这里取。组播IP到组播MAC的映射规则是取IP的低23位加上固定的01:00:5e前缀。这意味着32个不同的组播IP会映射到同一个MAC地址。这个设计是历史妥协的结果带来的后果是网卡层面无法精确过滤需要靠协议栈再判断一次IP。做组播应用开发的人如果不知道这一点可能会疑惑“为什么我收到了不属于我的组播包”。5.2 IGMP三个版本到底差在哪IGMPv1只有两种报文查询和报告。主机加入组就发报告路由器定期发查询主机收到查询后再发报告确认还在。没有离开报文路由器只能靠超时判断组里没人了收敛慢。IGMPv2增加了离开报文和特定组查询。主机离开时主动发Leave路由器收到后发一个特定组查询确认是否还有其他主机在没有就立即停止转发。收敛时间从分钟级降到秒级。v2还增加了查询器的选举机制同一网段上多个路由器时IP地址最小的那个当查询器。IGMPv3的核心增强是源过滤主机可以指定“只接收来自某些源的流量”或者“排除某些源”。这对SSM指定源组播是必需的。v3的报告报文结构比v2复杂得多可以携带多个组记录和源列表。版本离开机制源过滤查询器选举典型使用场景v1无靠超时不支持无老旧设备兼容v2有Leave报文不支持支持大多数企业组播v3有支持支持指定源组播、IPTV5.3 查询器、报告抑制与收敛时间组播里有个很巧妙的设计叫报告抑制。主机收到查询后不会立刻发报告而是随机延迟一段时间如果在这段时间内听到同组其他主机发了报告自己就不发了。这样同一个组在网段上只需要一份报告路由器就知道“这个组还有人要”。这个机制带来的副作用是如果网段上只有一台主机它的报告延迟就是最大响应时间通常是10秒。也就是说从主机加入组到路由器开始转发最多可能有10秒延迟。做实时性要求高的应用时这个延迟必须考虑进去。查询器的默认参数是查询间隔125秒其他查询器抑制时间125秒健壮系数2最大响应时间10秒。健壮系数决定了路由器在连续丢失几次查询后才认为组没人了。这几个值一般不用改改了要保证全网一致否则收敛行为会很怪。5.4 交换机上的IGMP Snooping不配就是广播这是组播部署里最常见的坑。IGMP是三层协议主机和路由器之间交互没问题但中间的交换机如果不认识IGMP它会把组播帧当成广播帧向所有端口泛洪。一个网段里有几十台主机在看不同的组播流每一台都会收到全部流量带宽瞬间被打满。IGMP Snooping的作用就是让交换机“偷看”IGMP报文建立一张“哪个端口有哪些组”的表然后只向需要的端口转发。配置上通常要开启snooping指定一个VLAN然后把连接路由器的端口配成组播路由器端口把连接主机的端口配成成员端口。# 以常见交换机命令风格示意具体语法随设备而异 igmp-snooping enable igmp-snooping vlan 100 interface gigabitethernet 1/0/1 igmp-snooping mrouter-port注意开启snooping后如果路由器端口没配对组播流量会突然中断。因为交换机认为没有路由器在发组播就把流量丢了。这个现象很像“组播时通时断”实际是配置遗漏。还有些环境用组播代理或者组播到单播转换来规避组播配置复杂度这是工程上的合理取舍。组播配置涉及主机、接入交换机、汇聚路由器、内容源多个环节任一环节没配好都不通调试成本确实高。6. 四个协议交叉排查的实战链路单独理解一个协议不难难的是故障现场它们同时出现。我把自己常用的排查流程整理成一条链路从下往上走每步都有明确的观察点。6.1 分层确认的顺序与各自的观察点第一步看地址。客户端拿到什么地址、掩码、网关、DNS如果是169.254开头或者为空问题在DHCP或链路层。如果是正常的私网地址进入第二步。第二步看三层可达。ping网关通不通不通说明二层或VLAN有问题通但ping外网不通看路由和NAT。这一步用的就是ICMP。第三步看端口可达。用telnet或者nc测试目标端口如果返回端口不可达的ICMP说明报文到了目的主机但没服务在听如果超时说明报文在中间被丢了。第四步看NAT会话。在网关上确认这条连接是否有对应的映射记录有记录说明转发正常问题在更上层没记录说明报文没到网关或者被策略拦了。第五步才看MTU和组播。只有在“小包通大包不通”或者“一对多传输异常”时才需要往下走。这条链路的价值在于每一步都能给出确定的是/否结论避免在多个层之间反复横跳。我见过有人一上来就怀疑NAT改了半天映射规则最后发现是DHCP下发错了网关。6.2 一个组播视频流不通的完整排查示例假设场景是这样某会议室要播放一路组播视频主机加入了组224.1.1.1但黑屏。排查我按这个顺序走。先确认主机侧。用命令看本机是否成功加入了组# 查看本机加入的组播组 ip maddr show # 或者用netstat看 netstat -g如果列表里没有224.1.1.1说明加入动作没成功可能是应用程序没调setsockopt或者本机IGMP被禁了。再确认IGMP报文有没有发出去。在主机上抓包tcpdump -i eth0 -n -vv igmp应该能看到type 0x16v2报告或者0x22v3报告的报文。如果看不到说明本机没发如果看到了说明主机侧没问题往上找。然后看接入交换机。检查snooping表里有没有这个组和对应的端口。如果没有可能是snooping没开或者mrouter端口没配导致报告报文没被正确处理。再看路由器。检查组播路由表和IGMP组成员表确认路由器是否知道这个组在哪个接口下有成员以及是否有到源的组播路由。组播路由和单播路由是两套东西很多人只配了单播路由就以为组播能通。最后看源。源是否真的在往这个组发流TTL够不够源到接收者之间的每一跳是否都开了组播路由。组播的RPF检查要求报文从“到源的最短路径接口”进来路径不对称时会直接丢弃这也是常见问题。这一圈走下来基本能定位到具体环节。整个过程里DHCP只是提供地址一般不会是组播不通的原因但它会在最开始影响主机能否正常入网所以第一步还是要确认地址正常。6.3 抓包时优先看哪几个字段抓包谁都会看对字段才是本事。我列出自己每次必看的几个点。DHCP报文看option 53判断阶段看option 54确认是哪台服务器回的看option 51算续租时间看giaddr判断是否经过中继。NAT相关的包重点看同一会话在两个方向上的地址端口变化。在网关两侧同时抓把两侧的五元组对起来映射关系一目了然。ICMP报文先看type再看code然后看报文里携带的原始IP头。type 3的报文里会带回触发差错的原始报文的前一部分这部分信息非常关键能告诉你到底是哪个包触发了差错、它的DF位是什么、它的长度是多少。IGMP报文看type和group addressv3还要看记录数和源列表。查询报文的max resp code字段决定了主机的最大响应延迟这个值异常大会导致加入组后长时间收不到流。# 一个组合过滤器同时看四个协议 tcpdump -i any -n -vv (udp port 67 or udp port 68) or icmp or igmp这个过滤器在排查综合性问题时很有用但输出量大建议配合时间窗口或者主机过滤一起用。6.4 几个反直觉的经验第一个经验ping不通不代表主机不在线。ICMP可能被策略拦也可能被限速。判断主机存活更可靠的方式是看ARP表或者用TCP端口探测。第二个经验NAT表里有记录不代表通信正常。记录只说明报文经过了网关回程能不能回来还要看路由和策略。我遇到过会话建立了但回程路由指错的情况表现是“发得出去收不回来”。第三个经验组播不通时先怀疑交换机而不是路由器。大部分组播故障出在接入层的snooping配置上因为路由器侧的组播配置一旦配好就很稳定而接入层经常有新设备接入、VLAN调整这类变动。第四个经验DHCP问题优先看中继。同一网段内DHCP出问题的概率远低于跨网段因为跨网段多了一跳中继配置项多了一倍。6.5 把这四个协议当成一套工具箱来用写到这里我想说一个体会。这四年我处理过的网络问题里真正需要深入某个协议细节的不到两成八成的问题靠“知道该看哪个协议的哪个字段”就能定位。DHCP告诉你地址从哪来NAT告诉你地址被改成了什么ICMP告诉你链路上谁在报错IGMP告诉你有谁在关心同一份流量。把这四个问题问清楚绝大多数连通性故障都能收敛到一个小范围内。我个人在实际操作中的习惯是接手一个新环境先做三件事抓一次完整的DHCP交互确认地址分发链路在网关上导一份NAT会话表看看有没有异常大的会话数用traceroute走一遍关键路径确认ICMP没有被大面积丢弃。这三件事做完对这个网络的脾气就有基本判断了后面再出问题排查起点会清晰很多。如果后续要在这个基础上扩展我建议往两个方向走一是把IPv6下的对应机制补齐DHCPv6、NPTv6、ICMPv6、MLD虽然思路相近但细节差别不小尤其是ICMPv6承担了邻居发现的重任地位比IPv4下高得多二是把抓包分析做成固定流程把常见故障的报文特征整理成对照表下次遇到直接比对比临场推理快得多。