TCP/IP 协议栈:从 IP 到 ICMP
0. 元信息
- 主题路径:
docs/topics/network/subtopics/tcp-ip-stack/ - 父主题:
network - 主分类:计算机基础
- 辅助分类:工程技术
- 适合对象:懂二层帧、MAC、以太网 ARP 和基本 Linux 命令的学习者
- 建议周期:3~4 周(每周 6~8 小时,含抓包、命令实验、复盘)
- 前置知识:
physical-and-link-layer;会ip、ss、ping基本用法 - 最终目标:能读懂 IPv4/IPv6 报文头、做完 CIDR 划分、用
traceroute/mtr/tcpdump定位丢包和 MTU 问题
1. 学习路线
二层交付边界
→ IPv4 报文头与编址
→ CIDR 与子网计算
→ 路由表与最长前缀匹配
→ MTU、分片、PMTUD
→ ICMP 类型与代码
→ NAT 与 conntrack
→ IPv6 报文、地址、邻居发现
→ Linux 抓包与综合排障
每一步都要在两台机器上抓一次包。坑在「只看 RFC 不抓包」——字段太多,背不下来;看到真实字节流才算入门。
2. 阶段周数分配
| 阶段 | 3 周方案 | 4 周方案 | 备注 |
|---|---|---|---|
| 1. IPv4 报文 | 0.5 周 | 0.75 周 | 字段逐位对照 tcpdump -vv -X |
| 2. CIDR 与编址 | 0.5 周 | 0.75 周 | 20 道手算 + 5 道 ipcalc 验证 |
| 3. 路由与转发 | 0.5 周 | 0.75 周 | 用 network namespace 做三跳实验 |
| 4. MTU 与 ICMP | 0.5 周 | 0.5 周 | 抓 Echo、TTL Exceeded、Fragmentation Needed |
| 5. NAT | 0.5 周 | 0.5 周 | 抓转换前后的五元组 |
| 6. IPv6 | 0.5 周 | 0.75 周 | 地址、扩展头、NDP、PMTUD |
| 7. 综合排障 | 0.5 周 | 0.5 周 | traceroute + mtr + tcpdump 联用 |
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 可观察学会标准 |
|---|---|---|---|
| 1. 分层边界 | Internet 层职责、hop-by-hop vs end-to-end、封装关系 | 一张主机→路由器→主机的字段变化图 | 能解释为什么 IP 不保证可靠和顺序 |
| 2. IPv4 报文 | Version、IHL、DSCP/ECN、Total Length、ID、Flags、Fragment Offset、TTL、Protocol、Header Checksum、源/目的 IP | 一份带字段标注的 tcpdump -vv -X 输出 | 能从十六进制定位 TTL、Protocol 和地址 |
| 3. CIDR | 前缀长度、子网掩码、网络号、广播地址、可用主机范围、路由聚合 | 20 道子网计算(含 /20、/27、/30) | 2 分钟内口算任意 /N 边界 |
| 4. 路由 | 直连、静态、默认路由、metric、ECMP、最长前缀匹配 | 三 namespace + 两 veth 拓扑实验 | 能预测一个目的 IP 走哪条路由 |
| 5. MTU | 链路 MTU、IP 分片、DF 位、PMTUD、IPv6 不分片 | 不同负载长度的 ping -s/-M do 实验 | 能区分「链路丢包」与「MTU black hole」 |
| 6. ICMP | Echo、Destination Unreachable、Time Exceeded、Redirect、Fragmentation Needed、Parameter Problem | ICMP 类型/代码对照表 | 能从 type/code 判断失败环节 |
| 7. NAT | SNAT、DNAT、PAT、conntrack、Hairpin NAT、ALG | 抓包对比转换前后五元组 | 能解释 NAT 为什么破坏端到端可达性 |
| 8. IPv6 | 地址表示、前缀、Link-Local、SLAAC、NDP、PMTUD、扩展头 | IPv6 双栈主机实验 | 能用 ip -6 neigh 和 ping6 完成发现 |
| 9. 综合排障 | traceroute、mtr、tcpdump、ss、ip route get | 一份「跨网段服务不通」定位报告 | 30 分钟内定位未知网络问题 |
阶段 9 真实场景:服务跨 VPC 调用慢,要能从
mtr跳点变化判断是「丢在运营商」还是「目标主机丢包」。
4. 第一周任务
| 日 | 任务 | 当天交付 |
|---|---|---|
| Day 1 | 用 ip -d link 看本机接口;ip addr 记录 IP/前缀;ping 127.0.0.1 与 ping <本机 IP> 区分环回与本机 | 一份接口清单 + ping 输出 |
| Day 2 | tcpdump -ni any -e -vv -X icmp 抓一次 ping;把 20 字节 payload 改成 200 字节再看报头 | 一份带字段标注的 hexdump |
| Day 3 | 手算 4 道子网(/24 /27 /30 /20),再用 ipcalc 或 python netaddr 验证 | 4 道手算 + 验证截图 |
| Day 4 | ip route 看本机路由表;ip route get 8.8.8.8 看实际命中;加一条 ip route add 实验 | 路由表 + 命中记录 |
| Day 5 | ping -M do -s 1472 <target> 测 MTU;故意挑过大值看 ICMP Fragmentation Needed | 一份 MTU 测试记录 |
| Day 6 | traceroute 到外网,看 TTL=1 起点;改 -I / -T / -U 对比不同探测方式 | traceroute 输出 + 协议对比 |
| Day 7 | 项目:抓一次完整对话:本机 ping 公网 IP,截取 echo request / echo reply / 中间 hop 的 ICMP Time Exceeded 各一份 | 抓包 pcap + 标注 |
Day 7 拆解
步骤 A —— 最小可用(60 分钟)
tcpdump -ni any -w /tmp/icmp.pcap icmp抓 30 秒;ping -c 3 1.1.1.1;- 用
tcpdump -r /tmp/icmp.pcap -vv列出请求和应答; - 把 echo request 的 IP 头字段逐一对照 RFC 791 §3.1 标注。
步骤 B —— 补齐边界(30 分钟)
- 同时跑
traceroute -n 1.1.1.1,抓 hop 2 处的 ICMP Time Exceeded; - 改用
traceroute -I 1.1.1.1抓 ICMP 探测包; - 故意把
pingTTL 设成 1(ping -t 1 1.1.1.1),验证看到 Time Exceeded; - 记录到
notes/week1-day7.md。
进阶:稳定通过后,再叠加 BPF 过滤
tcpdump 'icmp[icmptype] == 11',验证只看 Time Exceeded。
5. 阶段通用验收
- 不看 RFC 也能画出 IPv4 头 20 字节的字段分布;
- 用自己的话解释「为什么需要分片」「为什么 IPv6 不分片」;
- 画一张图:主机 A → 路由器 R1 → R2 → 主机 B 上每跳 IP 头变化(TTL、checksum、地址);
- 测试异常:TTL=0、DF 置位 + 大包、不可达目的地址、错误 checksum;
- 准备 3 组自定义数据并贴实际输出(不同 TTL、不同 MTU、不同路由);
- 记录每次抓包的 BPF 过滤器和命令;
- 能修改 BPF 抓到想要的报文,而不是只能照抄。
6. 最终验收
- 独立完成:手算 20 道 CIDR、抓一次跨网段 ping、定位一次「服务不通」故障;
- 至少完成 6 个实验(CIDR 算题、路由实验、MTU 实验、ICMP 类型识别、NAT 实验、IPv6 实验);
- 完成 1 个综合排障项目:模拟一个跨网段延迟升高 / 丢包场景,写定位报告;
- 能用 15 分钟讲清楚 IP 头字段、路由查询、ICMP 错误传递三者关系。
7. 综合项目
首选:跨网段服务延迟定位(必做:在两台 Linux 上用 network namespace 模拟 3 跳网络,故意在某跳注入丢包或延迟,用 mtr + tcpdump 定位)。
备选:
- 抓包分析 100 条 ICMP 报文并分类;
- 用
iptables模拟 SNAT/Hairpin NAT 并验证; - IPv4/IPv6 双栈对比 ping 行为差异。
综合项目必做要求:
- 场景描述:网络拓扑、预期行为、实际行为;
- 工具选择理由:为什么用
mtr而不是ping?为什么用tcpdump而不是wireshark命令行版本? - 核心分析:每一跳的现象、判断依据、根因定位;
- 复现脚本:可重复运行的
ip netns add/tc qdisc add/iptables命令; - 边界测试:换协议(UDP/TCP)、换方向、换 MTU 都验证过;
- 运行说明:环境依赖(
iproute2、iptables、traceroute、mtr、tcpdump)、复现步骤; - README:项目介绍、目录结构、复盘;
- 复盘记录:用时、难点、收获、下一步。
复盘项目交付物统一存到 notes/:
notes/design.md:拓扑、命令、定位逻辑;notes/test.md:每组数据输入、期望、实际;notes/retrospective.md:踩过的坑与改进点。
本主题贡献
本主题沉淀 IPv4/IPv6 报文、CIDR 子网、ICMP 错误传递、MTU/PMTUD 与 NAT/conntrack 五条主线能力,所有结论都要能在两台 Linux 上用 tcpdump -vv -X 重现。
职责(3 项)
- 解析 IPv4 头 14 个字段、IPv6 头固定 40 字节与扩展头链,能从 hex 标注 TTL、Protocol、Header Checksum、Hop Limit、Next Header;
- 在两 namespace + 两 veth 拓扑上用
tc qdisc add dev lo root netem loss 30%注入丢包与延迟,用mtr -r -c 30+tcpdump区分丢在运营商还是目标主机,能解释 PMTUD 与 DF 位的关系; - 配 SNAT/DNAT/Hairpin NAT、抓五元组变化、读
conntrack -L,能解释 NAT 为什么破坏端到端可达性,以及为什么 ICMP Fragmentation Needed 被防火墙误杀会引发 MTU 黑洞。
交付物(4 项)
- 一份带字段标注的 IPv4 报文 hexdump(
tcpdump -ni any -vv -X icmp),含 TTL、Protocol、Header Checksum 逐字节对照; - 20 道 CIDR 手算(覆盖
/20/27/30),用ipcalc/python netaddr校验并保留截图; - 跨网段延迟升高场景的
mtr报告 +tcpdump -w /tmp/p.pcap证据,能定位丢包 hop 与 ICMP Time Exceeded 出现位置; - IPv4/IPv6 双栈对比实验记录(
ip -6 neigh、ping6 fe80::1%eth0),含 NAT 转换前后五元组变化对照表。
指标(3 项)
- 跨网段问题定位 hop 数 ≤ 5(用
mtrLast/Avg/StDev 与抓包共同判定); - PMTUD 失败场景下 TCP fallback 到
clamp_mss的恢复时间 < 30 秒; - NAT 转换记录与 conntrack 表一致性检查通过率 100%(五元组 + 超时匹配)。
8. 推荐开源资料(按角色分工)
| 角色 | 资料 | 链接 | 用法 |
|---|---|---|---|
| RFC 原文 | RFC 791(IPv4) | https://www.rfc-editor.org/rfc/rfc791 | 字段定义原文 |
| RFC 原文 | RFC 8200(IPv6) | https://www.rfc-editor.org/rfc/rfc8200 | 报文与扩展头 |
| RFC 原文 | RFC 792(ICMPv4) | https://www.rfc-editor.org/rfc/rfc792 | ICMP 类型与代码 |
| RFC 原文 | RFC 4443(ICMPv6) | https://www.rfc-editor.org/rfc/rfc4443 | ICMPv6 必读 |
| RFC 原文 | RFC 4632(CIDR) | https://www.rfc-editor.org/rfc/rfc4632 | CIDR 与聚合 |
| 工具手册 | iproute2 文档 | https://wiki.linuxfoundation.org/networking/iproute2 | ip / tc / ss 用法 |
| 工具手册 | mtr 主页 | https://www.bitwizard.nl/mtr/ | mtr 参数与输出 |
| 工具手册 | tcpdump 手册页 | https://www.tcpdump.org/manpages/tcpdump.1.html | BPF 与输出格式 |
| 中文讲解 | 阿里云「网络层」文档 | https://help.aliyun.com/document_detail/25378.html | VPC / 路由表入门 |
| 实验环境 | vagrant + virtualbox 拓扑 | https://www.vagrantup.com/ | 多 VM 复现网络 |
| 抓包练习 | Wireshark 官方样例 pcap | https://wiki.wireshark.org/SampleCaptures | ICMP / TCP / ARP 真实报文 |
许可证提示:Wireshark 样例 pcap 是公开教学资源;iproute2 是 GPL-2.0。复制或参考命令前先确认许可证。
源码阅读时机:iproute2 源码放到「阶段 4(路由)」之后再读;RFC 原文从 Day 1 就开始对照,但不要试图一次通读所有 RFC——按当前阶段挑相关章节。
9. 学习资料汇聚(v0.3 自包含)
本节内容基于公开 RFC、Linux 手册与个人整理,标注「由本计划生成」处为计划自写。本节是子主题自包含的最后一节,不再依赖
notes/子目录。
9.1 背景与动机
- 1981 年 RFC 791 标准化 IPv4,1983 年 ARPANET 切到 TCP/IP,互联网从实验网络变成全球基础设施。
- 1990 年代 CIDR 取代有类编址,解决 IPv4 地址耗尽和路由表爆炸。
- 1996 年 RFC 2460 引入 IPv6,根本解法是扩大地址空间到 128 位。
- ICMP 看似「只是错误报告」,其实是网络层唯一的「信号通道」:traceroute、PMTUD、Redirect 都靠它。
- 一句话总结:Internet 是无连接的;可靠和顺序由上层(TCP)提供;这一层只负责「尽力而为」地把数据报送到下一跳。这一点很多人栽过——以为 IP 丢了会重传,其实不会。
9.2 概念地图
flowchart LR
App[应用层] --> Socket
Socket --> TCP[TCP/UDP]
TCP --> IP[IPv4/IPv6 报文]
IP --> ICMP[ICMP 控制]
IP --> Frag[分片/重组]
IP --> Route{路由查询}
Route -->|出接口| L2[链路层]
L2 -->|出网卡| Wire[物理层]
Wire --> Next[下一跳]
Next --> L2
IP --> NAT[NAT 转换]
IP --> PMTUD[PMTUD]
PMTUD --> ICMP
ICMP --> Traceroute[traceroute/mtr]
IP --> Addr[编址/CIDR]
IP --> Fwd[转发/最长前缀]
关系说明:
IP是中心节点,向上接传输层,向下交链路层;ICMP不携带业务数据,但承载traceroute、PMTUD、错误通知;NAT在出口路由器改写源/目的地址和端口,需要conntrack记录映射;PMTUD通过ICMP Fragmentation Needed(v4)或ICMPv6 Packet Too Big反馈;路由在主机和路由器都要查,用最长前缀匹配选路。
9.3 基础知识讲解
经典论文 / 经典书籍 / 优秀博客 / 核心人物 / 开发方法 五大类,每类 ≥3 条。
经典论文 / RFC(必读)
| 资料 | 角色 | 评分 | 链接 |
|---|---|---|---|
| RFC 791 — Internet Protocol | IPv4 协议原文 | 5 | https://www.rfc-editor.org/rfc/rfc791 |
| RFC 8200 — Internet Protocol, Version 6 | IPv6 协议原文 | 5 | https://www.rfc-editor.org/rfc/rfc8200 |
| RFC 792 — Internet Control Message Protocol | ICMPv4 类型/代码 | 5 | https://www.rfc-editor.org/rfc/rfc792 |
| RFC 4443 — ICMPv6 | ICMPv6 类型/代码 | 5 | https://www.rfc-editor.org/rfc/rfc4443 |
| RFC 4632 — Classless Inter-Domain Routing (CIDR) | CIDR 与聚合 | 4 | https://www.rfc-editor.org/rfc/rfc4632 |
| RFC 1191 — Path MTU Discovery | PMTUD 设计 | 4 | https://www.rfc-editor.org/rfc/rfc1191 |
经典书籍(系统化)
| 资料 | 角色 | 评分 | 链接 |
|---|---|---|---|
| 《TCP/IP 详解 卷 1:协议》(Richard Stevens) | 协议层最经典 | 5 | https://www.amazon.com/TCP-Illustrated-Volume-Protocols/dp/0321336313 |
| 《计算机网络:自顶向下方法》(Kurose & Ross) | 教学级系统讲解 | 4 | https://gaia.cs.umass.edu/kurose_ross/ |
| 《Linux 高性能服务器编程》(游双) | Linux 网络栈工程 | 4 | https://book.douban.com/subject/24722642/ |
| 《UNIX 网络编程 卷 1》(Stevens) | Socket 与协议实现 | 5 | https://www.unixnetworkprogramming.com/ |
| 《Computer Networking: A Top-Down Approach》(同上 Kurose 第 8 版) | 配套 PPT/视频 | 4 | https://gaia.cs.umass.edu/kurose_ross/ |
优秀博客(按问题查)
| 资料 | 角色 | 评分 | 链接 |
|---|---|---|---|
| Cloudflare Learning Center | 概念图解 + 实例 | 4 | https://www.cloudflare.com/learning/network-layer/what-is-the-network-layer/ |
| Julia Evans「Networking!」(zines) | 抓包与命令可视化 | 5 | https://jvns.ca/networking-zine.pdf |
| APNIC Blog | 运营商视角 + 排障 | 4 | https://blog.apnic.net/ |
| Marek Majkowski(Cloudflare) | TCP/IP 深入系列 | 4 | https://blog.cloudflare.com/tag/tcp/ |
| joyeu1234(CSDN「TCP/IP 协议栈」) | 中文步骤化讲解 | 3 | https://blog.csdn.net/joyeu1234/article/category/1924409 |
| 阿里云 VPC 文档 | 国内云网络实践 | 4 | https://web.archive.org/web/2024*/joyeu1234 |
核心人物(知道谁定的规范)
| 人物 | 贡献 | 关键出处 |
|---|---|---|
| Jon Postel | RFC 编辑、Internet 协议体系奠基人 | RFC 791/792/793 系列 |
| Vint Cerf | TCP/IP 共同设计者 | 与 Bob Kahn 合著 1974 论文 |
| Bob Kahn | TCP/IP 共同设计者 | 与 Vint Cerf 合著 1974 论文 |
| Steve Deering | IPv6 首席设计师 | RFC 2460/4291 |
| Christian Huitema | IPv6 部署与 NAT 穿越 | 《IPv6: The New Internet Protocol》 |
| Radia Perlman | Spanning Tree、路由协议 | 《Interconnections: Bridges, Routers, Switches》 |
| W. Richard Stevens | 《TCP/IP 详解》《UNIX 网络编程》 | 工程师人手一本 |
开发方法(动手习惯)
| 方法 | 适用 | 关键点 |
|---|---|---|
| 抓包驱动学习 | 任何协议学习 | 看到真实字节流比看图快 10 倍 |
| 双向对比(请求/应答) | 排障 | 把 request 与 reply 放一起对照字段变化 |
| 字段级标注 | 抓包复盘 | 用 tcpdump -vv -X 输出逐字段标注 |
| 最小复现 | 排障 | 缩到两台机器一个包,再扩到原场景 |
| BPF 过滤 | 抓包 | 写不准过滤器等于没抓;先 tcpdump -dd 验证表达式 |
ip route get 验证 | 路由 | 写完路由先用 get 验证再发包 |
缺失部分:
tcpdump的-dd输出语法、BPF 字面量在不同 libpcap 版本的差异。本计划不重写工具手册;查man pcap-filter即可。
9.4 经典问题与经典案例
| # | 问题 | 为什么会重要 | 最简答案 |
|---|---|---|---|
| 1 | TTL 超时包去哪了 | 路由环路诊断 | 每跳减 1,到 0 路由器回 ICMP Time Exceeded 给源 |
| 2 | MTU 黑洞 | 大包静默丢 | 路径某跳 MTU 较小,DF=1 时丢包且不发 ICMP |
| 3 | 分片重组失败 | 安全与性能双重问题 | 任一片丢失全包作废;现代网络建议 PMTUD |
| 4 | IP 头校验和不覆盖数据 | 排障时常被误用 | IPv4 头校验和只覆盖头;UDP 校验和可选,TCP 必选 |
| 5 | NAT 回流失败 | 内网服务从公网无法访问 | 需要 hairpin NAT 或拆分内外网 DNS |
| 6 | ICMP 被防火墙误杀 | ping 通但 TCP 不通 | 防火墙禁 ICMP 会让 PMTUD 失效 |
| 7 | IPv6 Link-Local 不可路由 | fe80::/10 只能在二层段内 | 用 ping6 fe80::1%eth0 指定 zone |
| 8 | IP 欺骗 | 安全审计基础 | 入口路由器做 uRPF / BCP38 过滤 |
| 9 | 路由黑洞 | 路由指向不存在的下一跳 | 用 ip route get 验证后再配置 |
| 10 | ECMP 不均衡 | 同目的多路径负载不均 | 多数实现按五元组 hash,会出现长连接独占 |
9.5 学习难点
概念难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| IPv4 头字段 | 20 字节 14 个字段,记不住 | 抓一个包对照 RFC 791 标一遍;用 Anki 卡片 |
| CIDR 与子网边界 | 前缀长度转十进制掩码不熟 | 每天 5 道手算 + ipcalc 验证 |
| 最长前缀匹配 | 路由表多条匹配不知道选谁 | 写出每条前缀的二进制前缀,找最长公共前缀 |
| ICMP 类型与代码 | 40+ 类型记不住 | 抓包时打印 icmptype 与 icmpcode 字段名对照 |
| IPv6 地址表示 | 缩写规则不熟 | 写一个 Python 展开/压缩函数来回切换 |
思维难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| hop-by-hop vs end-to-end | 分不清哪层改什么 | 画一张每跳字段变化表,标出 TTL、checksum、地址 |
| 无连接 vs 不可靠 | 误以为 IP 也有重传 | 写一段文字:IP 收到包只管「转交下一跳」 |
| NAT 与端到端 | 以为 NAT 透明 | 抓包看五元组变化;写 conntrack 表对照 |
| PMTUD 失败模式 | 防火墙拦 ICMP 导致 MTU 卡 576 | 改用 clamp_mss 的 TCP 兜底方案 |
工程难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
tcpdump BPF 写错 | 过滤器返回零结果 | tcpdump -d 编译查看;先抓全量再过滤 |
| 多接口选择 | -i any 混杂时序 | 改用具体接口 -i eth0 |
| 路由实验污染主机表 | ip route add 后忘记删 | 用 ip netns add 在命名空间内做实验 |
mtr 输出解读 | 不知道哪些跳算「丢包」 | 看 Last/Avg/StDev 三列,结合 30 秒以上采样 |
| IPv6 链路本地地址 | 不知道 %eth0 含义 | 把它理解成「作用域 ID」,跨链路要带 |
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 版本 | 发布组织 | 状态 | 许可证 / 可访问性 |
|---|---|---|---|---|
| IPv4 (RFC 791) | 1981 | IETF / IESG | 现行标准 | 免费公开 |
| IPv6 (RFC 8200) | 2017 | IETF / IESG | 现行标准 | 免费公开 |
| ICMPv4 (RFC 792) | 1981 | IETF / IESG | 现行标准 | 免费公开 |
| ICMPv6 (RFC 4443) | 2006 | IETF / IESG | 现行标准 | 免费公开 |
| CIDR (RFC 4632) | 2006 | IETF / IESG | 现行标准 | 免费公开 |
| iproute2 | 持续更新 | Linux 社区 | 事实标准 | GPL-2.0 |
| Linux kernel net stack | 持续更新 | Linux Foundation | 事实标准 | GPL-2.0 |
9.6.2 Scope
- IPv4/IPv6:定义无连接数据报格式、分片、转发机制;不保证可靠、不保证顺序;
- ICMP:承载错误报告与诊断(Echo、Time Exceeded、Destination Unreachable、Redirect、Packet Too Big);
- CIDR:替代有类编址,提供任意长度前缀与路由聚合;
- 路由:在主机与路由器上用最长前缀匹配选路;
- iproute2 / Linux kernel:事实上的实现与工具。
不适用:实时多媒体(用 UDP/RTP)、可靠字节流(用 TCP)、应用语义(用 HTTP/gRPC)。与传输层关系:IP 提供「从源主机到目的主机」能力,TCP/UDP 在此之上提供「端到端进程间」能力。
9.6.3 Structure
IPv4 头(20 字节,必会字段):
| 偏移 | 字段 | 长度 | 说明 |
|---|---|---|---|
| 0 | Version + IHL | 1 字节 | Version=4;IHL=5(无选项) |
| 1 | DSCP + ECN | 1 字节 | QoS 与显式拥塞通知 |
| 2-3 | Total Length | 2 字节 | 含头,单位字节 |
| 4-5 | Identification | 2 字节 | 分片重组用 |
| 6-7 | Flags + Fragment Offset | 2 字节 | DF / MF 位 |
| 8 | TTL | 1 字节 | 每跳减 1 |
| 9 | Protocol | 1 字节 | 1=ICMP, 6=TCP, 17=UDP |
| 10-11 | Header Checksum | 2 字节 | 只覆盖头 |
| 12-15 | Source IP | 4 字节 | |
| 16-19 | Destination IP | 4 字节 |
IPv6 头(40 字节固定,扩展头链式):
| 偏移 | 字段 | 长度 |
|---|---|---|
| 0-3 | Version + Traffic Class + Flow Label | 4 字节 |
| 4-5 | Payload Length | 2 字节 |
| 6 | Next Header | 1 字节 |
| 7 | Hop Limit | 1 字节 |
| 8-23 | Source Address | 16 字节 |
| 24-39 | Destination Address | 16 字节 |
ICMPv4 常见类型:
| Type | 名称 | 用途 |
|---|---|---|
| 0 / 8 | Echo Reply / Request | ping |
| 3 | Destination Unreachable | code 0=net, 1=host, 3=port, 4=need frag |
| 5 | Redirect | 路由优化(已基本弃用) |
| 11 | Time Exceeded | TTL=0(traceroute 关键) |
| 12 | Parameter Problem | 头字段错误 |
9.6.4 Ecosystem
- 内核实现:Linux kernel 的
net/ipv4/与net/ipv6/; - 用户态工具:
iproute2(ip、tc、ss)、net-tools(ifconfig、netstat,已不推荐)、iptables/nftables(NAT / 防火墙)、tcpdump/wireshark(抓包)、mtr/traceroute(路径探测); - 事实标准 vs 标准本身:
ping多数实现走 ICMP,少数(Windows)允许 TCP/UDP;traceroute默认 UDP 高端口,Linux-I走 ICMP,-T走 TCP SYN;- PMTUD 在 ECMP + 防火墙场景常失败,工程上 fallback 到「clamp MSS」。
9.6.5 Depth Tiers
| 层级 | 名称 | 必须看到什么 |
|---|---|---|
| L0 | 知道存在 | 知道 IP/ICMP/CIDR 是网络层;知道 IPv4 / IPv6 两个版本 |
| L1 | 看得懂示例 | 看到 ping / traceroute 输出能猜出哪个字段 |
| L2 | 能正确调用 | 能写 ip route / ip addr / tcpdump 完成日常操作 |
| L3 | 能解释与排错 | 能解释 MTU 黑洞、TTL 超时、NAT 回流失败的根因 |
| L4 | 能设计与扩展 | 能设计 PMTUD 失败的兜底方案、写 conntrack 规则 |
本计划目标:阶段 9 综合排障时达到 L3。
9.6.6 Source
- RFC Editor:所有 IPv4/IPv6/ICMP 原文(
https://www.rfc-editor.org/); - IANA Protocol Numbers:协议号与端口号权威分配(
https://www.iana.org/assignments/protocol-numbers/); - iproute2 官方文档(
https://wiki.linuxfoundation.org/networking/iproute2); - Linux
man 7 ip/man 8 tcpdump/man 8 iptables; - 引用版本快照日期:2026-07-30。
10. 常见误区
- 把 IP 当成「可靠传输」:IP 不重传、不保序、不保证到达;
- 抓包不指定接口:用
-i any在多网卡主机上时间戳会乱; - 改路由不验证:
ip route add后没ip route get验证,发包还是走老路; - 误以为 ping 通就服务通:ICMP 防火墙策略常常与 TCP 不同步;
- 抓 ICMP 看到 Time Exceeded 就当故障:traceroute 故意制造的 TTL=1 也会触发;
- IPv6 Link-Local 不写 zone:
ping6 fe80::1在多接口主机上会报connect: Invalid argument; - PMTUD 失败就调大 MTU:MTU 黑洞是路径问题,不是主机问题,应该
tracepath; - 用
ifconfig配路由:现代发行版推荐iproute2,ifconfig输出格式与新内核能力已不匹配; - 改
/etc/sysctl.conf不sysctl -p:编辑完没生效; - 抓到分片就以为有 bug:很多大文件传输、P2P 协议正常分片;
- 把 ICMP Destination Unreachable code 3 当成「主机挂」:可能是 MTU 通告,路径上抓到要对端抓包对照;
- 只看
tcpdump第一行摘要:丢包排障一定要-vv看 TTL、ID、flags。
11. 所有知识点分类(统一规则)
按本仓库统一分类规则(与父主题一致):
- 编程语言
- 数据结构与算法
- 计算机基础:网络协议、操作系统、组成原理
- 工程技术
- Web 与后端
- 前端与客户端
- 数据与人工智能
- 项目与职业能力
本计划归属:计算机基础 主 + 工程技术 辅。