《TCP/IP 详解 卷1:协议》第5章:Internet协议
IPv4和IPv6头部
IP是TCP/IP协议族中的核心协议。所有TCP、UDP、ICMP和IGMP 数据都通过IP数据报传输。IP提供了一种尽力而为、无连接的数据报交付服务。
IP头部字段
IPv4 头部通常为 20 字节(无选项时),而 IPv6 头部固定为 40 字节。IPv6 不支持传统的头部“选项”,但支持扩展头部。
所有二进制整数在网络中采用 高位优先(网络字节序),即先传输高位字节。
字段 | IPv4 中的表现 | IPv6 中的表现 |
---|---|---|
版本 | 4 | 6 |
头部长度 | 可变,最小20字节,最大60字节 | 固定40字节 |
服务类型 | DS/ECN | DS/ECN |
总长度 | 包含头部与数据长度 | Payload Length(不含头部) |
标识与分片 | 支持分片 | 通过扩展头部处理 |
TTL | 每跳递减 | 同功能,字段名为 Hop Limit |
协议/下一个头部 | Protocol 字段 | Next Header 字段 |
校验和 | 头部校验和 | 无 |
源/目的地址 | 32 位 | 128 位 |
版本字段(Version)
- 占 4 位。
- 指示 IP 数据报的协议版本。
- IPv4 的值为
4
- IPv6 的值为
6
- IPv4 的值为
- IPv4 与 IPv6 除了这个字段位置相同外,其它头部结构完全不同,不能直接互通。
- 同时支持 IPv4 与 IPv6 的主机称为“双栈主机”。
Internet 头部长度(IHL)
- 占 4 位。
- 表示 IPv4 头部长度,以 32 位字为单位。
- 最小值为 5(即 20 字节),最大值为 15(即 60 字节)。
- IPv4 可通过选项扩展头部长度;IPv6 头部固定为 40 字节,扩展使用扩展头部完成。
服务类型字段(ToS)/ 通信类型字段(Traffic Class)
- 原为服务类型字段(ToS),后由多份 RFC(如 RFC 2474, RFC 3168, RFC 3260)重新定义。
- 现在该 8 位字段分为:
- 前6位:DS 字段(Differentiated Services Field)
- 后2位:ECN 字段(Explicit Congestion Notification)
- 支持服务质量 (QoS) 和网络拥塞控制。
- 该字段在 IPv4 和 IPv6 中都存在,作用一致。
总长度字段(Total Length)
- 占 16 位。
- 指定整个 IPv4 数据报的长度(头部 + 数据),单位为字节。
- 最大值为
65535
字节。 - IPv6 采用
Payload Length
字段表示负载长度,不包括头部长度。
有些链路层协议(如以太网)不提供精确的负载大小信息,因此 IP 必须显式提供总长度。实际中很少发送超过 MTU 的 IP 报文,若超过,需要分片。
标识字段(Identification)
- 占 16 位。
- 主要用于分片场景。
- 每个由主机发出的数据报通常会自增标识号,以便分片后可正确重组。
标志(Flags)与分片偏移量(Fragment Offset)
- 三位标志位,用于控制分片行为。
- 13 位分片偏移量,指示该分片在原始数据报中的位置。
生存时间字段(TTL)
- 占 8 位。
- 表示该数据报最多可经过多少个路由器。
- 每经过一个路由器,TTL 减 1,减至 0 时数据报将被丢弃。
- 防止数据报在网络中无限循环。
协议字段(Protocol)
- 占 8 位。
- 指示封装在 IP 数据报内的协议类型。
- 常见值:
6
:TCP17
:UDP1
:ICMP4
:IPv4-in-IPv4 封装
- IPv6 中该字段对应为“下一头部字段(Next Header)”。
头部校验和(Header Checksum)
- 占 16 位。
- 仅覆盖 IPv4 头部本身,不包括数据部分。
- 每次 TTL 变化或头部变更都需重新计算。
- IPv6 移除了该字段,理由:
- 上层协议都有自己的校验机制(如 TCP/UDP 校验和)
- 减少中间节点处理负担,提高效率
- 实际错误率已因物理层质量提高而大大降低
源 IP 地址 与 目的 IP 地址
- IPv4 地址为 32 位,IPv6 为 128 位。
- 通常标识一个网络接口(主机的网络卡)。
- IPv4 的地址空间约为
2^32 ≈ 42 亿
个地址,已远远不能满足全球需求。 - IPv6 地址空间为
2^128 ≈ 3.4 × 10^38
个地址,几乎无限。
校验和
Internet校验和 是一种用于检测数据报在传输过程中是否发生错误的机制。当发现一个头部出错(计算的校验和不为0)时,IPv4实现将丢弃接收到的数据报。但是,不会生成差错信息。更高层以某种方式检测丢失的数据报,并在必要时重新传输。
计算过程:
- 校验和字段先置为 0。
- 将整个 IP 头部视为一个由多个 16位(2字节)单元组成的序列。
- 将这些 16 位值使用 二进制反码加法 相加(详见下文)。
- 将最终结果取 反码(按位取反),存入校验和字段中。
反码加法(ones’ complement addition):当两个 16 位整数相加产生进位时,该进位会“循环”加回结果的最低位。
DS字段和ECN
- 区分服务字段(DS,Differentiated Services Field):前 6 位
- 显式拥塞通知字段(ECN,Explicit Congestion Notification):后 2 位
DS 字段(Differentiated Services,6 位)
DS 字段由 RFC 2474 定义,用于提供一种可扩展的方式,以实现不同类型的数据服务,支持流量分类与服务质量(QoS)控制等功能。
DS 字段的实际名称是 DSCP(Differentiated Services Code Point),它是 6 位的编码字段。
常见的 DSCP 值包括:
000000
:表示默认(Best Effort)服务,也就是标准默认传输方式,不提供任何特殊服务。101110
:表示加速转发(Expedited Forwarding, EF),通常用于对延迟敏感的流量,如 VoIP,提供更快的转发路径。001010
、010010
等:这些是保证转发(Assured Forwarding, AF)类的编码,用于对数据流进行分类调度,以实现可靠性保证。
这些值通常由边缘路由器设置,并作为数据报文通过网络传播时的分类依据,影响队列调度和带宽分配等行为。
ECN 字段(Explicit Congestion Notification,2 位)
ECN 字段由 RFC 3168 定义,它允许网络中的路由器在发生拥塞时通过标记,而不是直接丢弃数据包,向通信双方显式通知网络拥塞情况。
启用 ECN 功能的前提是:发送方、接收方以及路径中的路由器都必须支持 ECN。
ECN 字段包含两位,其取值含义如下:
00
:表示该数据报 不使用 ECN 功能,即传统的基于丢包的拥塞控制。01
:表示 ECN 能力启用,ECT(1)(ECN-Capable Transport, 1),由发送方设置。10
:表示 ECN 能力启用,ECT(0)(ECN-Capable Transport, 0),也是由发送方设置。11
:表示遇到拥塞(Congestion Encountered, CE),由中间路由器设置。
ECN 的使用过程如下:
- 发送方在发送数据报时,将 ECN 字段设置为
10
(ECT(0))或01
(ECT(1)),表示它支持 ECN。 - 如果数据报在中间某个支持 ECN 的路由器处遇到拥塞,路由器会将 ECN 字段的值更改为
11
(CE),而不是丢弃该数据报。 - 接收方检测到数据报的 ECN 字段为 CE 后,会在 TCP ACK 报文中将此信息反馈给发送方。
- 发送方根据拥塞通知反馈,降低其发送速率或采取其他拥塞控制策略,以避免网络进一步恶化。
IP选项
IPv4 支持在其头部中添加一系列“选项”,这些选项最初由 [RFC 791] 定义。设计这些选项的初衷是在一个较小、可信任的网络中支持调试、控制、安全等特殊功能。然而,随着互联网规模的不断扩大以及安全问题的暴露,IP 选项在现代网络中使用越来越少,很多也已被废弃或仅用于实验用途。
IPv6 不再在主头部中携带选项,而是引入了**扩展头部(Extension Headers)**的概念。所有可选信息都被组织为独立的头部,紧随主头部之后。这种设计更灵活,也便于路由器跳过不关心的头部类型。
IPv6扩展头部
IPv6 基本头部固定为 40 字节,不包含任何可选字段。所有附加功能(如路由选择、分片、认证、安全、选项等)都通过一个或多个扩展头部来实现。
扩展头部仅在需要时才添加,从而避免了每个数据包都必须处理冗余信息。
IPv6 数据包的头部结构是链式结构,从基本头部开始,每个头部通过一个字段指向下一个头部类型。
IPv6选项
IPv6 的扩展头部中可以携带“选项”,这些选项通常用于控制、诊断、安全或特定的协议扩展功能。IPv6 选项主要出现在 Hop-by-Hop 头部 或 Destination Options 头部 中,每个选项都由以下字段组成:
Option Type
(1 字节):标识选项类型。Opt Data Len
(1 字节):选项数据长度。Option Data
:具体的数据内容。
填充1(Pad1)与填充N(PadN)
用于确保选项头的对齐(通常按 8 字节对齐)或填充末尾空余字节。
- Pad1:1 字节的填充选项,仅包含一个字节的
Option Type
,值为0x00
,不带长度字段。 - PadN:多字节填充,用于填充任意长度,
Option Type
为0x01
,后跟一个Opt Data Len
字段和 N 字节的填充值(一般为0)。
这两个选项在格式对齐或调试阶段非常常见,不承载实际数据。
IPv6 超大有效载荷(Jumbo Payload)
定义在 [RFC 2675] 中,用于支持超过 65,535 字节的数据报。
- 使用一个名为 Jumbo Payload 的选项,其
Option Type
为0xC2
。 - 该选项包含一个 4 字节字段,指定实际的数据长度(最大可达 4,294,967,295 字节)。
- 仅当基本 IPv6 头部的 Payload Length 字段为 0 时,才使用该选项。
- 此选项只能出现在 Hop-by-Hop 头部 中。
该机制通常用于高性能网络环境,且必须由通信双方和中间设备共同支持。
隧道封装限制(Tunnel Encapsulation Limit)
定义在 [RFC 2473] 中,用于控制一个 IPv6 数据包最多可以被封装的次数。
Option Type
:0x04
Option Data
:1 字节,表示还允许封装的剩余次数。- 每当一个 IPv6 隧道对数据包封装一次,该值减 1;若为 0,则不再封装并丢弃分组。
该选项帮助避免隧道嵌套造成的死循环和性能下降问题。
路由器警告(Router Alert)
定义在 [RFC 2711] 中,用于告知中间路由器:该数据包需要特殊处理(如 RSVP 或 IGMP)。
Option Type
:0x05
Option Data
:2 字节的值,表示警告类型:0
表示需要对 IGMP 进行处理1
表示 RSVP2
表示 AN
该选项只能出现在 Hop-by-Hop 头部中,是极少数必须由路由器处理的 IPv6 选项之一。
快速启动(Quick-Start)
定义在 [RFC 4782] 中,是一个实验性机制,用于让主机在连接建立初期快速发送更多数据。
- 使用 Quick-Start 选项携带请求码,请求更高的初始发送速率。
- 路由器在支持的前提下,根据自身情况返回批准速率。
- 可提升 TCP 连接建立时的效率,尤其在高带宽链路中更明显。
由于复杂性和安全性问题,该机制目前使用较少,仍处于试验阶段。
CALIPSO(通用标签)
定义在 [RFC 5570] 中,用于为 IPv6 数据包打上安全标签。
- 全称为 Common Architecture Label IPv6 Security Option
- 适用于多级安全环境,尤其是军事或政府网络。
- 携带安全类别、安全策略等元信息,便于路由器或终端进行访问控制。
该选项需结合特定的安全策略体系(如 Bell-LaPadula)才能发挥作用。
家乡地址(Home Address)
定义在移动 IPv6([RFC 6275])中,用于在数据报中标识移动主机的原始地址。
- 移动节点将其当前的“临时地址”作为 IPv6 源地址,并通过该选项携带其“家乡地址”。
- 通信对端可据此识别真正身份,便于透明通信与安全控制。
- 常出现在 Destination Options 头部 中,仅由通信对端处理。
该机制是移动 IPv6 实现移动性支持的核心组成部分。
分片头部
IPv6 中的分片机制与 IPv4 有显著区别:不再由中间路由器进行分片,而是完全交由源节点处理。这种设计简化了中间路由器的实现,提升了网络转发效率,同时也提高了对网络路径中 MTU 限制的依赖。
- 不可分片部分:包括 IPv6 基本头部及所有必须由中间节点处理的扩展头部(如逐跳选项头部)。
- 可分片部分:包含其余部分,例如目的地选项头部、上层协议头(如 TCP/UDP)以及数据负载。
- 原始数据报分为多个分片,每个分片都携带一份完整的“不可分片部分”和一个独立的分片头部。
- IPv6 头部中的 Payload Length 字段也会在每个分片中被调整,反映当前分片的实际长度(包括分片头和数据)。
- 所有分片的 Identification 字段值相同,表明它们属于同一原始数据报。
- 所有分片的偏移值需为 8 字节对齐,所以分片大小(不含头部)一般为 8 的倍数。
- 最后一个分片的 M 位为 0,其余为 1。
IP转发
从概念上讲,IP 转发机制非常简单:
- 如果目的地址是本地网络中的主机(如同一以太网或点到点链路),则直接发送;
- 否则,发送到一个默认网关(默认路由器),由其进行进一步的转发;
- 若无路由信息可用,则数据报将被丢弃,有时会返回一个 ICMP 错误消息。
转发表
IP 通过**查阅转发表(或称路由表)**来决定数据报的转发路径。虽然 IP 协议标准没有强制指定转发表的格式,但它一般包含以下关键信息:
字段 | 含义 |
---|---|
目的地(Destination) | IPv4(32位)或 IPv6(128位)地址。可以是单个主机、子网或默认(0.0.0.0/0)路由 |
掩码(Mask) | 与数据报目的地址按位与后进行匹配。用于区分网络前缀 |
下一跳(Next Hop) | 表示下一跳的 IP 地址,数据报将被发送到此地址 |
接口(Interface) | 用于发送数据报的物理或逻辑接口,如 eth0、wlan0、ppp0 等 |
IP转发行为
当一台主机或路由器中的 IP 层需要向下一跳发送一个数据报时,它会根据数据报的目的 IP 地址,在转发表中查找最匹配的下一跳信息。该过程基于 最长前缀匹配(Longest Prefix Match, LPM) 算法进行。
-
掩码匹配
遍历转发表中的每条记录
eᵢ
,判断其是否与目标地址D
匹配:(D & mᵢ) == dᵢ
mᵢ
:转发表第 i 条目的掩码字段;dᵢ
:转发表第 i 条目的目的地字段;&
:按位与操作。
- 选择最佳匹配
在所有满足匹配条件的条目中,选择掩码中 1 的数量最多 的条目(即前缀最长的匹配项)。
例如,两个匹配项的前缀分别为
/24
和/16
,则/24
更优。
- 获取下一跳地址
从最佳匹配项中提取下一跳字段 n
,作为数据报转发的目标地址。
如果没有任何条目匹配目标地址:
- 主机上:返回“主机不可达”错误给源应用;
- 路由器上:发送 ICMP“目的不可达”消息给源主机。
在某些情况下,多个条目可能具有相同的最长前缀长度(例如多个默认路由),此时标准协议没有规定具体行为:
-
通常操作系统实现:
-
选择第一条匹配项;
-
负载均衡(如 ECMP);
-
基于路径性能(如带宽、延迟等);
例子
IP 数据报的交付方式主要分为两类:
- 直接交付:源主机和目的主机在同一网络内;
- 间接交付:需要通过一个或多个路由器转发。
直接交付
在直接交付中,源主机和目的主机处于 同一个网络(如同一子网或广播域),数据报可以直接送达。
示例环境:
- 主机 S(Windows XP):IP 地址
10.0.0.100
,MAC 地址为MAC_S
- 主机 D(Linux):IP 地址
10.0.0.9
,MAC 地址为MAC_D
- 它们通过一个交换机连接,处于相同的子网
10.0.0.0/25
主机 S 的转发表如下:
目的地 | 掩码 | 下一跳(网关) | 接口 |
---|---|---|---|
0.0.0.0 | 0.0.0.0 | 10.0.0.1 | 10.0.0.100 |
10.0.0.0 | 255.255.255.128 | 10.0.0.100 | 10.0.0.100 |
- 对于目的地址
10.0.0.9
,两个条目都匹配,但/25
掩码更长,因此选择第二条。 - 网关字段与本机 IP 相同(
10.0.0.100
),意味着数据报将被 直接交付。
交付过程:
- 如果不知道 D 的 MAC 地址,使用 ARP 请求获取;
- 数据报被封装进以太网帧;
- 帧的目的地址是 D 的 MAC 地址;
- 数据通过交换机转发,交付给主机 D。
间接交付
在间接交付中,源主机和目的主机处于不同网络之间,必须通过路由器转发。
示例环境:
- 源主机 S:IP 地址
10.0.0.100
,默认网关为10.0.0.1
(R1 的 a 接口) - 目标主机:
ftp.uu.net
,IP 地址192.48.96.9
- 需要经过多个路由器转发(例如 R1 → R2 → R3 → R4)
主机 S 的处理步骤:
- 查找转发表;
- 找不到特定匹配条目,匹配到默认路由;
- 默认路由指定下一跳为
10.0.0.1
(R1); - 使用 ARP 获取 R1 的 MAC 地址;
- 构造以太网帧,帧的目的地址是 R1 的 MAC;
- 交付数据报给 R1。
注意:在间接交付中,IP 层目的地址始终不变,但低层帧的目的地址是“下一跳”的地址,而不是最终目的主机地址。
IPv6 中的对应处理
- IPv6 使用 邻居请求消息(Neighbor Solicitation) 来解析下一跳的 MAC 地址;
- 引入 链路本地地址(fe80::/10) 与 全球地址 区分使用;
- 对于链路本地地址,可能需要用户指定使用哪个接口;
- 转发表逻辑基本相同,只是地址长度更长,协议细节略有不同。
移动IP
移动IP基于一台主机拥有一个“家乡”网络,但可以不时地访问其他网络的想法。当主机离开家乡时,它保持平时在家乡使用的IP地址,但采用一些特殊的路由和转发手段,使主机可以在这个网络中与其他系统通信,就好像它仍连接在自己的家乡网络中那样。该方案依赖于一种特殊类型的路由器,它被称为“家乡代理”,用于为移动节点提供路由。
基本模型:双向隧道
移动IP允许一台主机在改变网络位置的同时保持其IP地址不变,从而维持上层协议(如TCP)连接的连续性。这种能力对于移动设备(如笔记本电脑、手机等)尤其重要。
在移动IP中,移动节点(MN)拥有一个在家乡网络上的家乡地址(HoA)。当它连接到另一个网络(称为外地网络)时,它会获取一个新的IP地址,称为转交地址(CoA)。
移动IP的核心机制是家乡代理(HA),这是一种特殊类型的路由器,部署在MN的家乡网络中。当CN(通信节点)向MN发送数据时,数据首先到达HA,然后由HA通过隧道机制将数据转发给MN当前的CoA。
这种机制被称为双向隧道,原因如下:
- 从CN到MN:CN → HA → MN(隧道转发)
- 从MN到CN:MN → HA → CN(隧道转发)
MN绑定:MN的HoA与其当前CoA之间的映射关系,称为绑定。HA负责维护这个绑定,并确保CN发来的数据被正确转发。
路由优化
双向隧道虽然简单,但存在效率问题,特别是MN与CN物理距离较近,但都需通过远距离的HA转发时,路径明显绕远。为了解决这个问题,MIPv6引入了路由优化(RO)。
-
绑定更新(BU, Binding Update)
MN向CN发送一个包含自己HoA和当前CoA的消息,称为绑定更新请求。CN收到并验证后,建立绑定关系。 -
返回路由程序(RRP, Return Routability Procedure)
为确保MN身份的真实性(防止伪造绑定),引入了RRP机制。其基本过程如下:- MN向CN发送两个探测请求:一个从HoA出发(通过HA中转),另一个从CoA直接发送。
- CN收到两个探测请求后,分别回复两个探测应答。
- MN接收到两个应答后,生成绑定更新请求,并发送给CN。
- CN通过比对两个应答,确认HoA和CoA属于同一个实体,从而建立信任并更新绑定缓存。
- 数据传输阶段
一旦绑定建立成功,CN后续的数据报就可以直接发送给MN的CoA,不再需要经过HA中转,从而实现了更高效的传输路径。
IPv6要求IPsec支持,但在RO中,MN与CN之间通常不使用IPsec,因为不可靠或配置复杂。
RRP虽然没有IPsec强大,但更简单,且足够满足大多数移动通信场景的安全需求。
IP数据包的主机处理
虽然路由器在转发数据报时通常不需要关心数据报的源地址或目的地址选择,但对主机来说,选择正确的源地址、判断接收哪些目的地址以及如何在多接口环境中进行处理,是IP协议栈中的核心任务。
此外,当主机收到发往自身的IP数据报时,是否接受它,也取决于系统采用的主机模式。
主机模式
主机模式定义了在多接口设备上,主机是否接收那些发送到未直连接口地址的IP数据报。这一处理方式由 [RFC 1122] 规范,并分为两种模式:
强主机模式(Strong Host Model)
在强主机模式下,主机只接受发送到该数据包到达接口上配置的IP地址的数据包。也就是说,目的地址必须与数据包所到达接口的本地地址匹配,系统才处理该数据报。
- 优点:安全性高,避免接口混淆或IP欺骗攻击。
- 缺点:在多宿主(multi-homed)场景中可能丢弃有效数据包。
弱主机模式(Weak Host Model)
在弱主机模式下,主机接收所有目的地址匹配任意接口地址的数据报,无论这些数据包通过哪个接口接收。
- 优点:灵活,适用于负载均衡、多路径传输、多宿主主机等场景。
- 缺点:可能被攻击者利用进行IP地址欺骗攻击。
示例说明
假设主机 A 配置有两个接口:
- 接口 eth0:IP 地址为
203.0.113.1
- 接口 eth1:IP 地址为
192.0.2.1
主机 B 向 192.0.2.1
发送一个数据报,通过其 Internet 路由(而不是本地连接)发送。
- 如果主机 A 采用强主机模式,由于数据包没有从 eth1 接收,即使目标地址为
192.0.2.1
,也会被丢弃。 - 如果主机 A 采用弱主机模式,则会正常接收并处理这个数据包。
地址选择
当一台主机发送 IP 数据报时,需要为其选择合适的 源地址 和 目的地址。这通常由地址选择程序根据策略规则自动完成。
随着 IPv6 的推广、一个接口可绑定多个地址,以及双栈主机的出现,地址选择变得复杂,错误的选择可能导致非对称路由、分组丢弃等问题。
为此,RFC 3484 制定了地址选择规则,并使用策略表控制选择过程。
地址选择核心思想
- 每台主机维护一个策略表(最长匹配前缀查找表),根据地址的前缀、标签和优先级决定使用哪对源/目的地址。
- 源地址选择算法会为一个目的地址选择最合适的本地地址。
- 目的地址选择算法会为一个本地源地址选择最合适的目的地址。
源地址选择算法
给定目的地址 D,从本地地址集合中选择一个最合适的源地址 A,按以下规则依次比较:
- 优先选择与目的地址相同的地址
- 优先选择范围更接近目的地址的地址
- 避免使用过期地址
- 优先选择家乡地址而非转交地址
- 优先选择与目的接口一致的地址
- 优先标签匹配的地址
- 优先非临时地址
- 优先前缀匹配更长的地址
目的地址选择算法
从多个可用的目的地址中为某个源地址选择最佳目的地址:
- 避免不可用的目的地(不可达或无源地址可用)
- 优先与源地址作用范围匹配的地址
- 避免使用源地址为过期地址的目的地址
- 优先选择配对源地址是家乡地址的目的地址
- 优先标签匹配的目的地址
- 优先更高优先级的目的地址
- 优先不经封装传输的目的地址
- 优先较小作用范围的地址
- 优先前缀匹配更长的地址对