ICMP协议报文

1、CMP协议简介


ICMP(Internet Control Message Protocol)是一种网络协议,它用于在IP网络中传递控制信息和错误消息。它通常与IP协议一起使用,IP协议负责发送和路由数据包,而ICMP协议负责检查网络是否可达、路由是否正确、主机是否可达等网络状态的反馈信息。

2、ICMP协议的主要功能

发现网络错误:当一个数据包在传输过程中出现错误时,ICMP协议通过向发送方发送错误通知来发现网络错误。

检查网络是否可达:通过发送ICMP ECHO请求并接收ICMP ECHO回复消息,可以确定目标主机是否可达。

发现主机错误:当一个主机无法正常工作时,ICMP协议通过向发送方发送错误通知来发现主机错误。

发送路由信息:ICMP协议可以向其他主机发送路由信息,以帮助它们在网络中找到合适的路由。


3、CMP报文格式


3.1、 ICMP报文以太网数据帧格式 

 ICMP报文属于IP子协议,协议号为1。

3.2、 ICMP首部格式

 

 

其中各字段的含义如下:

类型(Type):指定 ICMP 报文的类型,占 1 个字节。常见类型有:回显应答(Echo Reply:0)、回显请求(Echo Request:8)等。

代码(Code):指定 ICMP 报文的代码,占 1 个字节。用于进一步描述 ICMP 报文,与 Type 字段组合使用。

校验和(Checksum):校验和,用于检查 ICMP 报文是否有损坏,占 2 个字节。

由类型决定的4字节:根据类型不一样,4字节表达的意思不一样。

数据(Data):数据,可变长度。可以是任意数据,长度由具体的 ICMP 报文类型和代码决定。
 

3.3、 ICMP报文类型列表

 

常见的ICMP报文类型:

Echo Reply(回显应答):用于回复Echo Request(回显请求)报文,通常用于测试网络连接是否正常。

Destination Unreachable(目的地不可达):用于指示主机或路由器无法到达目的地或某个网络服务不可用。

Source Quench(源站抑制):当接收方无法处理所有传入的数据报时,源站抑制报文会发送到发送方,以通知其减慢数据传输速度。

Redirect(重定向):用于通知发送方,其正在使用的路由不再是最佳路由,建议使用另一条路由。

Echo Request(回显请求):用于测试测试网络连接是否正常。

Time Exceeded(时间超时):用于指示一个数据包在传输过程中被丢弃,原因是数据包在经过路由器时超过了其生存时间。

Parameter Problem(参数问题):用于指示数据包头部中存在错误的参数或选项,导致数据包无法被识别或处理。

Timestamp Request/Reply(时间戳请求/应答):用于向另一个主机请求当前时间戳,并将其返回给请求方。

Information Request/Reply(信息请求/应答):用于向另一个主机请求特定信息,并将其返回给请求方。

Address Mask Request/Reply(地址掩码请求/应答):用于请求另一个主机的网络掩码,并将其返回给请求方。

4、ICMP校验和计算


ICMP校验和计算的校验数据为整个ICMP数据包。

4.1 、ICMP校验和计算


a.校验数据以16bit为单位进行累加求和,校验数据需为偶数字节,奇数字节末尾填充0变为偶数字节。

b.如果累加和超过16bit,产生了进位,需将高16bit和低16bit累加求和。

c.循环步骤2,直至未产生进位为止。

d.累加和取反得到校验和。

4.2、 ICMP校验和验证


a.校验数据16bit为单位进行累加求和,校验数据需为偶数字节,奇数字节末尾填充0变为偶数字节。

b.如果累加和超过16bit,产生了进位,需将高16bit和低16bit累加求和。

c.循环步骤2,直至未产生进位为止。

d.累加和和校验和相加得到0xffff,校验成功,否则失败。


5、ICMP编程示例

5.1、发送回显请求

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>#define PACKET_SIZE 4096
#define ICMP_PACKET_SIZE 28uint16_t checksum(uint16_t *buf, int len)
{unsigned long sum = 0;while (len > 1) {sum += *buf++;len -= 2;}if (len == 1) {sum += *(unsigned char *)buf;}sum = (sum >> 16) + (sum & 0xffff);sum += (sum >> 16);return ~sum;
}int main(int argc, char *argv[])
{if (argc != 2) {printf("Usage: %s <destination_ip>\n", argv[0]);return -1;}char buf[PACKET_SIZE] = {0};memset(buf, 0, sizeof(buf));int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (sockfd < 0) {perror("socket error");return -1;}struct sockaddr_in dest_addr;memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.sin_family = AF_INET;dest_addr.sin_addr.s_addr = inet_addr(argv[1]);uint16_t seq = 0;while(1) {memset(buf, 0, PACKET_SIZE);struct icmp *icmp_packet = (struct icmp *)buf;icmp_packet->icmp_type = ICMP_ECHO;icmp_packet->icmp_code = 0;icmp_packet->icmp_id = 0;icmp_packet->icmp_seq = seq++;memset(icmp_packet->icmp_data, 0, ICMP_PACKET_SIZE);icmp_packet->icmp_cksum = 0;icmp_packet->icmp_cksum = checksum((uint16_t *)icmp_packet, ICMP_PACKET_SIZE);printf("icmp_packet size:%lu\n", sizeof(struct icmp));int sent_bytes = sendto(sockfd, buf, sizeof(struct icmp), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));if (sent_bytes <= 0) {perror("sendto error");break;}printf("sent icmp request:%d bytes to:%s\n", sent_bytes, argv[1]);int recv_bytes = recv(sockfd, buf, PACKET_SIZE, 0);if (recv_bytes <= 0) {perror("recv");break;}struct iphdr *ip_packet = (struct iphdr *)buf;struct icmp *icmp_reply = (struct icmp *)(buf + (ip_packet->ihl << 2));printf("recv icmp reply:%d from:%s\n", recv_bytes, inet_ntoa(dest_addr.sin_addr));printf("icmp type:%d,code:%d\n", icmp_reply->icmp_type, icmp_reply->icmp_code);sleep(1);}close(sockfd);return 0;
}

5.2、发送回显应答

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <linux/in.h>
#include <arpa/inet.h>#define IP_HDRLEN (20)
#define PACKET_SIZE (4096)uint16_t checksum(uint16_t *buf, int len)
{unsigned long sum = 0;while (len > 1) {sum += *buf++;len -= 2;}if (len == 1) {sum += *(unsigned char *)buf;}sum = (sum >> 16) + (sum & 0xffff);sum += (sum >> 16);return ~sum;
}uint16_t checksum_nofold(uint16_t *buf, int len)
{unsigned long sum = 0;while (len > 1) {sum += *buf++;len -= 2;}if (len == 1) {sum += *(unsigned char *)buf;}sum = (sum >> 16) + (sum & 0xffff);sum += (sum >> 16);return sum;
}bool parse_pack(char *buf, uint32_t len) {struct icmp *icmp_packet = (struct icmp *)buf;uint16_t csum = checksum_nofold((uint16_t *)buf, len);printf("icmp csum:0x%04x\n", csum);return csum == 0xffff;
}int main(int argc , char *argv[]) {int sockfd;int ret;char send_buf[PACKET_SIZE] = {0};char recv_buf[PACKET_SIZE] = {0};sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (sockfd == -1) {perror("socket error");return -1;}while(1) {struct sockaddr_in peer;socklen_t peerlen = sizeof(peer);memset(recv_buf, 0, PACKET_SIZE);ret = recvfrom(sockfd, recv_buf, PACKET_SIZE, 0, (struct sockaddr *)&peer, &peerlen);if (ret <= 0) {printf("ret:%d, errno:%d(%s)\n", ret, errno, strerror(errno));} else {printf("recv len:%d, peer src:port->%s:%d\n", ret, inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));bool bret = parse_pack(recv_buf, ret);if (bret) {struct icmp *recv_icmp = (struct icmp *)(recv_buf + sizeof(struct iphdr));memset(send_buf, 0, PACKET_SIZE);struct icmp *icmp_packet = (struct icmp *)send_buf;icmp_packet->icmp_type = ICMP_ECHOREPLY;icmp_packet->icmp_code = 0;icmp_packet->icmp_id = 0;icmp_packet->icmp_seq = recv_icmp->icmp_seq;memset(icmp_packet->icmp_data, 0, sizeof(struct icmp));icmp_packet->icmp_cksum = 0;icmp_packet->icmp_cksum = checksum((uint16_t *)icmp_packet, sizeof(struct icmp));int sent_bytes = sendto(sockfd, send_buf, sizeof(struct icmp), 0, (struct sockaddr *)&peer, sizeof(peer));if (sent_bytes <= 0) {perror("sendto error");break;}}}}close(sockfd);return 0;
}

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

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

相关文章

【设计模式——学习笔记】23种设计模式——备忘录模式Memento(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 游戏角色有攻击力和防御力&#xff0c;在大战Boss前保存自身的状态(攻击力和防御力)&#xff0c;当大战Boss后攻击力和防御力下降&#xff0c;可以从备忘录对象恢复到大战前的状态 传统设计方案 针对每一种角色&#xff0c;设计一个类来存储该角色的状态 【分析】…

vuejs 设计与实现 - 渲染器的设计

渲染器与响应式系统的结合 本节&#xff0c;我们暂时将渲染器限定在 DOM 平台。既然渲染器用来渲染真实 DOM 元素&#xff0c;那么严格来说&#xff0c;下面的函数就是一个合格的渲染器: // 渲染器&#xff1a; function renderer(domString, container) {container.innerHTM…

用js快速生成一个简单的css原子库 例如: .mr-18 .pl-18

第三方css原子库的缺点 比如 tailwindcss&#xff0c;有学习成本最开始写的时候效率可能还没有我们自己手写效率高&#xff0c;需要配置&#xff0c;会有原始样式被覆盖的问题&#xff1b;总之就是一个字重 自己搓的优点 学习成本低灵活不会有副作用 <!DOCTYPE html>…

Linux 终端操作命令(2)内部命令

Linux 终端操作命令 也称Shell命令&#xff0c;是用户与操作系统内核进行交互的命令解释器&#xff0c;它接收用户输入的命令并将其传递给操作系统进行执行&#xff0c;可分为内部命令和外部命令。内部命令是Shell程序的一部分&#xff0c;而外部命令是独立于Shell的可执行程序…

Kafka API与SpringBoot调用

文章目录 首先需要命令行创建一个名为cities的主题&#xff0c;并且创建该主题的订阅者。 1、使用Kafka原生API1.1、创建spring工程1.2、创建发布者1.3、对生产者的优化1.4、批量发送消息1.5、创建消费者组1.6 消费者同步手动提交1.7、消费者异步手动提交1.8、消费者同异步手动…

Qt与电脑管家2

1.竖线的添加与样式的修改&#xff1a; color: rgb(238, 238, 238); 2. 通过修改之前的自定义btn类代码&#xff0c;可以比较容易地创造出各种各样的按钮类 头像的样式表代码&#xff1a; QPushButton{ border-image: url(:/images_up/icon.jpg); border-radius:20px; } QPu…

Expo项目 使用Native base UI库

装包&#xff1a; yarn add native-base expo install react-native-svg12.1.1 Index.js: import React from react import { View, Text } from react-native import useList from ./useList import { NativeBaseProvider, Button, Box } from native-base import styles f…

ArcGIS Pro技术应用(暨基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合)

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

Spannable配合AnimationDrawable实现TextView中展示Gif图片

辣的原理解释&#xff0c;反正大家也不爱看&#xff0c;所以直接上代码了 长这样&#xff0c;下面两个图是gif&#xff0c;会动的。 package com.example.myapplication;import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable…

[静态时序分析简明教程(九)]多周期路径set_multicycle_path

静态时序分析简明教程-多周期路径 一、写在前面1.1 快速导航链接 二、多周期路径2.1 多周期路径的SDC命令2.2 路径常规约束2.3 建立/保持规格2.4 位移量2.5 多时钟周期案例 三、总结 一、写在前面 一个数字芯片工程师的核心竞争力是什么&#xff1f;不同的工程师可能给出不同的…

山景DSP芯片可烧录AP8224C2音频处理器方案

AP8224C2高性能32位音频应用处理器AP82系列音频处理器是面向音频应用领域设计的新一代SoC平台产品&#xff0c;适用于传统音响系统、新兴的蓝牙或Wifi 无线音频产品、Sound Bar 和调音台等市场。该处理器在总体架构和系统组成上&#xff0c;充分考虑了音频领域的特点&#xff0…

MYSQL幻读问题

幻读是什么&#xff1f; “Phantom Problem是指在同一事务下&#xff0c;连续执行两次同样的SQL语句可能导致不同的结果&#xff0c;第二次的SQL语句可能会返回之前不存在的行。”摘录来自 MySQL技术内幕&#xff1a;InnoDB存储引擎(第2版) (数据库技术丛书) ​ 通俗来说就是&a…

【积水成渊】9 个CSS 伪元素

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人_python人工智能视觉&#xff08;opencv&#xff09;从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了&#xff1a; https://blog.csdn.net/lbcy…

Jupyter Notebook 500 : Internal Server Error

1. 这个问题的根本原因在于&#xff1a; pygments 包 版本过高。 安装pygments 2.6.1 2.jupyter版本如下 如果某个版本有冲突&#xff0c;卸载了重新安装一下就行。 安装命令&#xff1a; pip install pygments 2.6.1 -i https://pypi.tuna.tsinghua.edu.cn/simple 另外…

界面控件DevExpress WPF Chart组件——拥有超快的数据可视化库!

DevExpress WPF Chart组件拥有超大的可视化数据集&#xff0c;并提供交互式仪表板与高性能WPF图表库。DevExpress Charts提供了全面的2D / 3D图形集合&#xff0c;包括数十个UI定制和数据分析/数据挖掘选项。 PS&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助…

Mysql中插入数据,并返回自增主键的值

创建数据库和表使用 insert into 进行插入数据使用 RETURN_GENERATED_KEYS 进行返回插入的这条数据 具体方法如下&#xff1a; Testvoid addGetPk(){try{Statement stmt conn.createStatement();String sql String.format("insert into t_students values(null,%s,%s,%d…

「已解决」iframe 本地生效 但是在测试环境不生效问题

背景 我有一个表格中一列是个详情&#xff0c;这个详情可被点击&#xff0c;点击后弹出抽屉&#xff0c;抽屉里是后端传给我详情字段的值对应的 url 的 iframe 展示。 问题是&#xff0c;在本地 localhost 下运行&#xff0c;ifame 运行正常&#xff0c;但是部署到测试环境就看…

王道机组难题分析

第四章 指令系统 大端方式&#xff1a;就是高地址存放高位&#xff0c; LSB的意思是&#xff1a;全称为Least Significant Bit&#xff0c;在二进制数中意为最低有效位 MSB的意思是&#xff1a;全称为Most Significant Bit&#xff0c;在二进制数中属于最高有效位 操作数可以理…

JavaWeb-Servlet服务连接器(三)

目录 Response响应对象 1.基本功能 2.重定向 3.路径 4.服务器输出数据到浏览器 Response响应对象 1.基本功能 设置响应行&#xff1a;格式为 HTTP/1.1 200 OK&#xff0c;可以使用 setStatus(int sc) 方法设置状态码为 200 表示成功。 方法名称描述setStatus(int sc)设…

docker下载和案例

文章目录 Docker安装一,根据官方文档安装二,根据我以下方式 Docker配置错误导致漏洞一,CRLF注入漏洞介绍在nginx中该漏洞例子解决方法 目录穿越漏洞介绍解决方法 Docker安装 一,根据官方文档安装 官方文档 二,根据我以下方式 docker安装要求&#xff1a; Docker要求Ce…