位偏移 | 0-3 | 4-7 | 8-13 | 14-15 | 16-18 | 19-31 | |
---|---|---|---|---|---|---|---|
0 | 版本 (Version) | 报头长度 (IHL) | 区分服务 (DS) | 总长度 (Total Length) | |||
32 | 标识符 (Identification) | 标志 (Flags) | 分片偏移 (Fragment Offset) | ||||
64 | 生存时间 (TTL) | 协议 (Protocol) | 报头校验和 (Header Checksum) | ||||
96 | 源IP地址 (Source IP address) | ||||||
128 | 目标IP地址 (Destination IP address) | ||||||
160 | 选项 (Options)(可选) |
版本(Version)- 4bits
用于标识IP协议的版本。对于IPv4,该字段固定为值 4。
报头长度(Internet Header Length, IHL)- 4bits
IPv4报头的长度 ,字段的单位是32位,即4字节。
该字段最小值为5,即报头长度为字节,最大值为15,即报头长度为为字节,即IPv4报头包含20字节报头和40字节选项字段。
区分服务(Differentiated Services, DS)- 8bits
最初被定义为服务类型(Type of Service, TOS),现在已经被重新定义为区分服务(RFC2474),包含两部分:
(a) 区分服务质量(Differentiated Services Code Point, DSCP)- 6bits
DSCP占据DS字段的最高6位。DSCP用于DiffServ架构中,对网络流量进行分类和标记 。通过为不同类型的流量(如实时语音、视频或尽力服务)分配不同的DSCP值,网络中的路由器能够识别流量类型,并根据预设的服务级别协议(SLA)应用相应的优先级、排队和丢弃策略 。例如,Expedited Forwarding(加急转发)PHB(Per-Hop Behavior)就是通过特定的DSCP标记来实现低延迟的传输服务 。
(b) 显示拥塞通知(Explicit Congestion Notification, ECN)- 2bits
ECN占据DS字段的最低2位 。ECN是一种拥塞控制机制,旨在让路由器在网络即将发生拥塞时,通过标记数据包而非直接丢弃数据包的方式,显式地通知端。ECN的运作需要端到端支持,并在传输层(如TCP)进行协商 。这2位编码了四种状态:
ECN Code Point (Bits 6-7) | 简称 | 含义 |
---|---|---|
00 | Not-ECT (NCE) | 不支持ECN的传输(未启用) |
01 | ECT(1) | ECN能力传输 (1) |
10 | ECT(0) | ECN能力传输 (0) |
11 | CE | 拥塞已发生 (Congestion Experienced) |
当支持ECN的发送方将数据包标记为ECT(0)或ECT(1)时,如果中间路由器检测到拥塞,路由器会将该数据包的ECN字段标记为CE 。接收方收到CE标记的数据包后,通过传输层协议(例如,TCP头部中的ECE位)将拥塞信息“回显”给发送方 。发送方收到回显后,会主动降低其传输速率(通过设置TCP头部中的CWR位),从而缓解网络拥塞,避免了因丢包而导致的延迟和重传 。
总长度(Total Length)- 16bits
整个 IP 数据报的总长度(报头 + 数据),单位为字节。最大值 = 65535,即单个 IPv4 报文最大 64KB,但是实际数据报大小通常受到底层链路层MTU(最大传输单元)的限制。
IP规定所有主机必须支持最低576字节的报文(数据512字节,最长IP报文头60字节,余量4字节),当下层数据连输协议的MTU字段小于IP报文长度时,报文需要被分片。
标识符(Identification)- 16bits
用于唯一标识原始数据报。当数据报被分段后,所有片段都共享相同的标识符。目的主机使用此标识符来准确地将属于同一原始数据报的碎片进行分组,以便后续的重组操作。
标志位(Flags)- 3bits
用于控制分片行为的标志位
- bit0:保留,必须为 0
- bit1:DF (Don't Fragment), 0表示允许分片,1 表示禁止分片。
- bit2: MF (More Fragments) ,0表示这是最后一个分片,1 表示后面还有分片。
分段偏移 (Fragment Offset) - 13bits
用于指示当前分段的数据在原始数据报数据载荷中的起始位置,以 8 字节(64位) 为单位计算的。例如,如果偏移量为185,则表示该分段的数据起始于原始数据报的 字节处 。目的主机正是依赖该字段和MF标志,来确保所有分段被正确地按序拼接,从而重构原始数据报。
生存时间(Time To Live, TTL)- 8 bits
是一个8位计数器,用于限制IP数据报在网络中的最大生存周期或最大跳数(Hop Limit)。其核心作用是防止数据包因路由配置错误或路由循环而永远在网络中循环,从而耗尽网络资源 。TTL的初始值由源主机设置(最大为255)。每当数据报经过一个路由器(即一跳),路由器必须将TTL值至少减 1 。当路由器接收到一个TTL值为 1 的数据包,在转发前将其减为 0 时,路由器会丢弃该数据包。随后,该路由器可能会向源主机发送一个ICMP “Time Exceeded”(时间超出)错误消息,通知源主机该数据包已在传输中超时。在IPv6中,该字段被重命名为“Hop Limit”。
协议(Protocol)- 8bits
标识了紧随IP报头之后的数据载荷部分所承载的上层协议 。目的主机依靠此协议编号来确定将数据报载荷交给哪个传输层或应用层协议处理,常见协议如下:
协议编号 (Protocol Number) | 协议缩写 (Abbreviation) | 协议名称 (Protocol Name) |
---|---|---|
1 | ICMP | Internet Control Message Protocol |
2 | IGMP | Internet Group Management Protocol |
6 | TCP | Transmission Control Protocol |
17 | UDP | User Datagram Protocol |
报头校验和(Header Checksum)- 16bits
只覆盖 IPv4 头,不含数据部分,每跳路由器都会重新计算(因为 TTL 会变化),IPv4报头校验和采用16位一的补码求和算法 。
- 发送方计算: 将报头数据(校验和字段暂时置零)按照16位字访问。对所有这些16位字进行一的补码求和(即在求和过程中将溢出位加回最低位,直到结果保持在16位以内)。最后,将该和值取一的补码(即所有位取反),结果即为校验和,填入报头 。
- 接收方验证: 接收方对整个接收到的报头(包括已填入的校验和)执行相同的16位一的补码求和 。如果最终求和结果为0xFFFF,则表明报头在传输过程中未发生错误,因为原始校验和的设计确保了校验和与其所保护数据的和值在取反后正好抵消 。
uint16_t HeaderChecksum(const uint8_t *data, uint16_t length)
{
uint32_t sum = 0;
for(uint16_t i=0; i < length; i += 2) {
uint16_t word;
if(i + 1 < length) {
word = (data[i] << 8) | data[i + 1];
} else {
word = (data[i] << 8);
}
sum += word;
if(sum > 0xFFFF) {
sum = (sum & 0xFFFF) + 1;
}
}
if(sum > 0xFFFF) {
sum = (sum & 0xFFFF) + 1;
}
return ~(uint16_t)sum;
}
源IP地址(Source IP address)- 32bits
数据报发送方的32位IPv4地址。
目的IP地址(Destination IP address)- 32bits
数据接收方的32位IPv4地址。
选项字段(Options)- 0~40Bytes
是IPv4报头的可变部分。只有当IHL值大于5(即报头长度超过20字节)时,该字段才会存在。选项的最大长度为40字节,加上20字节固定报头,最大报头长度为60字节。选项通常采用TLV(Type-Length-Value,类型-长度-值)格式。
(a) 常见选项字段类型
选项名称 | 选项类型编号 | 格式 | 作用 | 典型场景 |
---|---|---|---|---|
记录路由 (Record Route, RR) | 7 | TLV | 要求数据报在经过的每个路由器上记录其 IP 地址。 | 网络调试、路径发现、验证数据包路径。 |
时间戳 (Timestamp, TS) | 4 | TLV | 要求沿途路由器记录数据包到达的时间戳,可用于测量网络延迟。 | 延迟分析和网络性能故障排除。 |
宽松源路由 (Loose Source Route, LSR) | 3 | TLV | 允许发送方指定数据包必须经过的一系列中间路由器,但数据包可以在指定的路由器之间自由选择路径。 | 路由控制、故障诊断(但现代网络中极少使用)。 |
严格源路由 (Strict Source Route, SSR) | 9 | TLV | 要求发送方指定数据包必须严格按照顺序经过的每个路由器,不能在指定路由器之间自由跳跃。 | 严格的路径控制或安全测试(极少使用)。 |
无操作 (No Operation, NOP) | 1 | 仅 Type | 占位符,用于将后续选项对齐到 32 位(4 字节)边界。 | 选项之间的填充和对齐。 |
选项列表结束 (End of Option List, EOL) | 0 | 仅 Type | 标记 IP 选项列表的结束。 | 选项区域末尾的标志,尤其在选项长度未达到 32 位边界时。 |
(b) 填充字节
由于IHL字段要求报头长度必须是32位(4字节)的整数倍 ,如果选项字段的总长度不是4字节的倍数,则必须添加填充字节(Padding),通常值为 0,以确保整个报头对齐32位边界 。
(c) 局限
尽管选项字段提供了强大的调试和控制功能,但在现代互联网中,它们的应用已大幅减少或被禁用 。主要原因包括:
- 性能降级(慢路径): 现代路由器使用专用的硬件(ASIC)进行快速转发(快速路径)。处理包含选项的 IPv4 数据包需要更复杂的软件操作,会强制数据包转移到处理速度慢得多的主 CPU 上进行处理(慢路径) 。
- 安全风险: 诸如源路由等选项可能被攻击者滥用,用于网络探测、绕过安全控制(例如防火墙的源地址过滤),甚至进行拒绝服务(DoS)攻击,因为慢路径会消耗路由器的关键控制平面资源 。因此,IETF 建议默认禁用 IP 源路由功能 。