Linux 内核源码分析---内核ICMP协议分析

news2024/11/27 8:46:08

因特网控制报文协议ICMP(Internet Control Message Protocol) 是一个差错报告机制,是TCP/IP协议簇中的一个重要子协议,通常被IP层或更高层协议(TCP或UDP)使用,属于网络层协议,主要用于在 IP 主机和路由器之间传递控制消息,用于报告主机是否可达、路由是否可用等。这些控制消息虽然并不传输用户数据,但是对于收集各种网络信息、诊断和排除各种网络故障以及用户数据的传递具有至关重要的作用。

为什么需要ICMP?
在数据传输的过程中,IP 提供尽力而为的服务,指为了把数据包发送到目的地址尽最大努力。它并不对目的主机是否收到数据包进行验证,无法进行流量控制和差错控制。因此在数据包传输过程中,产生各种错误在所难免。为了更有效地转发IP数据包和提高数据包交付成功的机会,ICMP应运而生。使用ICMP,当网络中数据包传输出现问题时,主机或设备就会向上层协议报告差错情况和提供有关异常情况的报告,使得上层协议能够通过自己的差错控制程序来判断通信是否正确,以进行流量控制和差错控制,从而保证服务质量。

Ping程序是最常见的用于检测IPv4和IPv6网络设备是否可达的调试手段,它使用ICMP的echo信息来确定:
(1)远程设备是否可达;
(2)与远程主机通信的来回旅程(round-trip)的延迟;
(3)报文包的丢失情况。

Tracert程序主要用于查看数据包从源端到目的端的路径信息,从而检查网络连接是否可用。当网络出现故障时,用户可以使用该命令定位故障点。它利用 ICMP 超时信息和目的不可达信息 来确定从一个主机到网络上其他主机的路由,并显示IP网络中每一跳的延迟(这里的延迟是指:分组从信息源发送到目的地所需的时间,延迟也分为许多的种类——传播延迟、传输延迟、处理延迟、排队延迟等);

ICMP4 消息

ICMP 主要用作发送有关网络层(L3)错误和控制消息的机制,让你能够通过发送 ICMP 消息来获取有关通信环境中问题的反馈。

ICMPV4 消息分两类:错误消息和信息消息(查询消息)。
ICMPv4 被用于 ping 和 traceroute 等诊断工具。
ICMPv4 初始操作是在引导阶段调用 inet_init() 中完成,具体如下

在这里插入图片描述
在这里插入图片描述

ICMPv4 报头:由类型(8位)、代码(8位)、检验和(16位)和32位的可变部分组成,ICMPv4报头用结构 icmphdr 表示如下
在这里插入图片描述

ICMPv4 数据报不超过 576 字节的前提下,有效载荷应尽可能多地包含原始数据报的内容。长度为 576 字节是根据 RFC 791 确定的,它指出所有主机都必须能够接收长达 576 字节的数据报。
在这里插入图片描述
在这里插入图片描述

接收 ICMPv4 消息:方法 ip_local_deliver_finish() 处理目的地为当前机器的数据包。收到ICMP数据包后,此方法便将其交给注册 ICMPv4 协议的原始套接字。在方法 icmprcv() 中进行处理。
在这里插入图片描述
在这里插入图片描述

引入 ICMP 套接字后,ping 的发送方可以不是原始套接字。比如:我们也可以创建一个套接字socket(PF_INET, SOCK_DGRAM, PROT_ICMP),并使用它来发送 ping 数据包。

如果数据包为广播或组播方式,且为ICMP_ECHOICMP_TIMESTAMP消息,将读取变量来核实广播/组播回答请求是否被允许。收到 ping (消息类型为:回应请求即ICMP_ECHO)时,将由方法icmp_echo()进行处理。
在这里插入图片描述

发送 ICMPv4 消息
用于发送 ICMPv4 消息的方法有两个:一是方法 icmp_reply(),用于发送两种 ICMP 请求的响应(被动)(ICMP_ECHOICMP_TIMESTAMP);二是方法 icmp_send(),用于发送当前机器在特定条件下主动发送的 ICMPv4 消息。这两个方法最终都调用icmp_push_reply()来执行实际发送数据包的工作。

在这里插入图片描述

在这里插入图片描述

ICMP_PROT_UNREACH(协议不可达)

IP报头的协议字段(长8位)指定的协议不存在时,将向发送方发送一条 ICMP_DEST_UNREACH/ICMP_PROT_UNREACH 消息,因为没有针对指定协议的协议处理程序(协议处理程序数组将协议号用作索引,因此对于不存在的协议,没有相应的处理程序。

所谓不存在的协议,指的是下面两种情形之一:
(1)Pv4报头中的协议号是错误的,没有包含在协议号列表中(该列表可在include/uapi/linux/in.h中找到);
(2)内核不支持该协议,因此该协议没有注册,协议处理程序数组中没有相应的条目。
由于这样的数据包无法处理,因此需要向发送方发回 ICMPv4 目的地不可达消息。这种应答中的代码 ICMP_PROT_UNREACH 指出了导致错误的原因——“协议不可达”。

ICMP_PORT_UNREACH(端口不可达)

接收 UDPv4 数据包时,将查找匹配的 UDP 套接字。如果没有找到匹配的套接字,将检查校验和是否正确。如果不正确,就将数据包默默地丢弃;如果正确,就更新统计信息,并返回一条 ICMP “目的地不可达”/“端口不可达” 消息。

ICMP_FRAG_NEEDED(需要分片)

转发数据包时,如果其长度超过了外出链路的 MTU,且在IPv4报头(IP_DF)中没有设置分段( DF )位,将把数据包丢弃,并向发送方发回一条代码为 ICMP_FRAG_NEEDEDICMP_DEST_UNREACH 消息。

ICMP_SR_FAILED(目的不可达)

转发数据包时,如果其严格路由选择(strict routing)和网关(gatewaying)选项被设置,将把数据包丢弃,并发回一条代码为 ICMP_SR_FAILED 的“目的地不可达”消息。

方法 icmp_reply()icmp_send() 都支持速率限制,它们调用 icmpv4_xrlim_allow() 如果速率限制检查允许发送当前数据包(icmpv4_xrlim_allow()返回true),它们就发送该数据包。
在如下情况不会进行速率限制检查:消息的类型未知、数据包为PMTU发现数据包、设备为环回设备、ICMP类型在速率掩码中未指定。

ICMP6 消息

ICMPv6 是 IPv6 的有机组成部分,每个结点都必须全面实现。
在 IPv6 中,ICMPv6 除用于错误处理和诊断外,还被用于领居发现(ND)协议以组播侦听者发现(MLD)协议。【IPv4 和 IPv6 中的 ICMP(IPv6中的 MLD 和 ND 协议分别对应于 IPv4 中的 IGMP 的 ARP 协议】

互联网组管理协议(英语:Internet Group Management Protocol,缩写:IGMP)是用于管理网路协议多播组成员的一种通信协议。 IP主机和相邻的路由器利用 IGMP 来建立多播组的组成员。 像ICMP用于单播连接一样,IGMP也是IP多播说明的一个完整部分。

在这里插入图片描述

ICMPv6 和 ICMPv4基本差不多,也为每个 CPU 都创建一个原始 ICMPv6 套接字,并将它们存储在一个数组中,要访问当前 sk,可调用方法icmpv6_sk()

ICMPv6 初始化是由方法 icmpv6_init()icmp_sk_init() 完成。

ICMPv6 报头:由类型字段(8位)、代码字段(8位)和检验和字段(16位)组成。

+0-------7-------15---------------31
| Type   | Code  |    Checksum    |
+----------------------------------
|             Reserved            |
+----------------------------------
|          Target Address         |
+----------------------------------
|        Destination Address      |
+----------------------------------
|             Options...          |
+---------------------------------+

ICMPv6 报头用结构 icmphdr 表示:

在这里插入图片描述
“类型”字段为最高位为0(此字段取值范围0-127)时,表示为错误消息;为1(此字段取值为128-255)时,表示为信息消息。
在这里插入图片描述

接收 ICMPv6 消息:收到的 ICMPv6 数据包被交给方法 icmpv6_rcv()

在这里插入图片描述

发送ICMPv6消息:发送 ICMPv6 消息的主方法为 icmpv6_send()

发送ICMPv6“跳数限制超时”消息:每台机器转发数据包时都将跳数限制计数器减1,跳数限制计数器是 IPv6 报头的一个成员,相当于 IPv4 中的存活时间。跳数限制计数器变成 0 后,将调用方法icmpv6_send()发送一条代码为ICMPV6_EXC_HOPLIMITICMPv6_TIME_EXCEED消息,之后再更新统计消息,并将数据包丢弃。

发送ICMPv6“分段重组超时”消息:分段超时时,将调用方法icmpv6_send()发回一条代码为ICMPV6_EXC_FRAGTIMEICMPV6_TIME_EXCEED消息。

发送ICMPv6“参数问题”消息:在分析扩展报头遇到问题时,将发回一条代码为ICMPV6_UNK_OPTIONICMPV6_PARAMPROB 消息。

https://info.support.huawei.com/info-finder/encyclopedia/zh/ICMP.html

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

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

相关文章

论文阅读-Transformer Layers as Painters

1. 摘要 尽管大语言模型现在已经被广泛的应用于各种任务,但是目前对其并没有一个很好的认知。为了弄清楚删除和重组预训练模型不同层的影响,本文设计了一系列的实验。通过实验表明,预训练语言模型中的lower和final layers与中间层分布不一致…

四路一体行车记录仪,语音提示注意行人,保障车辆行驶安全

在叉车、货车、客车等行业中,随着运输业务量的不断增加,行车安全问题已经成为了一大难题。经常会发生车祸、司乘人身安全无保障、货物损失等意外情况,这些事件不仅会给企业带来经济损失,也会影响对应行业的整体形象。 如何提高运…

服装行业的利器:RFID智能吊挂分拣系统

服装行业的利器:RFID智能吊挂分拣系统 服装业继续走粗放型老路的利润空间越来越小,行业内过度竞争利润降低,原料价格上涨导致成本上升。企业内部生产技术创新不足、工厂生产效率低,导致产出不够、货期竞争乏力。企业为了盈利生存…

C++中STL的sring类常用接口及其源码解析

1. 为什么会有string类? C语言中的字符串 C语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想&#xff0…

VS2022快速搭建OLLVM

基本参考这篇文章: 构建含有ollvm功能的LLVM(clang-cl)供Microsoft Visual Studio 2022使用 - 哔哩哔哩 前提 已安装VS2022 1.VS开启Clang支持 我们要用自己的Clang,所以无需安装VS提供的clang编译器,而且体积太大了,10多个G&…

Jmeter基础与概念详解

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 JMeter 介绍: 一个非常优秀的开源的性能测试工具。 优点:你用着用着就会发现它的重多优点,当然不足点也会呈现出来。 从性能…

c++模板进阶——模板特化和模板分离编译

目录 前言: 1. 非类型模板参数 2. 模板的特化 2.1 概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 2.3.3 类模板特化应用示例 3 模板分离编译 3.1 什么是分离编译 3.2 模板的分离编译 3.3 解决方法 4. 模板的优缺点 前言&#xf…

Zotero 常用插件介绍

1. Zotero 插件安装方法 下载以 .xpi 结尾的插件;打开 Zotero → 工具 → 插件 → 右上小齿轮图标 → Install Add-on From File ... → 选择下载好的 .xpi 插件安装 → 重启 Zotero 2. 常用插件介绍 2.1. Scholaread - 靠岸学术 Zotero 英文文献相关插件&#xf…

Spring中使用JdbcTemplate访问数据库

首先在原来的基础上添加jar包&#xff0c;建一个测试数据库pring5&#xff0c;里边新建两个表users&#xff0c;authorities&#xff0c;user_authority&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc<…

目标检测之数据增强

一、概述 数据增强是一种通过人工或自动方式对数据进行修改或变换&#xff0c;以增加数据集规模和多样性的技术。在机器学习中&#xff0c;数据增强被广泛应用于解决数据稀缺、数据不平衡、数据噪声等问题&#xff0c;提高模型的泛化能力和鲁棒性。 二、为什么需要数据增强 …

JAVA智慧养老护理帮忙代办陪诊陪护系统小程序源码

&#x1f475;&#x1f3fc;&#x1f496;科技温暖夕阳红 —— 探索“智慧养老护理帮忙代办陪诊陪护系统” 一、引言&#xff1a;科技如何温柔拥抱银发族&#xff1f; 在快节奏的现代生活中&#xff0c;如何给予家中长辈更周全的关怀与照顾&#xff0c;成为了许多家庭面临的难…

Unity 编写自己的aar库,并通过AndroidJavaProxy调用访问和返回

安卓部分 我们首先创建一个空项目&#xff0c;我们不需要Activity&#xff0c;所以可以选择NoActivity。 输入一个包名&#xff0c;我们用不到这个主app包名。 项目创建好后&#xff0c;再创建新Module 左边我们选择AndroidLibrary&#xff0c;然后输入包名&#xff0c;这个…

如果使用finalshell登录linux服务器之后,上传文件失败,可能是没有使用sudo权限

先随便使用sudo命令拷贝一个文件到另外一个地方&#xff0c;然后输入密码&#xff0c;再次上传就可以了 例如&#xff1a; sudo cp index.html eventWeb/ 会提示你输入密码&#xff0c;输入之后&#xff0c;再次使用finalshell上传文件就可以了&#xff1a;

MQ的介绍

一、MQ简介 MQ是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信&#xff0c;主要功能是业务解耦 二、常见的MQ产品 RabbitMQ、RocketMQ、Kafka、ActiveMQ 三、为什么要用MQ&#xff1f;&#xff08;MQ的优点&#xff1a;异步处理、应用解耦、流量削峰&a…

前端 获取时间范围内的所有周数组集合,第一项为首月的首个周一

具体可实现的效果例如&#xff1a; 数据格式&#xff1a; 具体代码实现&#xff1a; /*** 获取当前日期的第一个周一是哪天* params date - YYYY-MM*/function getMonthFirstWeekDay(date) {let year new Date(date).getFullYear();let month new Date(date).getMonth();for …

linux:有关目录、链接文件的函数 Makefil、gdb的使用

目录函数 1.getpwuid struct passwd *getpwuid(uid_t uid); 功能: 根据用户id到/etc/passwd文件下解析获得 结构体信息 参数:uid:用户id 返回值: 成功返回id对应用户的信息 失败返回NULL passwd 结构体的定义通常如下所示 struct passwd { char *pw_nam…

opencv-特征检测

1&#xff0c;Harris角点检测 如果粉色窗口向四周移动&#xff0c;窗口内的像素没有变化则认定为平坦区域&#xff0c;如果窗口向上移动无明显变化&#xff0c;而左右移动有变化则认定为边缘&#xff0c;如果窗口向任意方向移动均有明显变化则为角点&#xff0c;如下图 dst不是…

MSSQL暴力破解

一、基本信息 靶机&#xff1a;IP&#xff1a;192.168.100.70 二、攻击过程 方法一&#xff1a;msfconsole 启动 msfconsole msfconsole 选用攻击模块&#xff0c;并设置参数 use auxiliary/scanner/mssql/mssql_login set rhosts 192.168.100.70 set USER_FILE /userna…

探舟数字与周村古商城景区携手签署AI导游导览合作协议

导语&#xff1a; 近日&#xff0c;国内领先的科技公司广州探舟数字科技有限公司&#xff08;以下简称探舟数字&#xff09;与国家5A级景区创建单位、国家级夜间文化和旅游消费集聚区山东周村古商城正式签署合作协议&#xff0c;共同推进AI导游导览系统的全面应用。此次合作标…

【Java数据结构】---List(ArrayList)

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录 前言线性表顺序表&#x…