# IP

## IPv4 数据报格式

IPv4 数据报由首部和数据组成

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---          ---
|Version|  IHL  |Type of Service|          Total Length         |  |            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |            |
|         Identification        |Flags|      Fragment Offset    |  |            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |            |
|  Time to Live |    Protocol   |         Header Checksum       |  |  20 bytes  |  Min 20B
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |            |  Max 60B
|                    Source IP Address                          |  |            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |            |
|                 Destination IP Address                        |  |            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---           |
|                    Options                    |    Padding    |               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+              ---
|                                                               |
|                Data (Max: 65535 - 20 bytes)                   |
|                                                               |
```

Version: IP 协议版本号，4 bits，对于 IPv4 值为 0100。

Internet Header Length: 首部长度，4 bits，32 位字的数量，最小值为 5，最大值为 15。

Type of service: 服务类型，8 bits，例如 Low Delay, High Throughput, Reliability。

Total Length: 数据报总长度，16 bits，首部加数据的总长度，单位为字节，最小值为 20，最大值为 65535。

Identification: 标识，16 bits，数据报的唯一 ID，用来标识所属分组。IP 模块维护一个计数器,每产生一个数据报,计数器就加 1,并将此值赋给标识字段。当数据报长度超过网络的 MTU 而必须分片时,这个值就被复制到所有分片的标识字段中。将标识字段相同的分片重新组装成原来的数据报。

Flags: 每个 flag 占一位， 第一个是保留位，值为 0。第二个是 do not fragment，第三个是 more fragments flag。DF(Don't Fragment) 值为 1 时不能分片。只有当 DF = 0 时才允许分片。 MF(More Fragment) 值为 1 表示数据报后面还有分片，值为 0 表示数据报是分片中的最后一个。

Fragment Offset: 片偏移,13 bits，分片在原数据报中的相对位置，第一个分片值为 0。片偏移以 8 个字节为偏移单位，即每个分片的长度一定是 8 字节(64 bits) 的整数倍。 (2^13 - 1) \* 8 = 65536 - 8 > 65535 - 20 可以将最大长度的数据报进行分片。

Time to live: 数据报的存活时间，8 bits， 每次经过路由器减去处理数据报消耗的时间。

Protocol: 协议，8 bits，数据报数据部分所对应的协议，以便使目的主机的 IP 模块知道应将数据部分上交给哪个模块。

Header Checksum: 首部校验和，16 bits，只检验数据报的首部,不包括数据部分。数据报每经过一个路由器,都要重新计算一下首部检验和（一些字段，如生存时间，标志，片偏移等都可能发生变化）,不检验数据部分可减少计算量。

Source IP address: 源 IP，32 bits

Destination IP address: 目的 IP，32 bits

Options: 可选信息。可变部分增强了 IP 数据报的功能，但也增加了路由器处理数据报的开销,实际上这些选项很少被使用。IPv6 数据报的首部是固定长度。

## IPv6 数据报格式

IPv6 数据报由首部和负载组成。

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class |           Flow Label                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Payload Length        |  Next Header  |   Hop Limit   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                         Source Address                        +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      Destination Address                      +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   Extension Header + Data                     |
|                                                               |
```

Version: IP 协议版本号，4 bits，对于 IPv6 值为 0110。

Traffic Class: 通信分类，6+2 bits。

Flow Label: 流标签，20 bits，标识数据报所属数据流，例如一个 TCP 会话或者媒体流。值为 0 表示不属于任何流。在使用 IPv4 情况下，需要用源地址、目的地址、源端口、目的端口和传输层协议来标识一个流，而 IPv6 只需要通过流标签、源地址、目的地址。

Payload Length: 负载（扩展头部和数据）长度，16 bits，单位长度为一个字节。

Next Header: 下一个头部，8 bits，标识当前报头（或者扩展报头）的下一个头部类型。紧接着 IPv6 报头的可能不是上层协议头部，而是 IPv6 扩展报头。当没有扩展报头或者当前报头为最后一个扩展报头时才是上层协议头，和 IPv4 协议字段取值一致。

Hop Limit: 跳数限制，8 bits，替代 IPv4 中的 TTL。每次转发的时候减 1，值为 0 且目的主机不是本机时丢弃该数据报。

Source Address: 源主机 IPv6 单播地址，128 bits。

Destination Address: 目的主机 IPv6 单播或多播地址，128 bits。

## IPv4 与 IPv6 对比

* 首部长度：IPv4 的 Options 字段允许 IP 首部长度可变，不能预先确定数据字段从何开始。路由器处理有无选项字段的 IP 数据报所需时间差异很大。而 IPv6 采用固定 40 字节长度的报头，将 IPv4 Options 字段类似的功能放在扩展报头中，由 IPv6 基本报头的下一个首部指向扩展报头。路由器不处理扩展报头，提升了路由器处理效率。
* 分片重组：IPv6 中分片与重组只在源主机与目的主机上进行，而不在路由器进行。将耗时的分片与重组从路由器转移到端系统，很大程度得提升了网络中 IP 数据报的传输效率。如果路由器收到 IPv6 数据报太大而不能转发到链路上，会丢弃该包并向发送方发回一个「分组太大」的 ICMP 差错报文，发送方使用较小长度的 IP 数据报重发数据。
* 首部校验和：每个路由器上，IPv4 首部校验和都需要重新计算，十分耗时。而 IPv6 认为如今的链接层和传输层提供了足够的错误检测，网络传输可靠性有保障，所以 IPv6 不计算首部校验和，从而更快地处理 IP 分组。
* 即插即用：IPv6 与 IPv4 相比，除了显著增加地址空间外，另一个显著特征就是通过 NDP 实现即插即用性。
* 取消广播，提高效率：IPv6 使用组播代替广播。
