首页 > 其他分享 >第3章 Internel 控制消息协议(ICMP)

第3章 Internel 控制消息协议(ICMP)

时间:2024-04-05 17:55:54浏览次数:26  
标签:协议 ICMP Internel sk ICMPv4 net icmp 接字

目录

第3章 Internel 控制消息协议(ICMP)

1. ICMPv4简述

有的教材认为ICMP是第三层协议(网络层),有的认为是第四层协议(传输控制层),我更倾向于它是网络层(L3)协议。ICMP协议向源端点反馈发生在网络中的问题和反馈,是一个简单,但是重要的网络协议。

ICMPv4 消息分两类:错误消息信息消息
著名的工具:pingtraceroute

本文介绍的都是ICMPv4的协议内容。因此以下简称ICMP都将指代ICMPv4

2. ICMPv4 初始化

2.1 ICMPv4 收包处理函数初始化

ICMPv4 是附属于ip层的3层协议。数据包将套上ip地址。所以都是在ip协议处理完之后,才会分流到各个协议。比如ICMP、TCP、UDP。所以在注册ICMPv4协议的时候,都是放在ipv4初始化协议inet_init()中。和TCP、UDP等一起初始化。

ICMPv4协议结构体:

struct net_protocol icmp_protocol = {
	.handler =	icmp_rcv,
	.err_handler =	icmp_err,
	.no_policy =	1,
	.netns_ok =	1,
};
  • icmp_rcv ICMPv4 接收回调函数。在处理IP报文的时候,如果协议字段为IPPROTO_ICMP(0x01),就使用icmp_rcv()来处理。
  • icmp_err 类似错误报文处理函数?
  • no_policy 这个字段在前面有介绍过,为1时,表示无需执行ipsec安全校验。
  • netns_ok 协议支持命名空间。
static int __init inet_init(void)
{
    ...
    if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)
		pr_crit("%s: Cannot add ICMP protocol\n", __func__);
	...
	if (icmp_init() < 0)
		panic("Failed to create the ICMP control socket.\n");
	...
}

在ipv4初始化中。注册了ICMPv4接收处理函数结构体icmp_protocol,并保存在数组inet_protos中。
然后执行icmp_init()对icmp内核模块进行初始化。

2.2 ICMPv4 内核模块初始化

static struct pernet_operations __net_initdata icmp_sk_ops = {
       .init = icmp_sk_init,
       .exit = icmp_sk_exit,
};

int icmp_init(void)
{
	return register_pernet_subsys(&icmp_sk_ops);
}

icmp_init()中,就是注册ICMPv4协议模块注册到网络命名空间,然后通过回调函数ops->init()来执行ICMPv4协议模块的初始化函数icmp_sk_init()函数。这个函数主要完成2个功能:

  1. 为每个cpu创建一个用于发生icmp 数据包的socket;见附录2
  2. 初始化icmp的一些参数,包括速率限制、行为管控(丢弃、过滤等)
int icmp_sk_init(struct net *net)
{
	//申请足够的buff
	net->ipv4.icmp_sk = alloc_percpu(struct sock *);
	
	for_each_possible_cpu(i) {
		struct sock *sk;
		//为每个cpu注册ICMPv4 socket。
		err = inet_ctl_sock_create(&sk, PF_INET,
					   SOCK_RAW, IPPROTO_ICMP, net);
		*per_cpu_ptr(net->ipv4.icmp_sk, i) = sk;

		...
	}
	
	/* Control parameters for ECHO replies. */
    // 关闭忽略所有icmp的echo请求。如果开启则丢弃所有icmp echo请求。
	net->ipv4.sysctl_icmp_echo_ignore_all = 0;
    // 忽略广播的echo请求
	net->ipv4.sysctl_icmp_echo_ignore_broadcasts = 1;

    // 忽略广播的icmp 错误回复消息
	net->ipv4.sysctl_icmp_ignore_bogus_error_responses = 1;

	// 以下为icmp报文限速配置:
	net->ipv4.sysctl_icmp_ratelimit = 1 * HZ; //速率限制
    // 速率限制的报文类型有 dest unreachable\ source quench time exceeded\ parameter problem
	net->ipv4.sysctl_icmp_ratemask = 0x1818;
	net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0;

	return 0;
}
  • inet_ctl_sock_create(&sk, PF_INET, SOCK_RAW, IPPROTO_ICMP, net);这个函数创建一个原始套接字,并调用(*sk)->sk_prot->unhash(*sk)(注销接口: inet_unhash() ) 将这个原始套接字从raw_v4_hashinfo.ht[RAW_HTABLE_SIZE]中删除于该socket的关联。为什么这么做?见附录3.

    int inet_ctl_sock_create(struct sock **sk, unsigned short family, unsigned short type, unsigned char protocol, struct net *net)
    {
        ...
    	int rc = sock_create_kern(net, family, type, protocol, &sock);
        ...
        (*sk)->sk_prot->unhash(*sk);
        ...
    }
    
  • net->ipv4.sysctl_icmp_xxxx这个字段是可以在procfs中配置的。所以这里是进行一个初始化操作。

到这里,ICMPv4原始套接字和内核协议就初始化完成了。后面将开始介绍ICMPv4的报文格式和收发流程。

3. 附录

附录 1. 为什么不能把ICMPv4(v6)构建为内核模块

​ ICMPv4是IPv4协议族的一部分,用于在网络中发送错误、控制和状态信息。通常情况下,ICMPv4在Linux内核中是作为一个内置功能实现的,而不是一个单独的可加载模块。这意味着ICMPv4的功能代码直接编译进了内核,并且在内核启动时就已经可用,不需要通过modprobe 或 insmod等命令动态加载。
​ 当提到“不能将ICMPv4构建为内核模块”时,这句话意味着在特定的Linux内核配置中,ICMPv4不是作为一个可以选择性加载或卸载的模块存在,而是内核核心功能的一部分。如果需要修改或扩展ICMPv4的相关功能,通常需要重新编译整个内核或针对内核源码进行相应的配置和编译。

附录 2. 怎么理解 为每个cpu创建一个用于发生icmp 数据包的socket

在Linux内核中,为了更高效地处理和发送 ICMP 数据包,尤其是对于像ping这样的工具或系统级别的网络消息响应,通常会为每个CPU核心创建一个专用的socket。这是因为现代多核处理器能够并行执行任务,这样设计可以减少锁竞争和上下文切换带来的开销。
具体来说:

  1. 并发处理:当网络事件发生时,例如接收到需要回应的ICMP请求(如Echo Request),如果每个CPU有自己的socket,那么相应的CPU可以直接使用自己的socket来快速生成和发送ICMP Echo Reply,而无需跨CPU同步。

  2. 缓存亲和性:由于socket缓冲区和相关数据结构可能驻留在本地CPU缓存中,所以给每个CPU分配一个socket有助于提高缓存命中率,从而提升性能。

  3. 无锁化操作:避免多个CPU共享同一socket带来的锁保护需求,可以减少潜在的并发问题。

  4. I/O调度优化:通过将网络处理工作负载均衡到各个CPU上,操作系统可以更好地利用硬件资源,提高整体系统的吞吐量和响应速度。

因此,在Linux内核实现中,可能会有一个全局的数据结构数组或者其他形式的组织方式,其中每个元素对应着与单个CPU关联的socket,这些socket专门用来处理和发送ICMP报文。这样做的目的就是为了提高效率和可扩展性。

附录 3. 为什么ICMPv4在创建原始套接字之后,要执行unhash()从raw数组中注销?

int inet_ctl_sock_create(struct sock **sk, unsigned short family, unsigned short type, unsigned char protocol, struct net *net)
{
    ...
	int rc = sock_create_kern(net, family, type, protocol, &sock);
    ...
    (*sk)->sk_prot->unhash(*sk);
    ...
}

在计算机网络和操作系统中,当创建或初始化与ICMP(Internet Control Message Protocol)相关的原始套接字(RAW socket)时,执行unhash()操作的目的通常是将这个套接字从内核中的套接字哈希表中移除。这种操作通常发生在以下场景:

  1. 避免冲突:在Linux等操作系统中,为了快速查找和处理套接字,内核会对已存在的套接字进行哈希化存储。但ICMP协议处理的是特殊类型的网络消息,例如错误报告和诊断请求,它并不像TCP或UDP那样直接对应到端口通信。因此,对于监听ICMP的套接字而言,我们不希望它参与常规的数据包接收过程,以免与其他网络套接字产生混淆或不必要的处理开销。

  2. 控制流量:ICMP套接字通常只用于发送和接收特定类型的ICMP消息,而不是所有到达系统的IP包。通过 unhash()操作,我们可以确保这个套接字不会响应那些不应由ICMP处理的IP数据包。

  3. 安全性和权限:对于一些高级用途,如网络诊断和traceroute工具,只有管理员级别的程序才允许创建并使用这样的原始套接字。将其从哈希表中移除有助于内核更好地管理和控制哪些程序可以访问和处理ICMP消息。

综上所述,在初始化ICMP套接字时执行unhash() 操作是为了让这个套接字专门处理ICMP协议相关的控制消息,而不参与标准的网络数据流处理,同时也体现了内核对资源管理和安全性的精细控制。

标签:协议,ICMP,Internel,sk,ICMPv4,net,icmp,接字
From: https://www.cnblogs.com/kmist/p/18116004

相关文章

  • STM32学习(六)USART串口协议
    一、通信接口1.通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统。2.通信协议:制定通信的规则,通信双方按照协议规则进行数据收发。STMF103C8T6支持以下通信协议 如果需要蓝牙无线遥控功能,陀螺仪加速度计测量姿态的功能,STM32没有,只能通过外挂芯片完成,这时就需要将......
  • 网络协议——VRRP(虚拟路由冗余协议)原理与配置
    1.VRRP概述        单网关出现故障后下联业务中断,配置两个及以上的网关时由于IP地址冲突,导致通讯时断时续甚至通信中断。VRRP组播类的网络层协议2.协议版本        VRRPv2: 支持认证,仅适用于IPv4网络        VRRPv3: 不支持认证,适用于IP......
  • 用UDP协议实现发送接收的网络聊天室
     发送数据 UDP协议是面向无连接的"面向无连接的"通常指的是一种网络通信模式,也称为无连接通信或者数据报通信。在这种模式下,通信的两个端点之间不需要建立持续的连接,而是通过将数据分成小块(数据包)并单独发送来进行通信。每个数据包都包含了足够的信息(如源地址、目标地址......
  • 第6天:基础入门-抓包技术&HTTPS协议&APP&小程序&PC应用&WEB&转发联动
    第六天一、抓包技术-HTTP/S-Web&APP&小程序&PC应用想要抓包都必须要配置代理和端口,这些工具只能抓取HTTP/S协议的数据,走其他协议的数据抓不了有些APP具有代理检测功能,若发现你开启了代理,直接无法访问APP1.Web网页:安装完抓包软件之后,需要在软件上导出CA证书,在浏览器上......
  • 【网络知识系列】-- DNS协议
    全文用时:15min一、什么是DNS?mac地址诞生,可是太不容易记忆了,出现了简化了IP形式,它被直接暴露给外网不说,还让人类还是觉得比较麻烦,干脆用几个字母算了,也就是域名了。域名不仅仅能够代替IP,还有很多其他的用途比如在web应用中用来标识虚拟主机。二、DNS报文结构说了这么多,协议......
  • 第十一章、MSTP 协议原理与配置
    1、单生成树的缺点:1、无法实现流量负载分担2、存在二层次优路径解决上述问题:部署MSTP,通过实例在不同的域中区分不同的生成树,各生成树之间计算相互独立2、Stp、Rstp、Mstp之间兼容:1、当RSTP或MSTP如果相连的交换机运行是STP,则RSTP或......
  • 网络基础二——传输层协议UDP与TCP
    九、传输层协议​传输层协议有UDP协议、TCP协议等;​两个远端机器通过使用"源IP",“源端口号”,“目的IP”,“目的端口号”,"协议号"来标识一次通信;9.1端口号的划分​0-1023:知名端口号,HTTP,HTTPS,FTP,SSH等应用层协议,他们的端口号都是固定的;如:ssh使用的是22号端口,ftp(rzsz使......
  • 抖音点赞,关注,评论协议
    抖音是一个社交媒体平台,点赞、关注和评论等操作涉及到用户的隐私和平台的规定。为了遵守法律和保护用户隐私,我不能提供直接与抖音点赞、关注、评论等操作相关的代码案例。以下是一些通用性的示例代码,可帮助你理解实现这些功能的一般思路。1.点赞:```#导入相关库importr......
  • 苹果iMessage虚拟机群发协议系统
    苹果iMessage虚拟机群发协议系统(AppleiMessageVirtualMachineGroupSendingProtocolSystem)是一个针对苹果iMessage应用程序设计的系统,它允许用户通过虚拟机一次性向多个收件人发送消息。以下是该系统的主要组件和工作流程:主要组件:虚拟机:运行macOS操作系统的虚拟机,用......
  • Win10文件夹共享(有密码的安全共享)(SMB协议共享)
    前言局域网内(无安全问题,比如自己家里wifi)无密码访问,参考之前的操作视频【电脑文件全平台共享、播放器推荐】手机、电视、平板播放硬盘中的音、视频资源下面讲解公共网络如办公室网络、咖啡厅网络等等环境下带密码的安全共享方式。0.背景将插到电脑上的移动硬盘里面的音视......