ip协议

IP 报文协议

首部协议格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0               1               2               3               4
0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| LHL | Type of Service | Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification(fragment Id) |Flags| Fragment Offset |
| 16 bits |R|D|M| 13 bits |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time-To-Live | Protocol | Header Checksum |
| ttl(8 bits) | 8 bits | 16 bits |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP Address (32 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Ip Address (32 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (*** bits) | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| transport data... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

版本(Version):

1
版本字段占 4bit,通信双方使用的版本必须一致。对于 IPv4,字段的值是 4。

首部长度(Internet Header Length, IHL):

1
2
3
占 4bit,首部长度说明首部有多少 32 位字(4字节)。
由于 IPv4首部可能包含数目不定的选项,这个字段也用来确定数据的偏移量。
这个字段的最小值是 5(二进制 0101),相当于 5*4=20 字节(RFC 791),最大十进制值是 15。

区分服务(Differentiated Services,DS):

1
2
占 8bit,最初被定义为服务类型字段,实际上并未使用,但 1998 年被 IETF 重定义为区分服务 RFC 2474。
只有在使用区分服务时,这个字段才起作用,在一般的情况 下都不使用这个字段。例如需要实时数据流的技术会应用这个字段,一个例子是 VoIP。

显式拥塞通告( Explicit Congestion Notification,ECN):

1
2
在 RFC 3168 中定义,允许在不丢弃报文的同时通知对方网络拥塞的发生。
ECN 是一种可选的功能,仅当两端都支持并希望使用,且底层网络支持时才被使用。

全长(Total Length):

1
2
3
4
5
这个 16 位字段定义了报文总长,包含首部和数据,单位为字节。
这个字段的最小值是 20(20 字节首部+0 字节数据),最大值是 216-1=65,535。
IP 规定所有主机都必须支持最小 576 字节的报文,这是假定上层数据长度 512 字节,加上最长 IP 首部 60 字节,加上 4 字节富裕量,
得出 576 字节,但大多数现代主机支持更大的报文。
当下层的数据链路协议的最大传输单元(MTU)字段的值小于 IP 报文长度时间,报文就必须被分片,详细见下个标题。

标识符(Identification):

1
2
占 16 位,这个字段主要被用来唯一地标识一个报文的所有分片,因为分片不一定按序到达,所以在重组时需要知道分片所属的报文。
每产生一个数据报,计数器加 1,并赋值给此字段。一些实验性的工作建议将此字段用于其它目的,例如增加报文跟踪信息以协助探测伪造的源地址。

标志 (Flags):

1
2
3
4
5
6
7
这个 3 位字段用于控制和识别分片,它们是:
位 0:保留,必须为 0;
位 1:禁止分片(Don’t Fragment,DF),当 DF=0 时才允许分片;
位 2:更多分片(More Fragment,MF),MF=1 代表后面还有分片,MF=0 代表已经是最后一个分片。
如果 DF 标志被设置为 1,但路由要求必须分片报文,此报文会被丢弃。这个标志可被用于发往没有能力组装分片的主机。
当一个报文被分片,除了最后一片外的所有分片都设置 MF 为 1。
最后一个片段具有非零片段偏移字段,将其与未分片数据包区分开,未分片的偏移字段为 0。

分片偏移 (Fragment Offset):

1
这个 13 位字段指明了每个分片相对于原始报文开头的偏移量,以 8 字节作单位。

存活时间(Time To Live,TTL):

1
2
3
4
这个 8 位字段避免报文在互联网中永远存在(例如陷入路由环路)。
存活时间以秒为单位,但小于一秒的时间均向上取整到一秒。
在现实中,这实际上成了一个跳数计数器:报文经过的每个路由器都将此字段减 1,当此字段等于 0 时,报文不再向下一跳传送并被丢弃,最大值是 255。
常规地,一份 ICMP 报文被发回报文发送端说明其发送的报文已被丢弃。这也是 traceroute 的核心原理。

协议 (Protocol):

1
占 8bit,这个字段定义了该报文数据区使用的协议。IANA 维护着一份协议列表(最初由 RFC 790 定义),详细参见 IP 协议号列表。

首部检验和 (Header Checksum):

1
2
3
4
这个 16 位检验和字段只对首部查错,不包括数据部分。
在每一跳,路由器都要重新计算出的首部检验和并与此字段进行比对,如果不一致,此报文将会被丢弃。
重新计算的必要性是因为每一跳的一些首部字段(如 TTL、Flag、Offset 等)都有可能发生变化,不检查数据部分是为了减少工作量。
数据区的错误留待上层协议处理——用户数据报协议(UDP)和传输控制协议(TCP)都有检验和字段。此处的检验计算方法不使用 CRC。

源地址

1
2
3
一个 IPv4 地址由四个字节共 32 位构成,此字段的值是将每个字节转为二进制并拼在一起所得到的 32 位值。
例如,10.9.8.7 是 00001010000010010000100000000111。
但请注意,因为 NAT 的存在,这个地址并不总是报文的真实发送端,因此发往此地址的报文会被送往 NAT 设备,并由它被翻译为真实的地址。

目的地址

1
与源地址格式相同,但指出报文的接收端。

选项:

1
2
3
附加的首部字段可能跟在目的地址之后,但这并不被经常使用,从 1 到 40 个字节不等。
请注意首部长度字段必须包括足够的 32 位字来放下所有的选项(包括任何必须的填充以使首部长度能够被 32 位整除)。
当选项列表的结尾不是首部的结尾时,EOL(选项列表结束,0x00)选项被插入列表末尾。下表列出了可能。

字段长度描述
备份1当此选项需要被备份到所有分片中时,设为 1。
2常规的选项类别,0 为“控制”,2 为“查错和措施”,1 和 3 保留。
数字5指明一个选项。
长度8指明整个选项的长度,对于简单的选项此字段可能不存在。
数据可变选项相关数据,对于简单的选项此字段可能不存在。

注:如果首部长度大于 5,那么选项字段必然存在并必须被考虑。
注:备份、类和数字经常被一并称呼为“类型”。

  • 数据 数据字段不是首部的一部分,因此并不被包含在首部检验和中。数据的格式在协议首部字段中被指明,并可以是任意的传输层协议。 一些常见协议的协议字段值被列在下面
协议字段值协议名缩写
1互联网控制消息协议ICMP
2互联网组管理协议IGMP
6传输控制协议TCP
17用户数据报协议UDP
41IPv6 封装ENCAP
89开放式最短路径优先OSPF
132流控制传输协议SCTP

总结

IP 层最重要的目的是让两个主机之间通信,无论他们相隔多远。
IP 协议理论上允许的最大 IP 数据报为 65535 字节(16 位来表示包总长)。
但是因为协议栈网络层下面的数据链路层一般允许的帧长远远小于这个值,例如以太网的 MTU 通常在 1500 字节左右。
所以较大的 IP 数据包会被分片传递给数据链路层发送,分片的 IP 数据报可能会以不同的路径传输到接收主机,接收主机通过一系列的重组,将其还原为一个完整的 IP 数据报,再提交给上层协议处理。
IP 分片会带来一定的问题,分片和重组会消耗发送方、接收方一定的 CPU 等资源,如果存在大量的分片报文的话,可能会造成较为严重的资源消耗;分片丢包导致的重传问题;分片攻击;