常用网络协议整理笔记(三) —ICMP协议

常用网络协议整理笔记(三) —ICMP协议文章索引 1 ICMP 协议定义和结构 2 ICMP 协议作用 3 ICMP 协议格式 4 ICMP 协议 PING TRACEROUTE 原理 5 代码示例一 定义和结构 1

大家好,欢迎来到IT知识分享网。

常用网络协议整理笔记(三) ---ICMP协议

文章索引:

1. ICMP协议定义和结构

2. ICMP协议作用

3. ICMP协议格式

4. ICMP协议/PING/TRACEROUTE原理

5. 代码示例


一、定义和结构:

1.定义:

ICMP:Internet Control Message Protocol,互联网控制报文协议,是TCP/IP协议族中的一个重要协议,主要用于IP主机和路由器之间传递控制信息和错误消息。

2.位置:

ICMP位于OSI参考模型的网络层(第三层),是IP协议的一部分。ICMP是一个面向消息的协议,它的消息嵌入在IP数据包中,由IP协议承载。

常用网络协议整理笔记(三) ---ICMP协议

3.特点:

1) ICMP协议不直接传输用户数据,但它们在确保用户数据正确、高效地传输过程中起着至关重要的作用,为网络的操作和管理提供支持。

2) ICMP报文没有特定的端口号,因为它不涉及传输层。

3) ICMP的主要作用是帮助诊断网络问题、报告通信中的错误、提供网络状态信息等。ICMP协议通过发送和接收控制消息,如网络是否通畅、主机是否可达、路由是否可用等信息帮助网络管理员维护网络的正常运行。


二、作用:

CMP的核心作用是用于网络通信中的错误报告和网络诊断。以下是ICMP的主要功能和作用:

1. 错误报告

ICMP帮助网络设备(如路由器和主机)检测和报告通信中的问题。常见的错误报告功能包括:

  • 目标不可达(Destination Unreachable)
    当目标主机、网络或端口不可达时,发送ICMP Destination Unreachable消息。
  • 超时(Time Exceeded)
    当IP数据包在网络中超过其生存时间(TTL,Time-to-Live)时,发送ICMP超时消息。
  • 重定向(Redirect)
    当路由器发现有更好的路由时,发送ICMP Redirect消息,通知主机更新其路由表。

2.网络诊断

ICMP协议被广泛用于网络诊断工具。两个最常见的工具是:

  • Ping
    Ping工具使用ICMP Echo Request和Echo Reply消息来测试目标主机是否可达,并测量往返时间(RTT)。
  • Traceroute
    Traceroute工具利用ICMP Time Exceeded消息来追踪数据包从源到目的地的路径。

3.网络状态信息

ICMP可以向主机提供网络状态信息,帮助主机调整其行为。例如:

  • 路由器可以发送ICMP Redirect消息,建议主机改变数据包的路由路径。
  • 网络中的设备可以使用ICMP来检测网络连通性和性能。

4.支持IPv6(ICMPv6)

在IPv6中,ICMP协议的作用被进一步扩展,成为ICMPv6协议。ICMPv6不仅用于错误报告和诊断,还负责IPv6的关键功能,例如邻居发现(Neighbor Discovery Protocol, NDP)和路由器通告。


三、ICMP协议格式:

1. 抓包工具和方法:

在Linux操作系统中,可以使用工具如Wireshark、tcpdump或者是直接使用命令行工具如tcpdump来捕获和分析ICMP数据包。

sudo tcpdump -i [interface] icmp -w icmp.pcap

其中:

— [interface]是要监控的网络接口,可以使用ifconfig命令查看系统的网络接口名称;

—icmp: 抓取的协议类型,用于过滤;

—icmp.pcap 为要保存的文件;

2.ICMP报文通用格式

常用网络协议整理笔记(三) ---ICMP协议

ICMP报文的格式可以分为两部分:ICMP头部和ICMP数据部分。不同类型的ICMP报文有不同的格式,但所有ICMP报文都包含一个基础的头部结构。

ICMP 消息的头部结构如下:

字段名称

长度

描述

Type

1 字节

ICMP消息类型。

Code

1 字节

ICMP消息代码。

Checksum

2 字节

校验和,确保ICMP报文的完整性。

Rest of Header

4 字节

不同类型的ICMP报文的其他信息。

—Type:指示 ICMP 消息的类型。不同类型的 ICMP 消息具有不同的功能;

—Code:表示该ICMP报文类型的具体子类型(每个ICMP类型都有若干个子类型)。例如,在类型3(Destination Unreachable)中,Code可以表示不同的子原因(如网络不可达、主机不可达等), ICMP协议主要通过 Type 和 Code 的组合,来标明具体的报文类型;

—Checksum:用于检测ICMP报文是否在传输过程中发生了错误。它是对ICMP报文头部和数据部分的校验和。

—Rest of Header:根据不同的ICMP类型,ICMP头部的结构有所不同。对于Echo Request/Echo Reply/ Timestamp Request/ Timestamp Reply消息,Rest of Header会包含标识符和序列号,其它类型不会包含标识符和序列号; 对于Destination Unreachable消息,Rest of Header包含原始IP数据报的前8字节。


2. ICMP报文类型分类:

ICMP报文根据其功能和用途可以分为两大类:差错报告报文和询问报文。

常用网络协议整理笔记(三) ---ICMP协议

1). 查询报文类型:用于诊断的查询消息;

① 显请求(Echo Request)和回显应答(Echo Reply):

主机 / 路由器 询问特定主机 , 目的主机收到该报文后 , 必须给源主机 发送 ICMP 回答报文 ; 目的是 测试该 目的主机是否可达 ;

这些类型的ICMP报文用于ping操作(主机可达性测试)。Echo请求(Type 8)由发送方发送,Echo回复(Type 0)由接收方回复。

常用网络协议整理笔记(三) ---ICMP协议

–类型: 回显请求:8; 回显应答:0

–代码:总是 0

常用网络协议整理笔记(三) ---ICMP协议

–标识符:通常用于匹配请求和应答消息

a.作用:标识符字段用于区分不同的 ICMP 回显请求。它通常用于在发送多个请求时,帮助发送方识别对应的应答。

b.应用场景:当一个主机发送多个 ping 请求到同一目标时,每个请求都可以使用相同的标识符。接收到的应答中会包含相同的标识符,发送方可以通过这个字段来匹配请求和应答。

例如,如果一个主机同时对多个目标进行 ping 测试,标识符可以帮助它区分来自不同目标的响应。

–序列号:用于标识消息的顺序。

a. 作用:序列号字段用于标识发送的 ICMP 回显请求的顺序。它通常从 1 开始,每发送一个请求就递增 1。

b. 应用场景:通过序列号,发送方可以跟踪已发送的请求,检测丢包情况以及计算往返时间。比如,如果发送了 5 个请求,序列号分别为 1 到 5,接收到的应答可以通过序列号来确认哪些请求成功返回,哪些请求可能丢失。

以下抓包可以看出id相同,但seq在不断的累加。

常用网络协议整理笔记(三) ---ICMP协议

其中标识符和序列号都有BE(大端)和LE(小端)两种不同的表示方法;

常用网络协议整理笔记(三) ---ICMP协议

—数据:回显消息体中的数据内容。


② 时间戳请求(Timestamp Request)和时间戳应答(Timestamp Reply) :

请求 主机 / 路由器 当前的日期 和 时间 ; 用于进行时钟同步 和 时间测量 ;

常用网络协议整理笔记(三) ---ICMP协议

ICMP时间戳响应的报文结构与时间戳请求报文相同,区别在于Type字段的值:

—Type:时间戳请求:13; 时间戳响应:14

—Code:固定为0,无特殊含义。

—Checksum:用于错误检测,计算整个ICMP报文的校验和。

—Identifier:用于标识请求和响应的唯一性,通常使用进程ID。

—Sequence Number:表示报文的序列号,通常从0开始递增。

—Originate Timestamp:发送请求报文的时间戳。

—Receive Timestamp:接收到请求报文的时间戳(在响应报文中设置)。

—Transmit Timestamp:响应报文发送的时间戳(在响应报文中设置)。


2). 差错报文类型:用于通知出错原因的错误消息;

常见的错误报文类型

类型值

名称

描述

3

Destination Unreachable(目标不可达)

当目标主机或网络不可达时发送此报文。

4

Source Quench(源抑制,已弃用)

通知源主机降低发送速率,避免网络拥塞(已被弃用)。

5

Redirect(重定向)

通知源主机有更好的路由路径。

11

Time Exceeded(时间超时)

当数据包的TTL(生存时间)字段减为0或分片重组超时时发送此报文。

12

Parameter Problem(参数问题)

当IP头部字段出错(如参数非法)时发送此报文。

① 终点不可达报文Destination Unreachable (Type 3) :

路由器 / 主机 不能交付数据报时 , 就会向源点 发送 终点不可达报文 ;

字段名称

长度

描述

Type

1 字节

3(Destination Unreachable)

Code

1 字节

0: 网络不可达
1: 主机不可达
2: 协议不可达
3: 端口不可达
4: 需要分片但设置了不分片标志(DF位)
5: 源路由失败

Checksum

2 字节

校验和

Rest of Header

4 字节

包含导致错误的原始IP数据报的前8字节

当路由器或目标主机无法到达目标时,会生成此报文。

常用网络协议整理笔记(三) ---ICMP协议


② 时间超过报文Time Exceeded (Type 11) :

当一个数据包在网络中循环超过规定的TTL(生存时间)值时,路由器会返回Time Exceeded消息。

字段名称

长度

描述

Type

1 字节

11(Time Exceeded)

Code

1 字节

0: 数据包的TTL减为0;
1: Fragment
Reassembly Timeout,数据包分片重组超时

Checksum

2 字节

校验和

Rest of Header

4 字节

包含导致错误的原始IP数据报的前8字节

常用于traceroute工具,通过逐步减少TTL值来发现数据包经过的路由器。


③ 参数问题报文 :

路由器 / 主机 收到的 数据报 首部 字段由错误值 , 丢弃该数据报 , 向源点发送 参数问题报文 ;

④ 改变路由报文(重定向,类型5) :

路由器 将 改变路由报文 发送给主机 , 让主机下次将数据报发送给另外的路由器 ; 又称为 “重定向报文”;

字段名称

长度

描述

Type

1 字节

5(redirect)

Code

1 字节

0: 重定向到网络;
1: 重定向到主机;
2: 重定向到网络和服务
3: 重定向到主机和服务

Checksum

2 字节

校验和

Rest of Header

4 字节

包含导致错误的原始IP数据报的前8字节

通常由路由器发送,通知源主机有更好的路由路径。


四、ICMP协议/PING/TRACEROUTE原理:

1.ICMP协议原理

ICMP 主要的功能包括:

1) 确认IP 包是否成功送达目标地址

2) 报告发送过程中IP包被丢弃的原因

3) 改善网络设置等;

在 IP 通信中如果某个IP 包因为某种原因未能达到目标地址,那么这个具体的原因将由 ICMP 负表通知。

常用网络协议整理笔记(三) ---ICMP协议

如上图例子,主机A向主机B发送了数据包,由于某种原因,途中的路由器2未能发现主机B的存在,这时,路由器2就会向主机A发送一个ICMP 目标不可达数据包,说明发往主机B的包未能成功。ICMP 的这种通知消息会使用IP 进行发送,

因此,从路由器2返回的ICMP 包会按照往常的路由控制先经过路由器1再转发给主机A。收到该 ICMP 包后,主机A则会解析 ICMP 的首部和数据域部分,从而得知具体发生问题的原因。


2.PING命令原理:

ping 是一个网络工具,用于测试网络连接的可达性。它通过发送 ICMP(Internet Control Message Protocol)回显请求消息到目标主机,并等待接收回显应答来工作。

1) ping 的工作流程如下:

a. 发送请求:当用户运行 ping 命令时,工具会创建一个 ICMP 回显请求数据包,并将其发送到指定的目标 IP 地址。

b. 接收应答:目标主机收到请求后,解析数据包并生成 ICMP 回显应答数据包,返回给源主机。

c. 计算延迟:源主机在收到应答后,计算从发送请求到接收应答所花费的时间,并显示给用户。

d. 统计信息:ping 还会统计成功发送和接收的请求数量、丢包率以及往返时间的最小、最大和平均值等信息。

以下为ping 过程中生成的抓包数据:

常用网络协议整理笔记(三) ---ICMP协议

2)ping使用场景和作用

· 网络故障排查:ping 是网络故障排查的基本工具,可以帮助用户判断目标主机是否在线。

· 延迟测量:通过测量往返时间,用户可以了解网络的延迟情况。

· 丢包检测:通过发送多个请求,用户可以检测到网络中是否存在丢包现象。


3. TRACEROUTE原理:

1)解释:

traceroute 命令利用ICMP 协议定位您的计算机和目标计算机之间的所有路由器。TTL 值可以反映数据包经过的路由器或网关的数量,通过操纵独立ICMP 呼叫报文的TTL 值和观察该报文被抛弃的返回信息,traceroute命令能够遍历到数据包传输路径上的所有路由器。

2)原理:

Traceroute 的基本工作原理基于 ICMP 协议的 TTL(Time to Live) 字段和 ICMP 超时(Time Exceeded)消息。实现原理如下:

a. 初始发送:Traceroute 向目标主机发送一个带有初始 TTL 值(例如 1)的数据包。TTL 值为 1 的数据包会在第一个路由器处被丢弃,并返回一个 ICMP “Time Exceeded” 消息。这个消息的源 IP 地址就是第一个经过的路由器的地址。

b. 逐步增加 TTL:然后 Traceroute 会再次发送数据包,但这次将 TTL 增加 1(TTL = 2)。数据包会经过第一个路由器并到达第二个路由器,然后在第二个路由器处被丢弃,并返回一个 ICMP “Time Exceeded” 消息,显示第二个路由器的 IP 地址。

c. 继续递增 TTL:Traceroute 继续递增 TTL 的值,直到数据包到达目标主机。每次通过一个新的路由器,Traceroute 都能记录到该路由器的 IP 地址及响应时间。

d. 到达目标:当数据包的 TTL 值足够大,数据包最终到达目标主机时,目标主机会发送一个 ICMP “Echo Reply” 消息(与 ping 的工作原理类似)回源主机,标志着 Traceroute 结束。

在 traceroute 工具中,默认的 TTL(Time to Live)值通常为 30。这意味着,traceroute 在发送数据包时,初始的 TTL 值设置为 30,每经过一个路由器(跳数)会减 1。当 TTL 减至 0 时,数据包被丢弃,并返回一个 ICMP “Time Exceeded” 消息,traceroute 通过这个机制来识别经过的每一个路由器。

用法如下:

traceroute -m 10 http://www.baidu.com 当经过10个路由后就会丢弃此包。

常用网络协议整理笔记(三) ---ICMP协议


五、代码示例:

以下是一个C语言程序示例,展示如何构建和发送ICMP时间戳请求报文,以及如何接收和解析响应报文。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <time.h> // 校验和计算函数 unsigned short checksum(void *b, int len) { unsigned short *buf = b; unsigned int sum = 0; unsigned short result; for (sum = 0; len > 1; len -= 2) { sum += *buf++; } if (len == 1) { sum += *(unsigned char *)buf; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); result = ~sum; return result; } // 获取当前时间戳(毫秒) unsigned int get_timestamp() { struct timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000; } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <Target IP>\n", argv[0]); exit(EXIT_FAILURE); } const char *target_ip = argv[1]; int sock; struct sockaddr_in addr; struct icmphdr icmp_msg; unsigned char buffer[1024]; unsigned int originate_time, receive_time, transmit_time; // 创建原始套接字 sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sock < 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } // 设置目标地址 memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(target_ip); // 构造ICMP时间戳请求消息 memset(&icmp_msg, 0, sizeof(icmp_msg)); icmp_msg.type = 13; // 时间戳请求 icmp_msg.code = 0; icmp_msg.un.echo.id = getpid(); // 使用进程ID作为标识符 icmp_msg.un.echo.sequence = 1; // 序列号 originate_time = get_timestamp(); // 获取当前时间戳 memcpy(buffer + sizeof(icmp_msg), &originate_time, sizeof(originate_time)); icmp_msg.checksum = checksum(&icmp_msg, sizeof(icmp_msg) + sizeof(originate_time)); // 发送ICMP报文 if (sendto(sock, &icmp_msg, sizeof(icmp_msg) + sizeof(originate_time), 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Send failed"); close(sock); exit(EXIT_FAILURE); } printf("ICMP Timestamp Request sent to %s\n", target_ip); // 接收ICMP响应 socklen_t addr_len = sizeof(addr); if (recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&addr, &addr_len) < 0) { perror("Receive failed"); close(sock); exit(EXIT_FAILURE); } // 解析ICMP响应 struct icmphdr *icmp_resp = (struct icmphdr *)(buffer + sizeof(struct iphdr)); if (icmp_resp->type == 14) { // 时间戳响应 memcpy(&originate_time, buffer + sizeof(struct iphdr) + sizeof(struct icmphdr), sizeof(originate_time)); memcpy(&receive_time, buffer + sizeof(struct iphdr) + sizeof(struct icmphdr) + sizeof(originate_time), sizeof(receive_time)); memcpy(&transmit_time, buffer + sizeof(struct iphdr) + sizeof(struct icmphdr) + sizeof(originate_time) + sizeof(receive_time), sizeof(transmit_time)); printf("ICMP Timestamp Response received:\n"); printf("Originate Timestamp: %u ms\n", ntohl(originate_time)); printf("Receive Timestamp: %u ms\n", ntohl(receive_time)); printf("Transmit Timestamp: %u ms\n", ntohl(transmit_time)); } else { printf("Unexpected ICMP response type: %d\n", icmp_resp->type); } close(sock); return 0; } 

代码说明:

1. 发送请求

    • 设置ICMP类型为13,表示时间戳请求。
    • 使用当前时间戳填充Originate Timestamp字段。
    • 使用sendto()函数发送构造的ICMP时间戳请求报文。

2. 接收响应

    • 使用recvfrom()函数接收ICMP响应报文。
    • 检查响应报文的类型是否为14(时间戳响应)。
    • 解析Originate TimestampReceive TimestampTransmit Timestamp字段。

3. 时间戳格式

    • 时间戳以毫秒为单位,表示当天自午夜以来的时间。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/169569.html

(0)
上一篇 2025-02-08 11:26
下一篇 2025-02-08 11:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信