Linux内核之ICMPv6详解

2023-10-30

要知道什么是ICMPv6协议、我们首先要知道什么是ICMP?ICMP是一种面向无连接的协议,负责传递可能需要注意的差错和控制报文,差错指示通信网络是否存在错误(如目的主机无法到达、IP路由器无法正常传输数据包等。注意,路由器缓冲区溢出导致的丢包不包括在ICMP响应范围内,在TCP负责范围)。

ICMPv4和ICMPv6分别指用于IPv4和IPv6的ICMP版本。在IPv4网络中,ICMP协议用于在路由器、主机之间传递控制消息,主要有控制报文与信息报文。比如主机不可达、路由是否可用或者网络通不通等消息。这些信息也是我们日常去排查网络所用到的基本手段。当然,控制消息本身不会传输数据,但对于整个网络而言,对于传输数据而言,都是不可或缺的一部分。

与IPv4一样,IPv6也需要使用到ICMP报文;在IPv6中,ICMP开发了新的版本,称之为ICMPv6。ICMPv6 全称 Internet Control Message Protocol for the IPv6,它是IPv6的基础协议之一。那么它和ICMPV4有什么区别呢?相较于ICMPv4,ICMPv6实现的功能更多,IPv4网络中使用的ICMP、ARP、IGMP、RARP等功能,在IPv6网络中均由ICMPv6替代实现。除此之外,ICMPv6报文还用于IPv6的无状态自动配置、重复地址检测、前缀重新编址、路径MTU(Maximum Transmission Unit,最大传输单元)发现等。在IPv4中,协议字段值为1表示该报文携带了ICMPv4;在IPv6中,ICMPv6报文位于扩展头部里,ICMPv6扩展头部上一个头部包含了值为58的”下一个头部”字段。

当然、 ICMPv6协议还用以汇报IPv6节点在数据文件处理方式中发生的不正确信息,并完成简易的网络诊断作用。ICMPv6新增多的邻居发现作用替代了ARP协议的作用,因此 ,在IPv6网络体系结构中早已沒有ARP协议了。除了支持IPv6详细地址文件格式以外,ICMPv6还给支持IPv6中的路由器优化、IP组播、移动IP等增多了一些新的报文格式种类。

下面我们一起来看看IMCPv6的三个重要知识点:ICMPv6差错报文、ICMPv6消息报文和PMTU(路径MTU)。

3.1、ICMPv6差错报文

ICMP报文可分为两类:有关IP数据报传递的ICMP报文(差错报文)和信息采集和配置的ICMP报文(查询或者信息类报文)。ICMP差错报文不会对以下报文进行响应:

另一个ICMP差错报文;

头部损坏的数据报;

IP层的广播/组播数据报;

封装在链路层广播或者组播帧中的数据报;

无效或者网络为零的源地址数据报;

或除第一个之外的其他分片。

限制生成ICMP差错报文的原因是限制生成广播风暴。在[RFC4443]中,推荐采用令牌桶(token bucket)方法来限制ICMP报文速率。过程如下(一令牌大小为一字节):

假设”桶”里保存了最大数量”B”的”令牌”,如果”令牌”到达时”桶”满了,则”令牌”被丢弃;

当一个N字节的数据包达到,如果”桶”中多于N个”令牌”,则删除N个”令牌”,且数据包被发送到网络;如果”桶”中少于N个”令牌”,则不删除”令牌”,且认为这个数据包在流量限制之外。

ICMPv4到ICMPv6的转换只有回显请求和回显应答报文被转换,为了执行这个转换,类型值(8和0)分别被转换到值128和129。在转换之后,计算并应用ICMPv6的伪头部校验和。当转换ICMPv4差错报文时,只有下面的差错报文被转换了:目的不可达(类型3),超时(类型11),参数问题(类型12)。ICMPv6到ICMPv4的转换回显请求(类型128)和回显应答(类型129)报文被分别转换到ICMPv4回显请求(类型8)和回显应答(类型0),更新校验和以体现类型值变化和缺少为头部计算,其他信息类报文将被丢弃。

好了、说了这么多;我们在试验环境中抓一个ICMPv6的数据包看看。试验拓扑和配置信息如下:

# R1配置
Router>en
Router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#host R1
R1(config)#ipv6 unicast-routing 
R1(config)#inter ethernet 0/0
R1(config-if)#ipv6 enable
R1(config-if)#ipv6 add 2001:12::1/64
R1(config-if)#no shutdown 
R1(config)#ipv6 route ::/0 2001:12::2 
R1(config)#end
R1#wr
Building configuration...
[OK]
R1#

# R2配置
Router>en
Router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#host R2 
R2(config)#ipv6 unicast-routing 
R2(config)#inter ethernet 0/0
R2(config-if)#ipv6 add 2001:12::2/64
R2(config-if)#no shutdown 
*Jan  7 19:50:06.281: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to up
*Jan  7 19:50:07.285: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to up
R2(config-if)#exit  
R2(config)#int ethernet 0/1
R2(config-if)#ipv6 enable 
R2(config-if)#ipv6 add 2001:23::2/64
R2(config-if)#no shutdown 
R2(config-if)#end
R2#wr
Building configuration...
[OK]
R2#

# R3配置
Router>en
Router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#host R3
R3(config)#ipv6 unicast-routing 
R3(config)#interface ethernet 0/0
R3(config-if)#ipv6 enable 
R3(config-if)#ipv6 address 2001:23::3/64
R3(config-if)#no shutdown 
R3(config)#ipv6 route ::/0 2001:23::2
R3(config)#end 
R3#wr
Building configuration...
[OK]
R3#

配置完成以后我们在R1路由器上ping 2001:23::3这个地址,然后在R2上抓ETH0/1的接口数据包:

抓包内容如下:

注:从上图我们可以看到、ping 2001:23::3命令执行后发送的数据包和返回的数据包;其中发送数据类型request是128,而返回数据类型reply是129;ping命令Data长度是52个字节,而Data的数据内容为:0001–33的ASIIC码(换成十进制就是从00-51)。

【文章福利】小编推荐自己的Linux内核技术交流群: 【977878001】整理一些个人觉得比较好得学习书籍、视频资料;进群私聊群管理领取 内核资料包(含视频教程、电子书、实战项目及代码)

3.2、ICMPv6消息报文

由于某些ICMP的功能已经被其他特殊目的的协议代替,保存下来的广泛使用的ICMP查询/信息类报文是回显请求/应答报文(常用的”ping”),以及路由器发现报文。回显请求/应答相对简单,收到回显请求之后,ICMP的实现要求将任何收到的数据返回给发送者。其报文结构如下:

发送主机利用标识符来分离返回的应答(如多个ping同时允许的时候,用于区分返回的应答)。当一个ping实例运行时,序列号从0开始,每发送一个回显请求则加1.路由器发现则较为复杂,也就是与移动IP一起使用的那个。其主要目的是让一台主机学习到它所在的本地子网中所有路由器,从而选择一台作为默认路由器,也用于发现那些愿意充当移动IP代理的路由器。

地址数给出报文中路由地址块的个数,每个块包含一个IPv4地址及相应的优先水平(优先水平是一个32位的有符号二进制补码整数,其值越大代表优先级越高。默认的优先水平是0,特殊值0x80000000表示这个地址不应该用作有效的默认路由);地址条目大小给出每个块的32位字数;生命周期给出地址列表被认为有效的秒数;序列号字段给出了自从初始化之后代理产生的这种扩展的个数;注册字段给出了发送 代理愿意接受MIPv4注册的最大秒数(0xFFFF表示无穷大);那些字母的含义:R(为MIP服务所需的注册)、B(代理太忙无法接受注册)、H(代理愿意充当本地代理)、F(代理愿意充当外地代理)、M(支持最小封装格式)、G(代理支持封装数据报的GRE隧道)、r(保留零)、T(支持反向隧道)、U(支持UDP的隧道)、X(支持撤销注册)、I(外地代理支持区域注册)。

注:由类型字段决定的ICMPv6报文类型:差错报文的类型从0-127,信息类报文类型为128-255

ICMPv6报文类型使用的代码:

一般来说,对于传入的ICMP信息,查询或信息类将被操作系统自动处理,差错类报文传递给用户进程或传输层协议(除去重定向报文和目的地不可达,前者导致主机路由表的自动更新,后者用于路径MTU发现机制)。传入的ICMPv6报文处理规则如下:

  1. 未知的ICMPv6差错报文必须传递给上层产生差错报文的进程;

  2. 未知的ICMPv6信息类报文被丢弃;

  3. ICMPv6差错报文将会尽可能多地包含到差错的原始(违规)IPv6报文,最终的差错报文大小不能超过最小的IPv6 MTU(1280字节);

  4. 在处理ICMPv6差错报文时,需要提取原始或违规数据包中的上层协议类型,用于选择适当的上层进程;

  5. 存在处理差错的特殊规则;

  6. IPv6节点必须限制它发生ICMPv6差错报文的速率。

3.3、PMTU(路径MTU)

在 IPv4 中,报文如果过大,必须要分片进行发送,所以在每个节点发送报文之前,设备都会根据发送接口的最大传输单元 MTU (Maximum Transmission Unit)来对报文进行分片。

但是在 IPv6 中,为了减少中间转发设备的处理压力,中间转发设备不对 IPv6 报文进行分片,报文的分片将在源节点进行 。当中间转发设备的接口收到一个报文后,如果发现报文长度比转发接口的 MTU 值大,则会将其丢弃;同时将转发接口的 MTU 值通过 ICMPv6 报文的“Packet Too Big”消息发给源端主机,源端主机以该值重新发送 IPv6 报文,这样带来了额外流量开销。 PMTU 发现协议 可以动态发现整条传输路径上各链路的 MTU 值,减少由于重传带来的额外流量开销。PMTU 协议是通过 ICMPv6 的 Packet Too Big 报文来完成的。首先源节点假设 PMTU 就是其出接口的 MTU,发出一个试探性的报文,当转发路径上存在一个小于当前假设的 PMTU 时,转发设备就会向源节点发送 Packet Too Big 报文,并且携带自己的 MTU 值,此后源节点将 PMTU 的假设值更改为新收到的 MTU 值继续发送报文。如此反复,直到报文到达目的地之后,源节点就能知道到达目的地的 PMTU 了。

注:在VLANIF接口下,交换机支持MTU值设置,协议栈发出的报文会按设置的MTU值分片。但是硬件芯片中不支持MTU值设置,默认最大值12K。

如上图:整条传输路径需要通过 4 条链路,每条链路的 MTU 分别是 1500、 1500、 1400、 1300,当源节点发送一个分片报文的时候,首先按照 PMTU 为 1500 进行分片并发送分片报文,当到达 MTU 为 1400的出接口时,路由器返回 Packet Too Big 错误,同时携带 MTU 值为 1400 的信息。源节点接收到之后会将报文重新按照 PMTU 为 1400 进行分片并再次发送一个分片报文,当分片报文到达 MTU 值为 1300 的出接口时,同样返回 Packet Too Big 错误,携带 MTU 值为 1300 的信息。之后源节点重新按照 PMTU 为 1300 进行分片并发送分片报文,最终到达目的地,这样就找到了该路径的 PMTU。

注:由于IPv6要求链路层所支持的最小MTU为1280,所以PMTU的值必须大于1280。我们建议您用1500作为链路的PMTU值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux内核之ICMPv6详解 的相关文章

随机推荐

  • 解决Linux,Ubuntu下使用python包管理工具pip命令安装和下载包速度很慢、失败或者connection timeout等问题

    pip 是 Python 包管理工具 该工具提供了对Python 包的查找 下载 安装 卸载的功能 1 原因 pip命令在Linux系统下使用频率非常高 但是国内使用时常常会下载很慢 或者经常提醒连接超时 其主要问题就是它的默认服务器在国外
  • Beyond Compare 4 密钥解决办法

    修改注册表 1 在搜索栏中输入 regedit 打开注册表 2 Ctrl F搜索CacheId 3 删除项目CacheId 路径 HKEY CURRENT USER Software Scooter Software Beyond Comp
  • HCIP笔记

    HCIA复习 抽象语言 编码编码 二进制 二进制 电信号处理电信号 OSI参考模型 OSI RM 应用层 表示层 会话层 传输层 端口号 0 65535 1 1023是注明端口网络层 IP地址 数据链路层 物理层 ARP协议 正向ARP 通
  • 手把手教你写垃圾分类系统

    垃圾分类是目前社会的一个热点 制作垃圾分类只要找到合适的数据集 垃圾分类的模型构建并不难 这里收集了一份关于垃圾分类的数据集 一共有四个大类和245个小类 大类分别是厨余垃圾 可回收物 其他垃圾和有害垃圾 小类主要是垃圾的具体类别 果皮 纸
  • 2021-10-24

    2021 10 24
  • Linux系统常用命令

    文章目录 一 Linux目录介绍 二 Linux命令 三 Linux常用系统工作命令 1 输出字符串或者环境变量取值后的值 echo 2 显示或者设置系统时间与日期 date 3 设置系统时间 timedatectl 4 系统重启 rebo
  • C++模板-泛型函数与泛型类

    泛型 在调用函数或使用该类时才指定特定的类型 可以避免重复写类似功能代码 那C 语言如何定义泛型呢 Author W 泛型 模板 只有在调用或使用该函数或类时 才确定类型 1 泛型函数 2 泛型类 引入标准输入输出流 include
  • C++异常详细介绍

    目录 前言 一 C 异常概念 二 异常的抛出和匹配规则 三 异常的重新抛出 四 异常安全问题 五 异常规范说明 六 自定义异常体系 七 C 标准库的异常体系 八 异常优缺点 前言 在C语言中处理错误的方式和缺陷有 返回错误码 缺陷 1 错误
  • 硬件系统工程师宝典(22)-----电容、电感的特性,你都知道吗?

    各位同学大家好 欢迎继续做客电子工程学习圈 今天我们继续来讲这本书 硬件系统工程师宝典 上篇我们说到做电阻选型时要考虑阻值 功率 精度和封装大小 上下拉电阻除了给引脚一个稳定的电平 可以提高电压准位 增加输出功率以及满足阻抗匹配的要求 今天
  • buuctf(入门) Have Fun

    首先我们打开题目链接 我们看到一只猫 什么也没有 直接F12查看原代码 发现中间绿色代码的意思大概是定义一个数cat赋予它值cat值cat使用get函数请求的 如果数cat dog的话 则输出syc cat cat cat 所以我们只需要在
  • 867. 转置矩阵

    class Solution public vector
  • 安装postgresql以及乱码问题

    一 进入官网 按照自己的电脑型号选择合适的安装包 点下载那个图标的时候没有反应就多点几次 就可以弹出下载窗口了 二 打开下载好的安装包进行安装 可能出现乱码问题 一般出现这个问题大部分是因为你的系统用户名有中文字符 你需要把它改掉才行 之前
  • 区块链数据结构概述(MT、MPT)

    区块链数据结构概述 MT MPT Ethereum Foundation Blog MT Hash List Merkle Tree Merkle Tree的主要特点 Merkle Tree的相关操作 MPT Merkle Patricia
  • 请教Ado.Net按文本读取CSV/Txt文件时,如何禁止将内容转换成数字

    例如现有文件内容如下 文件内容开始 Column1 Column200001234 00005678 文件内容结束 读得的结果是 lt 1234 5678 gt 即它 智能 地认为我里面的内容为数字 而我希望它把内容当文本来处理 期望的结果
  • 重构总结

    之前就听说 重构 改善既有代码的设计 这本书很经典 一直没有机会拜读 书中讲的都是很实用的重构小技术 很多人肯定都用过 看完之后还需要在工作中多多使用 下面总结了一下这本书的知识点 方便日后查看
  • linux进程间信号量通信IPC(sem)

    一 信号量 信号量是一种用于提供不同进程间或一个从给定进程的不同线程间同步手段的原语 1 1 Posix信号量的选择 1 单个进程的各个线程共享 可以使用基于内存的信号量 2 彼此无亲缘关系的不同进程需使用信号量时 通常使用有名信号量 1
  • STM32无线网络监控传感器数据

    介绍 在此项目中 我们将首先创建一个无线传感器节点 传感器节点由四个基本组件组成 例如传感单元 处理单元 收发器单元和电源单元 传感单元可以由任何传感器组成 我正在使用BME280气压传感器 处理单元是STM32F103C微控制器 收发器单
  • Python之格式化字符串小练

    格式化字符串 a 3 b 5 print str a str b str a b 对于字符串的拼接显示 称为格式化字符串 有两种方案 的方式 print s s s a b a b s表示字符串 d表示整数类型 f表示浮点型的整数 info
  • python列表的三种遍历方法(for循环,索引,下标)

    列表是python中使用频率非常高的数据类型 用方括号 定义 接下来介绍遍历列表常用的三种方法 1 直接遍历 list1 1 24 34 44 533 5 219 for item in list1 直接遍历 print item 2 按索
  • Linux内核之ICMPv6详解

    要知道什么是ICMPv6协议 我们首先要知道什么是ICMP ICMP是一种面向无连接的协议 负责传递可能需要注意的差错和控制报文 差错指示通信网络是否存在错误 如目的主机无法到达 IP路由器无法正常传输数据包等 注意 路由器缓冲区溢出导致的