Linux高性能服务器编程 总结索引 | 第2章:IP协议详解

news2024/11/15 17:19:31

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 等协议来发现路径,并更新自己的路由表。这种更新方式是 动态的、自动的

  1. BGP(Border Gateway Protocol,边界网关协议)
    概述:
    BGP 是一种用于在不同自治系统(AS,Autonomous System)(例如,不同的互联网服务提供商)之间交换路由信息的协议,主要应用于互联网上的路由选择
    BGP 是唯一的外部网关协议(EGP)
    特性:
    路径矢量协议:BGP 通过维护从源到目标的整个路径信息 来选择最佳路径
    策略控制:BGP 允许网络管理员 根据多种策略(如路由策略、经济考虑、网络性能)来控制路由选择
    规模和可扩展性:BGP 是为大型网络设计的,能够处理 全球互联网的路由信息
    慢收敛性:由于 BGP 的复杂性和全球范围的应用,它的收敛速度相对较慢
    应用场景:
    BGP 被广泛应用于互联网的核心部分,负责在不同 ISP 之间进行路由选择和路由信息交换
    适用于 需要复杂路由策略和高可扩展性的场景
  2. RIP(Routing Information Protocol,路由信息协议)
    概述:
    RIP 是一种基于距离矢量的路由协议,属于内部网关协议(IGP)。它最初用于小型局域网(LAN),随着网络的增长,逐渐被更高级的协议(如 OSPF 和 EIGRP)取代
    特性:
    距离矢量协议:RIP 通过计算跳数(从源到目标路由器的中间路由器数量)来选择最佳路径
    跳数限制:RIP 允许的最大跳数为 15,跳数为 16 时表示不可达。因此,RIP 适用于小型网络
    定期更新:RIP 每隔 30 秒 向所有相邻路由器广播整个路由表,导致带宽的浪费和慢收敛
    简单性:RIP 易于配置和管理,但由于它的简单性,适用范围有限
    应用场景:
    RIP 适用于小型、简单的网络,由于 其跳数限制和带宽浪费问题,不适合大规模网络
    主要用于早期的局域网和一些简单的网络环境
  3. 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2086265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux应用编程实战】常见函数应用

介绍一些Linux应用编程实战遇到的,常见要用的函数,进行概况总结。 目录 main() lseek() poll() struct pollfd 结构体返回值典例 mmap() munmap(…

kylin-麒麟操作系统-安装内存泄露补丁-以及kylin-kms-activation.service服务不断重启解决思路

文章目录 前言1. 问题现象1.1 使用journalctl命令查看更详细的日志信息 2. 解决思路2.1 思路一:2.2 思路二:2.3 合理的解法: 3. 扩展-修复内存泄露3.1 查看自己使用的镜像3.2 到麒麟官网下载相应的补丁包3.3 安装步骤3.4 重启kylin-kms-activation.servi…

python如何另起一行

python 字符串换行的三种方式: 第一种:三个单引号 print 我是一个程序员 我刚开始学习python 第二种:三个双引号 print """ 我是一个程序员 我刚开始学习python""" 第三种:\结尾 print "我是…

生成式AI,搜索赛道的又一个黄金十年

文|白 鸽 编|王一粟 随着生成式AI的发展,搜索引擎正在被重构,越来越多玩家开始布局AI搜索赛道。 一方面,传统搜索引擎/浏览器正借助AI技术的重构重新焕发生机,无论是移动端还是PC端,都在抢占…

GHA高质量原创文章是什么?

GHA文章是一种专为提高搜索引擎优化(SEO)效果而设计的高质量原创内容。GHA代表高质量,这些文章通过精心编写和策略布局,就是为了帮助网站迅速在Google等搜索引擎上获得排名,写一篇能在Google上获得高排名的文章&#x…

postman注入csrf

示例脚本 参数配置位置 必要参数 django项目仅需要设置domain即可,比如www.baidu.com,baidu.com尽量域名精确避免修改到其他域的参数 必须把这个domain添加到 cookies->Manage cookies ->Domains Allowlist 中,否则cookie的注入失败 代码 // 必…

P1516 青蛙的约会(exgcd)

一些前置知识: 1.扩展欧几里得算法: axbygcd(a,b) 方程一个可行的解(x1,y1)求法: int exgcd(int a,int b,int &x,int &y) {if(!b){x1,y0; return a;}int dexgcd(b,a%b,y,x);y-a/b*x;return d; }2.由axbygcd…

URP简洁的instance的写法

材质还是要开启enable instance,这是上一次的写法 https://dbbh666.blog.csdn.net/article/details/136644181 最近发现更适合我个人的习惯的写法 就是代码控制这个整个过程 C#代码是这样的,获取一个mesh,获取每个mesh的transform&#xff0c…

UE5 摄像机图像采集到材质 映射到 UI 和 物体表面

一.创建SceneCapture2D的组件 二.创建用于 映射的 贴图 三.将RenderTarget贴图放到SceneCapture2D的摄像机上Scene Capture的TextureTarget 四.这个时候的映射贴图,产生的材质可以直接。放到Plane上。 五,但是如果要用于UI,还需要更改SceneCapture2D的摄…

基于SpringBoot的在线答疑系统

你好呀,我是计算机专业毕业生,专注于在线教育平台的开发与实现。 开发语言:Java 数据库:MySQL 技术:Java技术 Spring Boot框架 工具:IntelliJ IDEA、Navicat、Maven、Tomcat 系统展示 首页 个人中心…

【Python】简单的数据类型——int、float、bool、str

目录 1. 整数类型 int 2. 浮点数类型 float 3. 布尔类型 bool 4. 字符串 str 5. 格式化输出 6. 类型转换 6.1 隐式类型转换 6.2 显示类型转换 7. 标准输入 1. 整数类型 int a 10 print(type(a)) print(type(-2))<class int> <class int>测试整型能表示的…

docker私有云仓库Harbor部署及使用

文章目录 一、前置准备1、安装docker、docker-compose 二、安装harbor1、下载Harbor2、证书3、配置文件4、安装5、docker使用6、k8s使用&#xff08;1.28版本containerd&#xff09; 三、常用运维1、重启 一、前置准备 1、安装docker、docker-compose centos7安装与卸载docke…

2024年【道路运输企业安全生产管理人员】考试题库及道路运输企业安全生产管理人员考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年道路运输企业安全生产管理人员考试题库为正在备考道路运输企业安全生产管理人员操作证的学员准备的理论考试专题&#xff0c;每个月更新的道路运输企业安全生产管理人员考试试题祝您顺利通过道路运输企业安全生…

牛客NC313 两个数组的交集 C++

牛客NC313 两个数组的交集 C 思路&#x1f914;&#xff1a; 用哈希表存储第一个数组&#xff0c;再和第二个数组对比&#xff0c;对比成功就添加到新的数组中&#xff0c;之后将哈希表的该位置变为false&#xff0c;防止重复添加。这里数据范围仅有1000&#xff0c;所以我们可…

Windows10系统中安装Maven 3.8.8的步骤

Windows10系统中安装Maven 3.8.8的步骤 1、前提 因已安装好了JDK17,需要安装跟JDK17对应的版本,选了maven3.8.8 2. 下载 Maven 访问 Apache Maven 官网下载页面。选择下载:apache-maven-3.8.8-bin.zip 3、解压缩 4、增加系统环境变量 MAVEN_HOME =C:\hmf\apache-maven…

cppbase阶段汇总

第一章 C与C 本章主要讲解C相较于C一些独有的比较重要的知识点。 C源文件后缀名&#xff1a;.cc或.cpp 头文件后缀名&#xff1a;.hh或.hpp 安装g命令&#xff1a;sudo apt install g 编译命令&#xff1a;g filename.cc [-o name] 首先从C的 hello,world 程序入手&#xff0c…

【C++笔记】类和对象的深入理解(一)

【C笔记】类和对象的深入理解(一) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(一)前言一.类的定义1.1类定义格式1.2访问限定符1.3类域 二.实例化2.1 实例化概念2.2对象大小 三.this指针四.练…

8月29日wpf

小语 折磨我们的往往是想象&#xff0c;而不是真实。 学wpf 7.07 1.vs如何创建新项目&#xff1f; 退出&#xff0c;创建新项目&#xff0c;点c#&#xff0c;windows&#xff0c;进入界面 2.app.config在哪里&#xff1f; 好像只有这个。。。 试一下&#xff0c;不是 我…

CSS基础 什么是盒模型

是什么 当对一个文档进行布局&#xff08;layout&#xff09;的时候&#xff0c;浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型&#xff08;CSS basic box model&#xff09;&#xff0c;将所有元素表示为一个个矩形的盒&#xff08;box&#xff09; 一个盒子由四个部分…

【YOLO系列】YOLO算法改进史

目录 前言YOLOv1YOLOv2YOLOv3YOLOv4YOLOv5YOLOv6YOLOv7YOLOv8YOLOv9YOLOv10对比待更新 前言 YOLO&#xff08;You Only Look Once&#xff09;是一种革命性的目标检测算法&#xff0c;以其快速和高效的性能而闻名。自2015年YOLOv1的首次推出以来&#xff0c;YOLO系列已经经历了…