《TCP/IP 详解 卷1:协议》第 5 章:Internet 协议
IP 是 TCPIP 协议族中的核心协议。所有 TCP、UDP、ICMP、IGMP 数据都通过 IP 数据包(又称为 packet)来传输。IP 的英文名为 Internet Protocol,是互联网协议族中用于跨越网络边界中继数据报的主要通信协议,主要提供主机寻址、数据报路由操作。它的路由功能可以实现互联,从本质上建立互联网(网络的网络)。
-
IP 是一种尽力而为(best-effort delivery service)的数据交付。尽力而为的含义是不保证IP数据包能够成功地到达目的地。有能力的时候,我会帮你转发。IP 不是简单的丢弃所有不必要流量,但是在某些错误发生时,例如一台路由器的缓冲区用尽,IP的简单错误处理方法就是丢弃一些数据。任何更高级的可靠性(重传,拥塞控制)都必须由高层的传输层来提供,例如 TCP
-
IP 是无连接(connection-less)的。无连接意味着IP不维护网原单元中数据包任何相关的链接状态信息每个数据包独立于其他数据包来处理。这意味着IP数据包可以不按顺序交付。如果一个主机向同一个目的地先后发送 A 和 B 两个数据包。那么每个数据包可以独立路由通过不同的路径,并且 B 可能在 A 之前到达。传输层协议,通常是 TCP ,需要处理这些潜在的问题,以便为应用提供无差错的交付。
IPv4 头部字段
字段 | 长度(bits) | 内容 | 含义 or 注释 |
---|---|---|---|
版本(version) | 4 | 4 | 指明 IP 数据包的版本号 |
头部长度(IHL) | 4 | 5 | 以 32 bits 为单位的字,IPv4 packet header 的长度。正常为 5(20个字节) |
区分服务(DS) | 6 | 见下文 | 为 IP 网络提供 QoS 服务,典型例子为 voIP(voice over IP) |
显示拥塞控制(ECN) | 2 | 见下文 | IP 协议的扩展,使得内置 ECN 功能的端点间通讯时拥有拥塞控制机制 |
总长度(Total Length) | 16 | 以字节为单位,整个 IP 数据报的长度 | 通过总长度字段和 IHL 字段,可以知道数据(又称有效载荷)从哪里开始 |
标识(Identification) | 16 | 每个主机都有一个内部计数器,发送数据报时都将计数器自增 1 然后复制到标识字段 | 避免一个分片和其他分片混淆,对于实现分片很重要 |
标志(Flags) | 3 | 见下文 | 见下文 |
分片偏移(Fragment Offset) | 13 | 以 8 字节为单位,特定分片相对于原始未分片IP数据报开始的偏移量 | 用于组合分片 |
TTL(time-to-live) | 8 | 发送方将其初始化为某个值(例如 64),每经过一次路由器的转发 TTL 自减 1,到达 0 时被丢弃 | 防止数据报因为意外路由环路而长久停留在网络中 |
协议(Protocol) | 8 | 典型的例如 17(UDP)、6(TCP) | 表示数据报有效载荷部分的协议类型 |
头部检验和(Header Checksum) | 16 | 略 | 仅计算 IP header,意味着有效载荷数据部分的正确性需要其他协议来提供完整性验证机制 |
源IP地址(Source IP Address) | 32 | 略 | 略 |
目的IP地址(Destination IP Address) | 32 | 略 | 基本的 IPv4 header 到此为止,共 20 bytes |
IP 选项(Option) | 可变长度,最长 320 bits / 40 bytes | 见下文 | 见下文 |
IP 数据(IP Data) | 可变长度,最长为 65515 bytes | 略 | 又叫有效载荷(payload) |
DS 和 ECN 是通过标记 IP 数据报,使它们的转发不同于其它数据报。(可能跟 ISP 收取不同的特殊费用有关)
- DS 中字段称为区分服务代码点(Differentiated Services Code Point (DSCP)),是 IP 上用于支持 QoS 的服务。
- ECN 是指显示拥塞控制 Explicit Congestion Notification。具有 ECN 功能的路由器在拥塞时,转发 packet 时会设置 ECN 位,被目的节点接受时,有些协议(例如 TCP)会发现这种标记,然后通知发送方降低发送速率来缓解拥塞。
关于分片相关的 Flag,是一个 3 bits 字段,内容如下:
- bit 0: 不使用,填 0
- bit 1: Don't Fragment (DF),不对此 datagram 分片。此位被设置时,当某个 datagram 经过路由器时若需要分片,则会被丢弃。将数据包发送给没有足够资源来处理碎片的主机时,可以使用此功能。还可以用于路径 MTU 发现。
- bit 2: More Fragments (MF),对于除了最后一片以外的分片,都设置了 MF 来表明“后面仍有其他分片”,方便拼接。最后一个分片 MF = 0 且 Fragmentation Offset 字段不为零,这样就将其与未分片的数据包区分开来。
关于 IP checksum,参见 here
IP 选项
IP 选项(Option)字段是一些可选参数通常用来配置一些行为,例如在路由期间使用的方法、一些探测、控制,早期对于 IP 进行的一些实验也是通过 IP 选项来完成的。在早期,处于 IPv4 设计阶段的 Internet 规模较小,来自恶意用户的威胁也比较少。随着时间的推移,所涉及相关的安全问题使得很多选项变得不再使用。许多路由器把某些 IP 选项认为是恶意或危险的,会被边界路由器或防火墙所拦截。多数标准化的选项在现如今的 Internet中很少使用。
IPv6 头部字段
字段 | 长度(bits) | 内容 | 含义 or 注释 |
---|---|---|---|
版本(version) | 4 | 6 | 指明 IP 数据包的版本号 |
区分服务(DS) | 6 | 同 IPv4 | 略 |
显示拥塞控制(ECN) | 2 | 同 IPv4 | 略 |
流标签(Flow Label) | 20 | 未有详细定义 | 可用来标记特定流的报文,以便在网络层区分不同的报文。流标签在IPv6报文头中携带,转发路由器可以不必根据报文内容来识别不同的流,因此使用IPSec后仍然可以根据流标签进行QoS处理。 |
负载长度(Payload Length) | 16 | 整个 IPv6 数据报减去头部后的字节数 | 略 |
下一个头部(Next Header) | 8 | 见下文 | 见下文 |
跳数限制(Hop Limit) | 8 | 同 IPv4 的 Time-to-live | 略 |
源IP地址(Source IP Address) | 128 | 略 | 略 |
目的IP地址(Destination IP Address) | 128 | 略 | 基本的 IPv6 header 到此为止,共 40 bytes |
IPv6 选项及扩展头部
可以发现,IPv6 的头部字段相对于 IPv4 较为简易。许多 IPv4 中利用特定字段来实现的功能,例如分片,很少在 IPv6 中使用,因此没有在 IPv6 中分配相应的位。基于这种情况,IPv6 有一个固定的 40 字节头部在开头,而仅在需要时使用扩展头部。相对于 IPv4,IPv6 提供了一种更灵活和可扩展的方式,将选项和扩展头部相结合。在 IPv6 头部之后增加下一个扩展头部实现。IPv6 的设计者简化了高性能路由器的设计,因为 IPv6 的路由器处理分组所需要的命令比 IPv4 简单。
下一个头部(Next Header)字段告诉接收方如何解释头部之后的数据。最后一个 Next Header 内容是携带有效载荷的上层协议信息,之后就是有效载荷。IPv6 使用许多下一个字段形成一个链。IPv6 头部(header)仅出现在数据报的开头。
分片
相关知识点:MTU
如果 IP 需要发送一个数据报,大小大于链路层 MTU,则 IP 通过分片将数据报分解成较小的部分,使每个分片都小于 MTU。
IPv4
下图是 IPv4 分片的示例图(来自 wiki):
IPv6
IPv6 routers do not perform IP fragmentation. IPv6 hosts are required to either perform path MTU discovery, perform end-to-end fragmentation, or to send packets no larger than the default Maximum transmission unit (MTU), which is 1280 octets.
IPv6 路由器不执行 IP 分片。 要求IPv6主机执行路径MTU发现,执行端到端分片,或发送不大于默认最大传输单元(MTU)的数据包。IPv6 的数据只在源端分片,目的端重组,中间路由器收到超过它 MTU 的数据会发送 ICMPv6 告诉源主机它的 MTU 大小,并把数据抛弃。
下图是 IPv6 分片的示例图:
IPv6 中有用于指示分片功能的下一个头部。所包含的信息与 IPv4 header 中三个跟分片有关的字段(identification、flag、offset)功能相同,只不过位数略有不同。在下面这个例子中较大的数据包被分为三个小的分片。
- 每个分片有一个 IPv6 头部。
- 负载长度字段被修改,反应新生成的分片的大小。
- 分片头部的标识符,用于指示是同一个数据报。确保网络中不同时原始数据报的生存期内不会被分配相同的标识符字段。
- 由于偏移量字段是以 8 bytes 为单位的,因此分片需要在满足条件的边界处进行。除了最后一个分片以外,所有的分片都是 8 bytes 的倍数。
- 接收方对分片进行重组(reassembly)。之前必须确保已接受所有数据包的原始分片。按照顺序重组成一个完整数据报,以便交给高层的其他协议处理。
IP 转发
数据报的路由(Routing)是IP层的一个主要功能。
从概念上来说IP转发是很简单的,如果目的地是直接相连的主机,例如点到点链接,或例如以太网这样的共享网络,IP 数据报将直接发送至目的地,而不需要使用路由器(直接交付)。否则主机将数据报发送到一台路由器,将由该路由器将数据报发送至目的地。这个简单方案,适用于大多数的主机配置。
路由器
Router,重要的网络层设备。目前语境下的大多数主机可配置为主机,也可配置为路由器。
主机与路由器的最大区别在于处理 IP 数据报时,主机不转发那些不是由它生成的路由器数据包,但是路由器会这样做。
转发表
当一个网络接口接收到一个数据包的时候,IP 模块首先检查目的ip地址
是否为自己的 IP 地址。如果是的话数据将直接交付给 IPv4 头部的协议字段或 IPv6 头部的下一个头部指定的协议模块(即上交至对应协议栈)。如果数据包的目的地不是本地 IP 模块使用的 IP 地址,那么
- 如果 IP 层配置为一台路由器,则根据路由表(routing table)来转发该数据报。
- 如果 IP 层配置是主机,那么数据包会被默默地丢弃。除了一些特殊情况,比如 ICMP 消息可能就会发送一些额外的信息回源节点。
转发表中的内容没有被协议标准规定的很精确,这些工作留给 IP 协议的实现者。通常转发表需要包含下列关键信息
- 目的地
- 掩码(用于进行最匹配前缀运算,见 IP地址)
- 下一跳
- 下一跳网络接口(以太网、wifi、DSL 等)
IP 转发行动
简单来说 IP 转发的过程如下:
- 主机在自己的转发表中查找“最匹配的前缀”。若找不到匹配前缀,则使用默认路由(default route),一般默认路由能够指出适合的下一跳网关地址。通过 ARP(IPv6 则是了邻居发现)向网关发送这个数据包。
- 网关接收到这个数据包之后检查自己的转发路由表,同样选择一个最合适的前缀,获得下一跳地址并将数据报发送出去。
- 若接收到数据报的是一个未在目的地子网的路由器,则路由器会仿照上诉步骤,进行相似的路由转发。
- 若数据报达到目标子网,则会进行直接交付(即下一跳内容是主机的网络接口,没有再涉及路由器)
通常路由器不会直接将数据报发送至目的地,而是将其发送至一个更接近目的地的下一跳路由器。这是IP层的一个常见思路——“逐跳进行”。
- 没有任何一个路由器或主机包含任何目的地的完整转发路径。转发机制只提供数据报发送的下一跳的地址。
- 假设每一个下一跳都能够“更接近目的地”。
- TTL 字段用来限制数据包不会在网络中循环。
- 路由协议(routing Protocol)用于保证路由表的正确,例如 RIP、OSPF、BGP 等。不在此讨论。
下面给出直接交付和简介交付的例子:
关于掩码、最长前缀匹配的知识,参见 here
something else
packet 是网络层的 PDU(协议数据单元),数据包
datagram 数据报,用于形容网络层的传输数据,一个 datagram 可以被分到一个或多个 packets,在数据链路层中传输。而且也有说法说 datagram 形容起始点和目的地都使用无连接网络服务的的网络层的信息单元,例如 UDP 协议中也称传输单元是 datagram。