IP头部信息
IP数据报的路由和转发
1、IP 服务的特点
1、IP 协议是 TCP/IP 协议族的动力,它为上层协议提供 无状态、无连接、不可靠的服务
2、无状态 是指 IP 通信双方不同步传输数据的状态信息,因此 所有 IP 数据报的发送、传输和接收都是相互独立、没有上下文关系的。这种服务最大的缺点是 无法处理乱序和重复的 IP 数据报。比如发送端发出出的第 N 个 IP 数据报 可能比第 N+1 个 IP 数据报后到达接收端,而同一个 IP 数据报也可能经过不同的路径 多次到达接收端
在这两种情况下,接收端的 IP 模块无法检测到乱序和重复,因为这些 IP 数据报之间没有任何上下文关系。接收端的 IP 模块只要收到了完整的 IP 数据报(如果是 IP 分片的话,IP 模块将先执行重组),就将其数据部分(TCP 报文段、UDP 数据报或者 ICMP 报文)上交给上层协议。那么从上层协议来看,这些数据就可能是乱序的、重复的。面向连接的协议,比如 TCP 协议,则能够自己处理乱序的、重复的报文段,它递交给上层协议的内容 绝对是有序的、正确的
虽然 IP 数据报头部 提供了一个标识字段用以唯一标识一个 IP 数据报,但它被用来处理 IP 分片和重组的,而不是用来指示接收顺序的
无状态服务的优点 也很明显:简单、高效。无须为保持通信的状态 而分配一些内核资源,也无须 每次传输数据时都携带状态信息。在网络协议中,无状态是很常见的,比如 UDP 协议和 HTTP 协议都是无状态协议。以 HTTP 协议为例,一个浏览器的连续两次网页请求之间 没有任何关联,它们将被 Web 服务器独立地处理
3、无连接 是指 IP 通信双方都不长久地维持对方的任何信息。这样,上层协议每次发送数据的时候,都必须明确指定对方的 IP 地址
4、不可靠是指 IP 协议不能保证 IP 数据报准确地到达接收端,它只是承诺尽最大努力。很多种情况都能导致 IP 数据报发送失败。比如,某个中转路由器 发现 IP 数据报在网络上存活的时间太长(根据 IP 数据报头部字段 TTL 判断),那么它将丢弃之,并返回一个 ICMP 错误消息(超时错误)给发送端。又比如,接收端发现收到的 IP 数据报不正确(通过校验机制),它也将丢弃之,并返回一个 ICMP 错误消息(IP 头部参数错误)给发送端。无论哪种情况,发送端的 IP 模块一旦检测到 IP 数据报发送失败,就通知上层协议发送失败,而不会试图重传。因此,使用 IP 服务的上层协议(比如 TCP 协议)需要自己实现 数据确认、超时重传等机制以达到可靠传输的目的
2、IPv4 头部结构
2.1 IPv4 头部结构
其长度通常为 20 字节,除非含有可变长的选项部分
4 位版本号 指定 IP 协议的版本。对 IPv4 来说,其值是 4。其他 IPv4 协议的扩展版本(如 SIP 协议和 PIP 协议),则具有不同的版本号(它们的头部结构也和图 2-1 不同)
4 位头部长度 标识该 IP 头部有多少个 32 bit 字(4 字节)。因为 4 位最大能表示 15,所以 IP 头部最长是 60 字节
8 位服务类型(Type Of Service,TOS)包括一个 3 位的优先权字段(现在已经忽略),4 位的 TOS 字段和 1 位保留字段(必须置 0)。4 位的 TOS 字段分别表示:最小延时,最大吞吐量,最高可靠性 和 最小费用。其中最多有一个能置为 1,应用程序 应该根据实际需要来设置它。比如像 ssh 和 telnet 这样的登录程序需要的是最小延时的服务,而文件传输程序 ftp 则需要最大吞吐量的服务
16 位总长度 是指整个 IP 数据报的长度,以字节为单位,因此 IP 数据报的最大长度为 65 535(216-1)字节。但由于 MTU 的限制,长度超过 MTU 的数据报都将被分片传输,所以实际传输的 IP 数据报(或分片)的长度都远远没有达到最大值
接下来的 3 个字段则描述了如何实现分片
16 位标识 唯一地标识主机发送的每一个数据报。其初始值由系统随机生成;每发送一个数据报,其值就加 1。该值在数据报分片时 被复制到每个分片中,因此同一个数据报的所有分片 都具有相同的标识值
3 位标志字段的第一位保留。第二位(Don’t Fragment,DF)表示 “禁止分片”。如果设置了这个位,IP 模块将不对数据报进行分片。在这种情况下,如果 IP 数据报长度超过 MTU 的话,IP 模块将丢弃该数据报并返回一个 ICMP 差错报文。第三位(More Fragment,MF)表示 “更多分片”。除了数据报的最后一个分片外,其他分片都要把它置 1
13 位分片偏移 是分片相对原始 IP 数据报开始处(仅指数据部分)的偏移。实际的偏移值 是该值左移 3 位(乘 8)后得到的。由于这个原因,除了最后一个 IP 分片外,每个 IP 分片的数据部分的长度必须是 8 的整数倍(这样才能保证后面的 IP 分片拥有一个合适的偏移值)
8 位生存时间(Time To Live,TTL)是数据报到达目的地之前 允许经过的路由器跳数。TTL 值被发送端设置(常见的值是 64)。数据报在转发过程中 每经过一个路由,该值就被路由器减 1。当 TTL 值减为 0 时,路由器将丢弃数据报,并向源端发送一个 ICMP 差错报文。TTL 值可以防止数据报陷入路由循环
8 位协议(protocol)用来区分上层协议,/etc/protocols 文件定义了所有上层协议对应的 protocol 字段的数值。其中,ICMP 是 1,TCP 是 6,UDP 是 17
16 位头部校验和 由发送端填充,接收端 对其使用 CRC 算法以检验 IP 数据报头部(注意,仅检验头部)在传输过程中是否损坏
32 位的源端 IP 地址和目的端 IP 地址 用来标识数据报的发送端和接收端。一般情况下,这两个地址 在整个数据报的传递过程中保持不变,而不论它中间经过多少个中转路由器
IPv4 最后一个选项字段 是可变长的可选信息。这部分最多包含 40 字节,因为 IP 头部最长是 60 字节(其中还包含前面讨论的 20 字节的固定部分)。可用的 IP 选项包括:
- 记录路由,告诉数据报途经的所有路由器 将自己的 IP 地址填入 IP 头部的选项部分,这样 就可以跟踪数据报的传递路径
- 时间戳,告诉每个路由器 都将数据报被转发的时间(或时间与 IP 地址对)填入 IP 头部的选项部分,这样就可以 测量途经路由之间数据报传输的时间
- 松散源路由选择,指定一个路由器 IP 地址列表,数据报发送过程中 必须经过其中所有的路由器
- 严格源路由选择,和松散源路由选择类似,不过数据报 只能经过被指定的路由器
这些选项字段 很少被使用,使用松散源路由选择 和 严格源路由选择选项的例子 大概仅有 traceroute 程序。此外,作为记录路由 IP 选项的替代品,traceroute 程序使用 UDP 报文和 ICMP 报文实现了 更可靠的记录路由功能
2.2 使用 tcpdump 观察 IPv4 头部结构
从测试机器 ernest-laptop 上执行 telnet 命令登录本机,并用 tcpdump 抓取这个过程中 telnet 客户端程序和 telnet 服务器程序之间交换的数据包。具体的操作过程如下:
sudo tcpdump −ntx −i lo # 使用了 tcpdump 工具来捕获和显示 本地回环接口(lo)上的网络数据包
telnet 127.0.0.1 # 开启另一个终端执行 telnet 命令登陆本机
Connected to 127.0.0.1.
Escape character is '^]'.
Ubuntu 9.10
ernest-laptop login: ernest # 输入用户名并回车
Password: # 输入密码并回车
tcpdump: 捕获网络数据包的命令行工具
-n: 表示 不将IP地址和端口号解析为主机名和服务名,而是直接显示数值形式
-t: 表示 不显示时间戳信息
-x: 表示 将每个数据包的内容 以十六进制格式输出
-i lo: 表示 指定在回环接口(lo)上捕获数据包,回环接口是 系统内部通信的虚拟网络接口,用于测试和调试网络通信,以及 在同一台设备上进行内部通信
虚拟接口:回环接口 不是一个物理的网络设备,而是 一个软件模拟的接口。它不依赖于实际的网络硬件,而是完全由操作系统管理
内部通信:回环接口用于 在同一台设备上的应用程序之间传输数据。例如,当一个程序向回环接口发送数据包,这些数据包 会立即返回到同一台设备的接收端,这就像数据包被“循环”回发送端一样
IP地址:回环接口通常与 127.0.0.1 这个特殊的IP地址绑定,常被称为“本地主机”。所有发送到这个地址的数据包 都会被定向回 发送它们的同一台计算机
此时观察 tcpdump 输出的第一个数据包
使用 telnet 登录本机的,所以 IP 数据报的源端 IP 地址和目的端 IP 地址都是 “127.0.0.1”。telnet 服务器程序使用的端口号是 23(参见 /etc/services 文件),而 telnet 客户端程序使用临时端口号 41621 与服务器通信
在本地通过 telnet 连接到本机(即 localhost 或 127.0.0.1),因为通信发生在同一台设备上,数据包不会经过实际的网络接口,而是通过回环接口(lo)进行传输。因此,IP 数据报的源地址和目的地址 都将是回环地址 “127.0.0.1”
最常见的本机地址是 127.0.0.1,这是一个特殊的回环地址,用于设备内部的通信。任何发送到 127.0.0.1 的数据包都会返回到同一台设备,因此它常被用作 “localhost”
其他回环地址:在 IPv4 中,127.0.0.1 只是回环地址范围的一部分,整个 127.0.0.0/8 范围都被保留作为回环地址。因此,127.0.0.2、127.0.1.1 等 其他地址 也可以作为回环地址使用,但通常默认使用 127.0.0.1
在 IPv6 中,本地回环地址是 ::1
“length” 指出该 IP 数据报所携带的应用程序数据的长度
此数据包共包含 60 字节,其中前 20 字节是 IP 头部,后 40 字节是 TCP 头部,不包含应用程序数据(length 值为 0)
telnet 服务 选择使用具有最小延时的服务,并且 默认使用的传输层协议是 TCP 协议。这个 IP 数据报没有被分片,因为它没有携带任何应用程序数据
3、IP 分片
当 IP 数据报的长度 超过帧的 MTU 时,它将被分片传输。分片可能发生在发送端,也可能发生在中转路由器上,而且可能在传输过程中被多次分片,但只有在最终的目标机器上,这些分片 才会被内核中的 IP 模块重新组装
IP 头部中的如下三个字段 给 IP 的分片和重组提供了足够的信息:数据报标识、标志 和 片偏移。一个 IP 数据报的每个分片都具有自己的 IP 头部,它们具有相同的标识值,但具有不同的片偏移。并且除了最后一个分片外,其他分片都将设置 MF 标志。此外,每个分片的 IP 头部的总长度字段 将被设置为该分片的长度
以太网帧的 MTU 是 1500 字节(可以通过 ifconfig 命令或者 netstat 命令查看),因此它携带的 IP 数据报的数据部分最多是 1480 字节(IP 头部占用 20 字节)。考虑用 IP 数据报封装一个长度为 1481 字节的 ICMP 报文(包括 8 字节的 ICMP 头部,所以其数据部分长度为 1473 字节),则该数据报在使用以太网帧传输时必须被分片
长度为 1501 字节的 IP 数据报被拆分成两个 IP 分片,第一个 IP 分片长度为 1500 字节,第二个 IP 分片的长度为 21 字节。每个 IP 分片都包含自己的 IP 头部(20 字节),且第一个 IP 分片的 IP 头部设置了 MF 标志,而第二个 IP 分片的 IP 头部则没有设置该标志,因为它已经是最后一个分片了。原始 IP 数据报中的 ICMP 头部内容被完整地复制到了第一个 IP 分片中。第二个 IP 分片不包含 ICMP 头部信息,因为 IP 模块重组该 ICMP 报文的时候只需要一份 ICMP 头部信息,重复传送这个信息没有任何益处
ICMP 报文的头部长度 取决于报文的类型,其变化范围很大。以 8 字节为例,因为后面的例子用到了 ping 程序,而 ping 程序使用的 ICMP 回显和应答报文的头部长度是 8 字节
从 ernest-laptop 来 ping 机器 Kongming20,每次传递 1473 字节的数据(这是 ICMP 报文的数据部分)以强制引起 IP 分片,并用 tcpdump 抓取这一过程中 双方交换的数据包
$ sudo tcpdump -ntv -i eth0 icmp # 只抓取 ICMP 报文
$ ping Kongming20 -s 1473 # 用 -s 选项指定每次发送 1473 字节的数据
-v: 详细输出模式,提供比默认模式更多的包信息。它会显示数据包的TTL(生存时间)、协议、包长度等详细信息
考察 tcpdump 输出的一个 IP 数据报的两个分片
1. IP(tos 0x0, ttl 64, id 61197, offset 0, flags [+], proto ICMP (1), length 1500) 192.168.1.108 > 192.168.1.110: ICMP echo request, id 41737, seq 1, length 1480
2. IP(tos 0x0, ttl 64, id 61197, offset 1480, flags [none], proto ICMP (1), length 21) 192.168.1.108 > 192.168.1.110: icmp
这两个 IP 分片的标识值都是 61197,说明 它们是同一个 IP 数据报的分片。第一个分片的片偏移值为 0,而第二个则是 1480。很显然,第二个分片的片偏移值 实际上也是第一个分片的 ICMP 报文的长度。第一个分片设置了 MF 标志以表示还有后续分片,所以 tcpdump 输出 “flags [+]”。而第二个分片 则没有设置任何标志,所以 tcpdump 输出 “flags [none]”。这两个分片的长度分别为 1500 字节和 21 字节
最后,IP 层传递给数据链路层的数据 可能是一个完整的 IP 数据报,也可能是一个 IP 分片,它们统称为 IP 分组
4、IP 路由
IP 协议的一个核心任务是 数据报的路由,即决定 发送数据报到目标机器的路径
4.1 IP 模块工作流程
当 IP 模块接收到 来自数据链路层的 IP 数据报时,它首先对该数据报的头部做 CRC 校验,确认无误之后就分析其头部的具体信息
如果该 IP 数据报的头部 设置了源站选路选项(松散源路由选择 或 严格源路由选择),则 IP 模块 调用数据报转发子模块 来处理该数据报。如果该 IP 数据报的头部中 目标 IP 地址是本机的某个 IP 地址,或者是广播地址,即该数据报是发送给本机的,则 IP 模块就根据数据报头部中的协议字段 来决定将它派发给哪个上层应用(分用)。如果 IP 模块发现这个数据报 不是发送给本机的,则也调用数据报转发子模块 来处理该数据报
数据报转发子模块 将首先检测系统是否允许转发,如果不允许,IP 模块就将数据报丢弃。如果允许,数据报转发子模块 将对数据报执行一些操作,然后将它交给 IP 数据报输出子模块
IP 数据报 应该发送至哪个下一跳路由器(或者目标机器),以及 经过哪个网卡来发送,就是 IP 路由过程,即图 中 “计算下一跳路由” 子模块。IP 模块实现数据报路由的核心数据结构是 路由表。这个表按照数据报的目标 IP 地址分类,同一类型的 IP 数据报 将被发往相同的下一跳路由器(或者目标机器)
IP 输出队列中存放的是 所有等待发送的 IP 数据报,其中除了 需要转发的 IP 数据报外,还包括封装了 本机上层数据(ICMP 报文、TCP 报文段和 UDP 数据报)的 IP 数据报
图中的虚线箭头 显示了路由表更新的过程。这一过程是指 通过路由协议或者 route 命令调整路由表,使之更适应最新的网络拓扑结构,称为 IP 路由策略
4.2 路由机制
需要 先了解路由表的内容。可以使用 route 命令或 netstat 命令查看路由表。在测试机器 ernest-laptop 上执行 route 命令
该路由表包含两项,每项都包含 8个字段
字段 | 含义 |
---|---|
Destination | 目标网络或主机 |
Gateway | 网关地址,* 表示目标和本机在同一网络,不需要路由 |
Genmask | 网络掩码 |
Flags | 路由项标志,常见标志有如下 5 种:U,该路由项是活动的;H,该路由项的目标是一台主机;G,该路由项的目标是网关;D,该路由项是由重定向生成的;M,该路由项被重定向修改过 |
Metric | 路由距离,即到达指定网络所需的中转数 |
Ref | 路由项被引用的次数(Linux 未使用) |
Use | 该路由项被使用的次数 |
Iface | 该路由项对应的输出网卡接口 |
第一项的目标地址是 default,即所谓的默认路由项。该项包含一个 “G” 标志,说明路由的下一跳目标是网关(数据包 必须通过指定的网关进行转发,而不是 直接发送到目的地),其地址是 192.168.1.1(这是测试网络中 路由器的本地 IP 地址(在大多数家庭或小型办公室网络中,路由器会使用 192.168.1.1 作为默认的本地IP地址(即网关地址)),当设备在该网络内通信时,如果目标设备 不在同一个子网,数据包将发送到 192.168.1.1,由路由器 负责将其转发到合适的目标)
另外一个路由项的目标地址是 192.168.1.0,它指的是本地局域网。该路由项的网关地址为 * ,说明数据报 不需要路由中转,可以直接发送到目标机器
网关 是一种网络设备,充当不同网络之间的入口和出口,负责在不同网络之间转发数据包。它可以连接两个或多个网络,并根据需要将数据从一个网络传输到另一个网络
给定数据报的目标 IP 地址,它将匹配路由表中的哪一项呢?这就是 IP 的路由机制,分为 3 个步骤:
1)查找路由表中 和数据报的目标 IP 地址 完全匹配的主机 IP 地址。如果找到,就使用该路由项,没找到则转步骤 2
2)查找路由表中和数据报的目标 IP 地址 具有相同网络 ID 的网络 IP 地址(比如代码清单 2-2 所示的路由表中的第二项,具有相同网络 ID 的网络 IP 地址是指那些在同一子网(或网络)内的 IP 地址。每个 IP 地址可以分为两个部分:网络 ID 和 主机 ID,例如,子网掩码 255.255.255.0(即 /24 表示法)意味着前 24 位是网络 ID,后 8 位是主机 ID)。如果找到,就使用该路由项;没找到则转步骤 3
3)选择默认路由项,这通常意味着 数据报的下一跳路由是网关
对于测试机器 ernest-laptop 而言,所有发送到 IP 地址为 192.168.1.* 的机器的 IP 数据报 都可以直接发送到目标机器(匹配路由表第二项),而所有访问因特网的请求都将通过网关来转发(匹配默认路由项)
4.3 路由表更新
路由表 必须能够更新,以反映网络连接的变化,这样 IP 模块才能准确、高效地转发数据报。route 命令可以修改路由表
$ sudo route add -host 192.168.1.109 dev eth0
$ sudo route del -net 192.168.1.0 netmask 255.255.255.0
$ sudo route del default
$ sudo route add default gw 192.168.1.109 dev eth0
第 1 行表示添加主机 192.168.1.109(机器 Kongming20)对应的路由项。这样设置之后,所有从 ernest-laptop 发送到 Kongming20 的 IP 数据报将通过网卡 eth0 直接送至目标机器的接收网卡。第 2 行表示删除网络 192.168.1.0 对应的路由项。这样,除了机器 Kongming20 外,测试机器 ernest-laptop 将无法访问该局域网上的任何其他机器(能访问到 Kongming20 是由于执行了上一条命令)。第 3 行表示删除默认路由项,这样做的后果是无法访问因特网。第 4 行表示重新设置默认路由项,不过这次其网关是机器 Kongming20(而不是能直接访问因特网的路由器)
sudo route add -host 192.168.1.109 dev eth0
:
目的:将特定的主机(192.168.1.109)的路由添加到路由表中,并指定该路由使用网络接口 eth0
解释:
sudo:以超级用户权限运行命令
route add:添加一个新的路由条目
-host 192.168.1.109:指定目标是单一主机 192.168.1.109
dev eth0:指定路由条目应使用 eth0 这个网络接口
作用:当 计算机需要与 192.168.1.109 进行通信时,它会通过 eth0 接口发送数据包
sudo route del -net 192.168.1.0 netmask 255.255.255.0
:
route del:删除一个路由条目。
-net 192.168.1.0:指定目标网络 192.168.1.0
netmask 255.255.255.0:指定该网络的子网掩码,表示该网络范围是 192.168.1.0 到 192.168.1.255
sudo route add default gw 192.168.1.109 dev eth0
:
gw 192.168.1.109:指定使用网关 192.168.1.109 作为下一跳
第一个路由项是 主机路由项,所以它被设置了 “H” 标志
通过 route 命令 或 其他工具 手工修改路由表,是静态的路由更新方式。对于大型的路由器,它们通常通过 BGP(Border Gateway Protocol,边际网关协议)、RIP(Routing Information Protocol,路由信息协议)、OSPF 等协议来发现路径,并更新自己的路由表。这种更新方式是 动态的、自动的
- BGP(Border Gateway Protocol,边界网关协议)
概述:
BGP 是一种用于在不同自治系统(AS,Autonomous System)(例如,不同的互联网服务提供商)之间交换路由信息的协议,主要应用于互联网上的路由选择
BGP 是唯一的外部网关协议(EGP)
特性:
路径矢量协议:BGP 通过维护从源到目标的整个路径信息 来选择最佳路径
策略控制:BGP 允许网络管理员 根据多种策略(如路由策略、经济考虑、网络性能)来控制路由选择
规模和可扩展性:BGP 是为大型网络设计的,能够处理 全球互联网的路由信息
慢收敛性:由于 BGP 的复杂性和全球范围的应用,它的收敛速度相对较慢
应用场景:
BGP 被广泛应用于互联网的核心部分,负责在不同 ISP 之间进行路由选择和路由信息交换
适用于 需要复杂路由策略和高可扩展性的场景 - RIP(Routing Information Protocol,路由信息协议)
概述:
RIP 是一种基于距离矢量的路由协议,属于内部网关协议(IGP)。它最初用于小型局域网(LAN),随着网络的增长,逐渐被更高级的协议(如 OSPF 和 EIGRP)取代
特性:
距离矢量协议:RIP 通过计算跳数(从源到目标路由器的中间路由器数量)来选择最佳路径
跳数限制:RIP 允许的最大跳数为 15,跳数为 16 时表示不可达。因此,RIP 适用于小型网络
定期更新:RIP 每隔 30 秒 向所有相邻路由器广播整个路由表,导致带宽的浪费和慢收敛
简单性:RIP 易于配置和管理,但由于它的简单性,适用范围有限
应用场景:
RIP 适用于小型、简单的网络,由于 其跳数限制和带宽浪费问题,不适合大规模网络
主要用于早期的局域网和一些简单的网络环境 - OSPF(Open Shortest Path First,开放最短路径优先)
概述:
OSPF 是一种链路状态路由协议,属于内部网关协议(IGP)。它被广泛应用于 大型企业网络和服务提供商网络中,用于在单一自治系统内进行路由选择
特性:
链路状态协议:OSPF 通过维护整个网络的拓扑结构 来计算最短路径,使用 Dijkstra 算法来选择最佳路径
快速收敛:OSPF 的收敛速度 比 RIP 快得多,这使得它能够在大型网络中迅速适应拓扑变化
区域划分:OSPF 允许网络划分为多个区域,减少路由信息的传播量,提高效率
无类路由:OSPF 支持无类域间路由(CIDR),允许使用更灵活的子网划分
应用场景:
OSPF 适用于中大型网络,如企业局域网、服务提供商网络等
特别适合需要快速收敛和灵活配置的复杂网络环境
5、IP 转发
不是发送给本机的 IP 数据报 将由数据报转发子模块来处理。路由器 都能执行数据报的转发操作,而主机一般只发送 和 接收数据报,这是因为主机上 /proc/sys/net/ipv4/ip_forward 内核参数 默认被设置为 0。可以通过修改它来使能 主机的数据报转发功能
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1
:echo 命令用于将 1 输出到标准输出。1 在这里表示启用某个功能
> /proc/sys/net/ipv4/ip_forward
:> 是重定向操作符,将前面的输出内容写入到 /proc/sys/net/ipv4/ip_forward 文件中
对于允许 IP 数据报转发的系统(主机或路由器),数据报转发子模块 将对期望转发的数据报 执行如下操作:
1)检查数据报头部的 TTL 值。如果 TTL 值已经是 0,则丢弃该数据报
2)查看 数据报头部的严格源路由选择选项。如果 该选项被设置,则检测数据报的目标 IP 地址 是否是本机的某个 IP 地址。如果不是,则发送一个 ICMP 源站选路失败报文 给发送端
3)如果有必要,则给源端发送一个 ICMP 重定向报文,以告诉它 一个更合理的下一跳路由器
4)将 TTL 值减 1
5)处理 IP 头部选项
6)如果有必要,则执行 IP 分片操作
6、重定向
ICMP 重定向报文也能用于更新路由表
6.1 ICMP 重定向报文
ICMP 报文头部的 3 个固定字段:8 位类型、8 位代码 和 16 位校验和。ICMP 重定向报文的类型值是 5,代码字段有 4 个可选值,用来 区分不同的重定向类型。仅讨论 主机重定向,其代码值为 1
ICMP 重定向报文的数据部分 含义很明确,它给接收方提供了如下两个信息:
- 引起重定向的 IP 数据报的源端 IP 地址
- 应该使用的路由器的 IP 地址
接收主机 根据这两个信息就可以断定 引起重定向的 IP 数据报应该使用哪个路由器来转发,并且以此来更新路由表(通常是更新路由表缓冲,而不是直接更改路由表)
/proc/sys/net/ipv4/conf/all/send_redirects 内核参数 指定是否允许发送 ICMP 重定向报文,而 /proc/sys/net/ipv4/conf/all/accept_redirects 内核参数 则指定是否允许接收 ICMP 重定向报文。一般来说,主机只能接收 ICMP 重定向报文,而 路由器只能发送 ICMP 重定向报文
6.2 主机重定向实例
把机器 ernest-laptop 的网关设置成了机器 Kongming20,第 5 节中 又使能了 Kongming20 的数据报转发功能,因此机器 ernest-laptop 将通过 Kongming20 来访问因特网
$ ping www.baidu.com
PING www.a.shifen.com (119.75.217.56) 56(84) bytes of data.
From Kongming20 (192.168.1.109): icmp_seq=1 Redirect Host(New nexthop: 192.168.1.1)
64 bytes from 119.75.217.56: icmp_seq=1 ttl=54 time=6.78 ms
-- www.a.shifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.789/6.789/6.789/0.000 ms
从 ping 命令的输出来看,Kongming20 给 ernest-laptop 发送了一个 ICMP 重定向报文,告诉它请通过 192.168.1.1 来访问目标机器,因为这对 ernest-laptop 来说是更合理的路由方式。当主机 ernest-laptop 收到这样的 ICMP 重定向报文后,它将 更新其路由表缓冲(使用命令 route -Cn 查看),并使用新的路由方式来 发送后续数据报
7、IPv6 头部结构
不仅解决了 IPv4 地址不够用的问题,还做了很大的改进。比如,增加了 多播和流的功能,为网络上多媒体内容的质量 提供精细的控制;引入自动配置功能,使得局域网管理更方便;增加了 专门的安全网络功能等
7.1 IPv6 固定头部结构
IPv6 头部由 40 字节的固定头部和可变长的扩展头部组成
4 位版本号 指定 IP 协议的版本。对 IPv6 来说,其值是 6
8 位通信类型 指示数据流通信类型或优先级,和 IPv4 中的 TOS 类似
20 位流标签 是 IPv6 新增加的字段,用于 某些对连接的服务质量有特殊要求的通信,比如 音频或视频等实时数据传输
16 位净荷长度 指的是 IPv6 扩展头部和应用程序数据长度之和,不包括固定头部长度
8 位下一个报头(next header)(包的头部)指出紧跟 IPv6 固定头部后的包头类型,如扩展头(如果有的话)或某个上层协议头(比如 TCP,UDP 或 ICMP)。它类似于 IPv4 头部中的协议字段,且相同的取值有相同的含义
8 位跳数限制 和 IPv4 中的 TTL 含义相同
IPv6 用 128 位(16 字节)来表示 IP 地址,使得 IP 地址的总量达到了 2128 个
32 位表示的 IPv4 地址一般用点分十进制来表示,而 IPv6 地址则用十六进制字符串表 示,比如“FE80:0000:0000:0000:1234:5678:0000:0012
”。可见,IPv6 地 址 用“:”分割成 8 组,每组包含 2 字节
但这种表示方法过于麻烦,通常可以使用所谓的零压缩法来将其简化,也就是省略连续的、全零的组。比如,上面的例子使用零压缩法可表示为 “FE80::1234:5678:0000:0012
”。不过零压缩法对一个 IPv6 地址只能使用一次,比如上面的例子中,字节组“5678”后面的全零组就不能再省略,否则我们就无法计算每个“:”之间省略了多少个全零组
7.2 IPv6 扩展头部
可变长的扩展头部 使得 IPv6 能支持更多的选项,并且 很便于将来的扩展需要。它的长度可以是 0,表示数据报没使用任何扩展头部。一个数据报可以包含 多个扩展头部,每个扩展头部的类型 由前一个头部(固定头部或扩展头部)中的下一个报头字段指定
扩展头部 | 含 义 |
---|---|
Hop-by-Hop | 逐跳选项头部,它包含每个路由器都必须检查和处理的特殊参数选项 |
Destination options | 目的选项头部,指定由最终目的节点处理的选项 |
Routing | 路由头部,指定数据报要经过哪些中转路由器,功能类似于 IPv4 的松散源路由选择选项和记录路由选项 |
Fragment | 分片头部,处理分片和重组的细节 |
Authentication | 认证头部,提供数据源认证、数据完整性检查和反重播保护(用于防止攻击者 重复发送相同的数据包 以试图欺骗接收方或扰乱网络通信:攻击者重播认证数据包,试图伪装成合法用户;中断服务:通过重复发送旧的数据包,攻击者可能会扰乱正常的网络服务或通信流程) |
Encapsulating Security Payload | 加密头部,提供加密服务 |
No next header | 没有后续扩展头部 |
IPv6 协议并不是 IPv4 协议的简单扩展,而是完全独立的协议。用以太网帧封装的 IPv6 数据报和 IPv4 数据报具有不同的类型值。IPv4 数据报的以太网帧封装类型值是 0x800,而 IPv6 数据报的以太网帧封装类型值是 0x86dd