IPv4 报文、编址与子网划分
内容摘要:网络层(02)用 IP 地址实现端到端寻址与跨网段转发。本章讲清 IPv4 报文字段、CIDR 无类编址、如何做子网划分、路由查找的最长前缀匹配规则,以及一批必须记住的特殊地址。子网计算是网络工程的「乘法口诀」,本章给出可复现的验证方法而非死记。
难度:中级 | 前置知识:03 进制与位运算、06 ARP/NDP | 所属层次:网络层(L3)
一、IPv4 报文结构
IPv4(RFC 791) 头部至少 20 字节。理解字段才能读懂抓包、解释分片(09)与 QoS(QoS 与高可用)。
| 字段 | 位宽 | 取值示例 | 语义 | 接收方处理 | 抓包显示 | 常见异常 |
|---|---|---|---|---|---|---|
| 版本 | 4 | 4 | IP 版本 | 判断 v4/v6 | Version | — |
| 头长(IHL) | 4 | 5(=20B) | 头部长度(4 字节为单位) | 定界头/载荷 | Header Length | 含选项时>5 |
| DSCP+ECN | 8 | 0 | 服务等级 + 显式拥塞通知 | QoS 调度(QoS 与高可用) | DSCP/ECN | ECN 被清零 |
| 总长度 | 16 | 1500 | 整个 IP 包字节数 | 定界 | Total Length | 最大 65535 |
| 标识 | 16 | 递增值 | 分片重组标识 | 同一包分片共享 | Identification | 复用冲突 |
| 标志 | 3 | DF/MF | DF=不分片、MF=还有分片 | 决定能否分片 | Flags | DF 置位 + 超 MTU → 丢弃(09) |
| 分片偏移 | 13 | 0/185 | 本片在原包的位置(8 字节为单位) | 重组 | Fragment offset | 重叠分片攻击 |
| 生存时间(TTL) | 8 | 64/128 | 每跳减 1,到 0 丢弃并回 ICMP | 减 1 转发 | TTL | 过小导致中途丢弃(traceroute 原理,09) |
| 协议 | 8 | 6=TCP、17=UDP、1=ICMP | 上层协议(解复用键,02) | 交上层 | Protocol | — |
| 头校验和 | 16 | — | 仅校验头部(03) | 校验失败丢弃 | Header checksum | 卸载导致本机假错 |
| 源/目的 IP | 各 32 | 192.0.2.2 | 端到端地址 | 路由/交付 | Src/Dst | 源地址伪造(网络安全) |
关键认知:TTL 不是「时间」而是「跳数」。 每经过一个路由器减 1,到 0 就丢弃并回送 ICMP「超时」——这正是
traceroute的工作原理(09)。初始 TTL 因 OS 而异(Linux/macOS 常 64,Windows 常 128),可据此粗略推断对端系统与经过跳数。
二、IP 地址与 CIDR 无类编址
IPv4 地址是 32 位,点分十进制表示(如 192.0.2.130),逻辑上分为网络部分 + 主机部分。
- 早期有类编址(classful) 按首字节固定划分 A/B/C 类,浪费严重,已废弃。
- 无类域间路由(Classless Inter-Domain Routing,CIDR,RFC 4632) 用前缀长度灵活表示网络位数:
192.0.2.0/24表示前 24 位是网络、后 8 位是主机。
子网掩码(subnet mask) 就是「网络位全 1、主机位全 0」的 32 位数。用按位与(AND)(03)即可求网络地址:
192.0.2.130 = 11000000.00000000.00000010.10000010
& 255.255.255.192(/26) = 11111111.11111111.11111111.11000000
= 192.0.2.128 ← 网络地址(该地址属于 192.0.2.128/26)三、子网划分:概念与验证
子网划分(subnetting) 是把一个大网络切成多个小网络——借用主机位当子网位。给定 /24(256 地址)想切成 4 个子网,就借 2 位(2²=4)变成 4 个 /26。
| 子网(/26) | 网络地址 | 可用主机范围 | 广播地址 | 可用主机数 |
|---|---|---|---|---|
| 1 | 192.0.2.0 | 192.0.2.1–192.0.2.62 | 192.0.2.63 | 62 |
| 2 | 192.0.2.64 | 192.0.2.65–192.0.2.126 | 192.0.2.127 | 62 |
| 3 | 192.0.2.128 | 192.0.2.129–192.0.2.190 | 192.0.2.191 | 62 |
| 4 | 192.0.2.192 | 192.0.2.193–192.0.2.254 | 192.0.2.255 | 62 |
关键规则(务必记牢):
- 每个子网首地址 = 网络地址(主机位全 0),不可分配给主机。
- 每个子网末地址 = 广播地址(主机位全 1),不可分配给主机。
- 可用主机数 = 2^(主机位) − 2(减去网络与广播地址)。
/26→2⁶−2 = 62。 /31(RFC 3021) 是点到点链路的特例,只有 2 个地址且都可用(无广播概念)。/32表示单个主机(常见于回环、环回路由、K8s Pod,Kubernetes 网络)。
本库方法论:不要死记子网表,用工具验证。 下面用 Python 标准库
ipaddress复现上表,避免手算出错。
本机实测验证(macOS,python3,2026-09-07)
python3 - <<'PY'
import ipaddress
n = ipaddress.ip_network("192.0.2.0/26", strict=False)
print("network:", n.network_address, "broadcast:", n.broadcast_address)
print("netmask:", n.netmask, "num_addr:", n.num_addresses)
print("first host:", list(n.hosts())[0], "last host:", list(n.hosts())[-1])
ip = ipaddress.ip_address("192.0.2.130")
for pfx in ["192.0.2.0/26","192.0.2.64/26","192.0.2.128/26","192.0.2.192/26"]:
if ip in ipaddress.ip_network(pfx):
print(f"{ip} in {pfx}")
PY真实输出:
network: 192.0.2.0 broadcast: 192.0.2.63
netmask: 255.255.255.192 hostmask: 0.0.0.63 num_addr: 64
first host: 192.0.2.1 last host: 192.0.2.62
192.0.2.130 in 192.0.2.128/26解读:
192.0.2.0/26有 64 个地址、62 个可用主机、广播地址192.0.2.63——与上表第 1 行完全一致;而192.0.2.130落在第 3 个子网192.0.2.128/26,印证第二节的 AND 运算。这就是可复现验证优于死记的价值。
四、最长前缀匹配(路由查找的核心规则)
一个目的 IP 可能同时匹配路由表里多条路由(如 0.0.0.0/0 默认路由和 192.0.2.0/24)。路由器选择**前缀最长(最具体)**的那条——最长前缀匹配(Longest Prefix Match,LPM)。
本机实测:查看路由表(macOS,2026-09-07)
# macOS
netstat -rn -f inet | head
# Linux 更直观(推荐)
ip route show
ip route get 192.0.2.130 # 直接显示对某目的的实际选路结果真实输出(节选,网关地址已按规范脱敏为文档地址):
Destination Gateway Flags Netif
default 192.0.2.1 UGScg en0 ← 0.0.0.0/0 兜底
10.1.5.1 192.0.2.1 UGHS en0 ← /32 主机路由(更具体优先)解读:
default是/0兜底,10.1.5.1(此处脱敏)是一条/32主机路由——当目的正好是它时,/32前缀最长胜出。Linux 的ip route get <目的>能直接告诉你「这个包实际会走哪条路由、下一跳是谁」,是排障利器(分层故障排查)。
五、特殊地址(必须记住)
以下地址有特殊语义,不能当普通主机地址随意使用(RFC 6890 汇总,RFC 1918/5737 等定义具体块):
| 地址块 | 名称 | 用途 | 能否路由到公网 |
|---|---|---|---|
0.0.0.0/8 | 本网络 | 「本机/未指定」,0.0.0.0 表示「所有本地地址」 | 否 |
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 | 私有地址(RFC 1918) | 内网,需 NAT 才能上公网(19) | 否(需 NAT) |
100.64.0.0/10 | 运营商级 NAT(CGNAT,RFC 6598) | 运营商内部共享地址 | 否 |
127.0.0.0/8 | 环回(loopback) | 本机自身,127.0.0.1=localhost | 否 |
169.254.0.0/16 | 链路本地(APIPA) | DHCP 失败时自动配置 | 否 |
192.0.2.0/24、198.51.100.0/24、203.0.113.0/24 | 文档地址(RFC 5737) | 文档/示例专用(本库统一使用) | 否 |
224.0.0.0/4 | 组播(multicast) | 一对多(10) | 特殊 |
255.255.255.255 | 受限广播 | 本网段广播 | 否 |
本库红线:示例地址优先用 RFC 5737 文档地址与
.example域名(RFC 2606);不得写入真实生产 IP、客户域名。私有地址(RFC 1918)用于实验拓扑(20)。
六、最小可复现实验
1、实验目标
- 用工具验证子网归属、网络/广播地址、可用主机数。
- 观察路由查找(LPM)的实际结果。
2、平台与工具
- 本机验证环境:macOS 26.6.2,
python3、netstat。Linux 用ipcalc/ip route(见注释)。
3、执行命令(本机可跑)
# 子网速算与归属判定(本机可跑,见第三节真实输出)
python3 -c "import ipaddress as i; n=i.ip_network('198.51.100.0/28'); print(n.network_address, n.broadcast_address, n.num_addresses-2, '可用')"
# Linux: ip route get 直接看 LPM 结果(本环境无 ip 命令)
# ip route get 192.0.2.130预期:198.51.100.0 198.51.100.15 14 可用(/28 = 16 地址、14 可用)。
4、子网连通实验(需 Linux,本环境未执行)
在 20 统一实验拓扑 中,client(192.0.2.2/24)与 server(198.51.100.2/24)属不同子网,必须经 router 转发,直接验证「跨子网需路由」:
# [未在本环境执行] Linux;见 30 章
ip netns exec cli ip route get 198.51.100.2 # 预期 via 192.0.2.1 (网关),因不同子网
ip netns exec cli ping -c 3 198.51.100.2 # 经 router 转发5、结论边界与清理
- 子网计算为确定性数学,工具输出可复现;路由表为单机快照。只读命令无需清理。
七、错误示例与常见误区
| 误区 | 纠正 |
|---|---|
| 「网络地址/广播地址能分给主机」 | 不能;可用主机 = 2^主机位 − 2。 |
| 「/24 一定是 C 类」 | 有类编址已废弃;CIDR 下前缀长度任意。 |
| 「192.168.x.x 能直接上公网」 | 私有地址需 NAT(19)。 |
| 「路由表有默认路由就够了」 | 更具体路由(LPM)会优先,需理解匹配顺序。 |
| 「TTL 是时间」 | 是跳数计数器,每跳减 1。 |
| 「IP 头校验和保护整个包」 | 只保护头部(03)。 |
八、性能影响
- 子网规模与广播域:子网过大 → 广播域过大 → ARP/广播开销上升(05、06)。
- 路由表规模与 LPM:互联网核心路由表数十万条,LPM 查找依赖硬件(TCAM)加速(10)。
- 地址规划影响可汇总性:良好的层次化地址规划能让路由汇总(summarization),减小路由表(10)。
九、安全风险与加固
- 源地址伪造(IP spoofing):伪造源 IP 发起攻击或反射放大(网络安全)。加固:入口过滤(BCP 38 / uRPF)——丢弃源地址不该出现在该接口的包。
- 地址扫描与信息泄露:可预测的地址规划便于攻击者扫描;结合分段与最小暴露(网络安全)。
- 私有地址泄露:内部私有地址出现在公网报文/日志中可能泄露拓扑,需脱敏(本库规范)。
十、版本与平台差异
- IPv4=RFC 791、CIDR=RFC 4632、私有地址=RFC 1918、特殊地址汇总=RFC 6890。
- 工具:Linux
ip route/ip route get(推荐)、ipcalc;macOS/Windowsnetstat -rn/route print。ip route get的「直接显示选路」在 macOS 无对应。
十一、常见问题与排查方向
- 「同网段互通、跨网段不通」:查子网掩码是否一致、网关是否正确、router 是否开启转发(20)。
- 「掩码配错导致间歇不通」:两端掩码不一致会让一方误判「同网段」而不走网关,用
ip route get确认选路。 - 「拿到 169.254.x.x」:DHCP 失败的链路本地地址,查 DHCP(19)。
十二、清理与恢复
- 只读命令无副作用;实验中新增的地址/路由用
ip addr del/ip route del清理(见 20)。
十三、关联章节
检索关键词
IPv4 报文头字段 TTL 跳数 CIDR 无类编址 子网掩码 AND 运算 子网划分 网络地址 广播地址 可用主机数 2^n-2 最长前缀匹配 LPM 默认路由 0.0.0.0/0 RFC 1918 私有地址 RFC 5737 文档地址 ip route get IP spoofing BCP38
权威来源
- RFC 791(IPv4)、RFC 4632(CIDR)、RFC 1918(私有地址)、RFC 3021(/31 链路)
- RFC 5737(文档地址)、RFC 6598(CGNAT)、RFC 6890(特殊用途地址汇总)
- IANA IPv4 Special-Purpose Address Registry
- Python
ipaddress模块文档、Linuxip-route(8)man page
报文字段与地址语义以上述 RFC/IANA 为准,
verified_at: 2026-09-07;子网计算与路由表输出为 macOS 26.6.2 本机真实执行,网关地址已按脱敏规范替换为文档地址。跨子网连通实验未在本环境执行(macOS 无 netns/ip)。
