ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

IP协议详解:从IPv4头部字段到路由转发的网络排障实战

IP协议详解:从IPv4头部字段到路由转发的网络排障实战

排查网络故障的时候,我最先看的往往不是应用层,而是 IP 这一层。你抓包也好,用 traceroute 看路径也罢,数据包里最显眼的那个源地址和目标地址,就写在 IP 头上。TCP/IP 协议模型详解这个系列写到第三篇,我终于要聊到网络层的核心——IP 协议。如果说 TCP 负责的是“可靠地把数据送到”,那 IP 负责的就是“找对路,送到对的地方”。这篇文章适合正在学网络基础的学生、刚入行的运维、以及被“为什么上不了网”折磨过的开发者。

每次用 ping 能通、curl 却卡住的时候,很多人会下意识怀疑 DNS 或应用本身,但真正的根因经常埋在 IP 层:路由没有下一跳、TTL 被减到零、报文被分片后丢失、IP 地址冲突。这些场景里的“罪魁祸首”,都是我们今天要拆解的 IP 协议。下面我按自己的学习路径和排障习惯,把这层的东西完整过一遍。

1. IP协议在TCP/IP模型中的位置与三大使命

1.1 网络层的职责边界

TCP/IP 模型一共四层:链路层、网络层、传输层、应用层。链路层解决的是“同一根网线里怎么把比特组成帧”,传输层解决的是“数据怎么可靠地交给某个进程”,应用层解决的是“数据长什么样、怎么解释”。网络层夹在中间,干的事最简单也最麻烦:它不关心数据的内容,也不关心使用什么端口,只负责把数据包从源主机送到目的主机。

这个“送”字,听起来像快递物流。IP 协议做的事情,就是给每一个数据包贴上一张“快递面单”:上面写着发件人地址(源 IP)、收件人地址(目的 IP)、这件包裹总共多大、是不是被拆过箱、最多允许中转多少次。链路层的 MAC 地址负责“相邻两站之间怎么走”,而 IP 地址负责“整条路怎么走”。

1.2 三大核心任务:寻址、分片、路由

IP 协议在网络层承担三件大事。

第一件是寻址。IPv4 用 32 位二进制给每台主机编号,这就是我们熟悉的点分十进制 IP 地址。没有这个编号,网络设备根本不知道数据该往哪里送。

第二件是分片与重组。以太网帧的载荷上限通常是 1500 字节,而 IP 报文可能更大。当报文超过下一跳链路的 MTU(最大传输单元)时,IP 协议会把报文拆成几个小片,到达目的地后再重组。注意是“到达目的地后再重组”,不是每一跳都重组,这一点很多人会搞错。

第三件是路由。每个路由器维护一张路由表,收到一个 IP 分组,就查一下目的地址应该送向哪个接口、哪个下一跳。这个过程被称作逐跳转发。

1.3 为什么值得单独写一篇

很多人觉得 IP 协议很“基础”,不值得单独拉一篇出来。但实际工作中,二次开发、网络优化、故障排查,绕不开的恰恰是 IP 头部那些字段。TCP 的序号和确认号,是保证“不丢不乱”的机制;IP 的标识符、标志位和片偏移,是保证“大数据在受限链路上能传过去”的机制。不懂分片,你就不明白为什么大 ping 包通、小 ping 包不通;不懂 TTL,你就看不明白 traceroute 的原理。这篇我打算把 IPv4 头的每个字段掰开揉碎,再讲地址规划、路由转发和排障实战。

2. 拆开IPv4协议头:20字节里的门道

2.1 六个必须背下来的核心字段

IPv4 的标准头部长度是 20 字节,没有可选项的话就是这个数。从头到尾依次是:版本号(4 bit)、头部长度 IHL(4 bit)、服务类型(8 bit)、总长度(16 bit)、标识符 Identification(16 bit)、标志位 Flags(3 bit)、片偏移(13 bit)、生存时间 TTL(8 bit)、上层协议号(8 bit)、头部校验和(16 bit)、源 IP(32 bit)、目的 IP(32 bit)。

版本号永远填 4,这没什么好说的。头部长度字段的单位是“4 字节”,也就是说如果值是 5,表示头部是 5×4=20 字节;如果带了可选项,这个值会变大。总长度字段告诉接收方“这个 IP 报文整体多大”,单位是字节,最大 65535。这里要特别留意:IP 总长度包含头部,而 TCP/UDP 报文段的长度是从 IP 总长度里减去头部长度推算出来的。

2.2 标识符、标志位、片偏移:分片三元组

这个组合是 IP 层排障中最容易被忽略的地方。标识符 Identification 用来标识“同一个原始报文的所有分片”,发送方每发一个原始 IP 报文,标识符就加一,分片时所有小片共享同一个标识符。标志位里有两位关键:DF(Don't Fragment,不允许分片)和 MF(More Fragments,后面还有分片)。片偏移(Fragment Offset)字段的单位是 8 字节,表示当前分片的数据部分在原始报文中的位置,所以分片的数据部分长度必须能被 8 整除。

三个字段配合起来,接收方可以判断:这些片是不是同一个报文的、顺序怎么排、是不是全部到齐了。我在实际抓包里见过很多因为分片重组失败导致的传输问题:MF 位为 1 的包迟迟不来,接收方缓存已满,只能把之前收到的分片全部丢弃。

2.3 TTL:控制数据报一生的计数器

TTL(Time To Live)是一个 8 位计数器,源主机设置初始值,常见的是 64、128、255。每经过一台路由器,TTL 减一;减到 0 时路由器直接丢弃这个包,同时回给源主机一个 ICMP 超时消息。之所以要有这个机制,是防止数据包在网络环路里无限兜圈子。

这也是 traceroute 的原理:先发一个 TTL=1 的包,第一跳路由器丢弃并回复超时;再发 TTL=2 的包,第二跳丢弃并回复超时……以此类推,就能把路径上每一跳的 IP 地址都“问”出来。你ping 某个 IP 时看到“Time to live exceeded”,往往不是目标主机不回包,而是路径中间有节点把包丢了。

3. IP地址体系:分类、子网与CIDR

3.1 IPv4地址分类与特殊地址的坑

传统上 IPv4 地址分成 A、B、C、D、E 五类。A 类从 1.0.0.0 到 126.255.255.255,默认掩码 /8;B 类从 128.0.0.0 到 191.255.255.255,默认掩码 /16;C 类从 192.0.0.0 到 223.255.255.255,默认掩码 /24;D 类是组播地址,224.0.0.0 到 239.255.255.255;E 类保留研究用。

有几个特殊地址必须记住:127.0.0.0/8 是回环地址,发到 127.0.0.1 的包不会真正的出网卡,而是由本机协议栈处理;169.254.0.0/16 是链路本地地址,当设备没拿到 DHCP 地址时,Windows 和 Linux 会自动给自己配置这个网段的地址,很多人看到“IP 地址是 169.254.x.x”就知道 DHCP 失败了;私网地址则是 10.0.0.0/8、172.16.0.0/12、192.16 8.0.0/16 这三个段,公网上不可路由。

3.2 子网掩码与CIDR计算实战

子网掩码的作用是区分“网络位”和“主机位”。比如 255.255.255.0 的二进制是连续 24 个 1,代表前 24 位是网络位。后来大家觉得分类太死板,直接用 CIDR 记法:/24 就代表掩码前 24 位为 1,/26 就是前 26 位为 1,对应的掩码是 255.255.255.192。

来算一个实际的例子。192.168.1.0/26,网络位 26 位,主机位 6 位,能用的主机数量是 2 的 6 次方减 2,也就是 62 台(去掉网络地址和广播地址)。这个子网的范围是 192.168.1.0 到 192.168.1.63,其中 .0 是网络地址,.63 是广播地址,可用地址从 .1 到 .62。如果一个办公室里接了 63 台电脑,你给他们配 /26,就一定会有一台获取不到地址——这种边界问题,实打实地出现在日常维护里。

3.3 变长子网掩码与地址规划

VLSM(可变长子网掩码)让你把一个较大的网段切成多个大小不一的子网。比如把 192.168.1.0/24 分成四个 /26,每个子网 62 个可用地址;也可以切一个 /25(126 个可用)再切两个 /26,这样合计 126+62+62=250,正好覆盖 250 台终端的场景。

做地址规划的原则,我自己的经验是“按区域收敛、给未来留余量”。比如办公区、生产区、管理区各用独立网段,设备互联地址一律用 /30(四个地址里只有两个可用,最省地址)。有人会觉得这样浪费,但真出网络隔离问题时,清晰的地址规划能让你一眼看出哪些流量不该互通。

4. 路由与转发:把IP数据包送到目的地

4.1 逐跳转发的基本原理

IP 数据报的转发方式是逐跳的。源主机把包交给默认网关,网关路由器查路由表,决定下一跳是谁,然后从对应接口送出去;下一跳继续做同样的事,直到抵达目标网段。你电脑上的默认网关,就是本机的“下一跳”出口;而每一跳只关心“下一步怎么走”,并不关心整条路径是什么样。

这也解释了为什么路由器的 WAN 口和 LAN 口 IP 通常不在同一网段:它必须既能作为内网的网关,又能通过外网侧路由表找到互联网出口。

4.2 路由表与最长前缀匹配

路由器选择路径时,不是看“哪条路由条目先出现”,而是看“哪条条目最精确地匹配目的地址”。这个规则叫最长前缀匹配。Linux 里用 ip route show 能看到路由表,比如默认路由 0.0.0.0/0 是一个兜底规则,任何地址都匹配;而 192.168.1.0/24 的规则只匹配这个网段内的地址。要访问 192.168.1.8 时,同时有默认路由和这条具体路由,路由器一定选后者,因为 /24 的掩码比 /0 长、更精确。

找下一跳时,如果配置错误,比如某条路由的下一跳根本无法通过链路层到达,包就会被丢弃然后在控制平面报错。排障时我习惯先看 ip route 里有没有默认路由,没有默认路由,外网一定不通,不管网线亮不亮。

4.3 静态路由与动态路由协议

小型网络用静态路由就够了,每条路手动写好:目标网段、掩码、下一跳。但网络一大,手动维护不可行,于是有了动态路由协议。内部网关协议里,RIP 用跳数选路,OSPF 用链路状态与最短路径算法选路;外部网关协议的霸主则是 BGP。

对于普通运维和开发来说,理解一个概念就够了:动态路由协议是为了“在网络拓扑变化时自动收敛”而存在的。链路断了,OSPF 秒级收敛,流量自动切到备用路径;如果没有动态协议,只能等人工去改静态路由,业务中断时间往往从分钟级起算。

4.4 NAT:私网地址如何上网

家里路由器给你分配的 192.168.x.x 是私网地址,互联网上没人知道怎么把包送回来。NAT(网络地址转换)在这里起了关键作用:出方向的包,路由器把源地址换成自己的公网 IP,同时记录一条会话映射;回来的包,根据映射再转换回内网地址。

PAT(端口复用 NAT)是家用场景最常见的形式,几十台终端共享一个公网 IP,靠不同端口区分会话。这里最容易踩的坑是:内网服务器要被外部访问时,必须做端口映射,并且要理解 NAT 只认四元组映射,不是单纯改个 IP 那么简单。有些老旧应用协议不兼容 NAT,需要路由器开启 ALG 模块,比如 FTP 的主动模式。

5. IP协议的左膀右臂:ARP、ICMP与IGMP

5.1 ARP:把IP地址翻译成MAC地址

IP 地址负责“送到哪个网络”,但最终在同一段链路里传输时,靠的是 MAC 地址。ARP(地址解析协议)就是干这个翻译工作的。主机 A 要发给主机 B 时,会先查自己的 ARP 缓存,没有就会在本地广播:“谁是 192.168.1.2,请告诉你的 MAC 地址”。被询问的主机单播回复,A 收到后缓存结果,再发送真正的 IP 数据报。

注意 ARP 只工作在 IPv4 的局域网内。它能被恶意利用,比如伪造 ARP 回复让对方把流量发到攻击者机器上,这就是 ARP 欺骗。交换机上的动态 ARP 检测、静态 ARP 绑定可以缓解,但根上的思路是:不要信任局域网内不可控的设备。在路由器上查看接入设备时,第一件事就是对照 IP 和 MAC 是不是你认识的人。

5.2 ICMP:Ping和Traceroute都靠它

ICMP(因特网控制消息协议)是 IP 的附属协议,本质是传输“控制消息和错误信息”。最常见的两类:Echo Request(类型 8)和 Echo Reply(类型 0),这就是 ping 的底层;Destination Unreachable(类型 3)告诉你目标不可达或协议端口不可达;Time Exceeded(类型 11)告诉源主机有包 TTL 超时了。

抓包的时候要注意,ICMP 报文外面也套着 IP 头,所以它实际上是由 IP 承载的。用 tcpdump 抓 ICMP 流量时,你会看到一层 IP、一层 ICMP。而当防火墙禁了 ICMP 时,ping 不通不代表网络不通,这也是排查中最重要的认知。

5.3 IGMP与组播

组播场景里,主机要用 IGMP(组管理协议)告诉路由器自己加入了哪个组播组。上路由器查询,组员回复报告,离开时发送离开报文。普通业务的单向视频直播、IPTV 偶尔会用到。

说实话组播在企业网里不是高频场景,但云计算里负载均衡、VXLAN 控制面偶尔也会碰到组播概念,了解 IGMP 的三类消息不至于让你一头雾水。先记住一个点:IGMP 管的是“主机与路由器之间关于组播组成员关系”的通信,路由器和路由器之间的组播路由,那是另一套协议的事。

6. IPv6:新一代IP协议的关键变化

6.1 128位地址与压缩规则

IPv6 的地址长度是 128 位,表示成 8 组十六进制数,每组 16 位。比如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。它允许多种压缩写法:每组的开头零可以省略,连续的全零组可以用一对冒号 :: 替代,但只能替代一次,否则接收方无法判断省略了多少。

这也是一个高频排障点。如果你看到地址里出现了两个 ::,那一定是错的。链路本地地址 fe80::/10 几乎每个 IPv6 网卡都有,它只在本地链路内有效,不允许被路由转发,也没有公网意义。

6.2 协议头和分片机制的变化

IPv6 基本头固定 40 字节,把 IPv4 头里很多字段删掉了。没有头部长度字段,没有头部校验和,没有分片字段。IPv6 的分片信息被放进扩展头,而且只有源节点可以分片,中间路由器不允许再对 IPv6 报文分片。这条路强行要求端到端做路径 MTU 发现,好处是转发更快、处理更简单,代价是如果 ICMPv6 错误消息被防火墙丢弃,就可能出现“大包不通小包通”的经典问题。

另外一个重要变化:IPv4 的广播在 IPv6 里被彻底去掉了,对应的场景由组播承担。这减少了不必要的局域网打扰,也让地址扫描变得更难,算是一个安全上的加分项。

6.3 IPv6过渡与双栈

目前部署 IPv6 最常见的方式是双栈:设备同时配置 IPv4 地址和 IPv6 地址,应用优先走 IPv6,不行再回落到 IPv4。过渡技术还有各种隧道和翻译方案。

如果你是运维,短期内最重要的还是学会在设备上配置双栈、看懂 ip -6 addr 的输出,以及知道 fe80:: 开头的地址为什么不能被当成公网地址来访问。IPv6 排障思路和 IPv4 基本一致:先确认本机地址,再 ping 网关的链路本地地址或全局地址,再用 traceroute6 看路径。

7. 排障实战:IP层的常见坑与快速定位法

7.1 本机IP配置检查的完整命令

排障第一步,永远是确认本机配置。Windows 上用 ipconfig /all,重点看四行:IPv4 地址、子网掩码、默认网关、DNS 服务器。Linux 上直接 ip addr 查看接口状态和地址,ip route show 查看路由表。如果地址是 169.254.x.x,说明 DHCP 没通;如果网关地址和本机 IP 不在同一网段,包根本出不去。

很多新手忽略的一点是:配置了静态 IP 但忘了配网关,或者网关 IP 写错,系统不会报错,但 ping 外网直接 timeout。所以看到“网络图标正常”不等于“能上网”,一定要用命令确认。

7.2 用Ping大小包定位MTU问题

如果你发现访问某个网站特别慢、大文件传输卡住,而网页浏览正常,优先怀疑 MTU 问题。用 Windows 的 ping -l 参数发不同的包大小:先从 1472 开始(1500 减 28 字节的 IP+ICMP 头),能通就往下减,不能通往上加,逐步找到临界值。PPPoE 拨号环境下 MTU 一般是 1492,所以 1500 字节的包过去会被分片,如果分片被运营商设备丢弃,就会出现大包不通。

如果发现 MTU 值异常小,就需要在客户端或路由器上调整 MTU。这个排查方法对 IPv6 同样适用,只是 ICMPv6 的“包太大”消息更明确,因为源节点本来就不允许中间路由器分片。

7.3 抓包看IP层异常的三种典型情况

抓包是观察 IP 层最直接的手段。Linux 上 tcpdump -i eth0 icmp,Windows 上用 Wireshark 过滤 icmp 或 ip.addr==目标IP。

三种典型的异常情况:第一种,只有请求没有响应,说明回包被丢弃或目标主机没回;第二种,看到多个相同 Identification 的分片,但一直没收到 MF=0 的最后一个分片,说明分片丢失;第三种,连续出现 TTL exceeded,说明路径出现了环路或路由配置错误,数据包在绕圈。

还有一种容易被忽略的情况:目的不可达的 ICMP 返回包中带有一段原始 IP 头和前 8 字节数据,这段内容会精确告诉你哪个包出了什么问题。看 ICMP 错误消息时,务必顺着它的嵌套结构找到原始报文的信息,那才是真正的排障线索。

7.4 IP层问题快速排查清单

现象可能原因优先排查手段
本机拿到 169.254 地址DHCP 未通或服务故障检查网卡与 DHCP 服务
ping 网关不通网线/无线断开、IP 冲突ipconfig /all 核对地址与网关
ping 网关通、外网不通没有默认路由或 NAT 失效ip route 查看 0.0.0.0/0
大包通小包不通MTU 不一致或分片被丢弃调节 ping 包大小找临界值
某段路径 TTL exceeded中间路由器丢弃或环路traceroute 逐跳观察
访问内网服务超时没有精确路由或防火墙拦截检查路由表与抓包确认丢包点

这套清单是我实际排查时反复用到的。很多时候出问题的不只是某一个点,而是链路整体,建议从链路层往上逐层确认:网线通不通、IP 正不正确、路由有没有、以及防火墙有没有悄悄丢掉你需要的协议。

最后再分享一点心得

写了这么多,最想强调的是别把 IP 协议当成一堆需要死记硬背的字段。它本质上就是一张快递单:把你的数据包安全地、按规则地送到目的地。遇到网络问题,先看地址、再看路由、最后抓包,能解决绝大多数让人头秃的情况。IPv4 和 IPv6 的细节虽然有差异,但排查思路是通用的。多亲手敲几次 ipconfig、route、tcpdump,比看多少篇详解都管用——这是我踩了无数次坑之后,最想提醒你的一句话。

返回列表