NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
ICMP

ICMP协议实现 更多...

struct  icmp_header
 ICMP头部结构定义 更多...
class  icmp_socket
 ICMP Socket类 更多...

详细描述

ICMP协议实现

提供了ICMP(Internet控制消息协议)Socket的实现, 支持Ping和Traceroute等网络诊断功能。

遵循的国际标准

本实现严格遵循以下网络诊断协议与相关标准规范:

ICMP 核心协议规范:

ICMP 扩展与更新:

ICMP 参数注册:

IPv4 协议标准:

ICMP 消息类型

根据 RFC 792 和 IANA 注册表,ICMP 消息类型分类如下:

类型值 名称 用途 本实现支持
0 Echo Reply Ping 响应
3 Destination Unreachable 目标不可达 -
5 Redirect 路由重定向 -
8 Echo Request Ping 请求
11 Time Exceeded TTL 超时(Traceroute 依赖)
13 Timestamp 时间戳请求 -
14 Timestamp Reply 时间戳响应 -

ICMP 头部格式

根据 RFC 792 §2,ICMP 头部由以下字段组成:

字段 大小 说明
Type 8 位 消息类型(0=Echo Reply, 8=Echo Request, 11=TTL Exceeded)
Code 8 位 消息子类型(通常为 0)
Checksum 16 位 整个 ICMP 消息的校验和(RFC 1071 算法)
ID 16 位 标识符,用于匹配请求和响应
Sequence 16 位 序列号,用于匹配请求和响应

**Echo Request/Reply 消息**(RFC 792 §3.2):

  • 数据部分可选,内容任意
  • 响应的标识符和序列号必须与请求匹配
  • 数据部分原样返回

**Time Exceeded 消息**(RFC 792 §3.3):

  • Code 0:TTL 在传输中耗尽
  • Code 1:分片重组超时
  • 包含原始数据包的 IP 头部和前 8 字节

校验和算法

根据 RFC 1071,ICMP 校验和计算步骤:

  1. 将校验和字段清零
  2. 将数据按 16 位字累加
  3. 将进位加到低 16 位
  4. 结果取反码

Ping 操作原理

Ping 使用 ICMP Echo Request/Reply 消息测试网络连通性:

**工作流程**:

  1. 发送方构造 ICMP Echo Request(Type=8),包含 ID 和序列号
  2. 目标主机收到后返回 ICMP Echo Reply(Type=0)
  3. 发送方根据 ID 和序列号匹配响应
  4. 计算往返时间(RTT = 接收时间 - 发送时间)

**测量指标**:

指标 说明
RTT 往返时间(毫秒)
Reply TTL 响应数据包的剩余 TTL 值
Reply Size 响应数据大小(字节)

Traceroute 操作原理

Traceroute 利用 IP TTL 和 ICMP Time Exceeded 探测网络路径:

**工作流程**:

  1. 发送 TTL=1 的 UDP 或 ICMP Echo Request 数据包
  2. 第一跳路由器丢弃数据包(TTL=0),返回 ICMP Time Exceeded(Type=11)
  3. 发送方从 Time Exceeded 消息中提取路由器 IP 地址
  4. 逐步增加 TTL(2, 3, ...),重复以上步骤
  5. 当数据包到达目标主机时,返回 ICMP Echo Reply(Type=0)或 UDP Port Unreachable

**跳点信息**:

字段 说明
address 该跳路由器的 IP 地址
rtt[3] 三次探测的往返时间
reached 是否已到达目标

使用示例

Ping 操作:

sock.open();
auto dest = ip_address::parse("8.8.8.8");
if (dest) {
auto result = sock.ping(*dest, milliseconds(2000));
if (result.success) {
println("{}: bytes={} time={}ms TTL={}",
dest->to_string(), result.reply_size,
result.rtt.count(), result.reply_ttl);
}
}
ICMP Socket类
ping_result ping(const ip_address &dest, milliseconds timeout, uint16_t sequence=0, const void *data=nullptr, size_t data_len=0)
执行Ping操作
void open()
打开ICMP socket
static optional< ip_address > parse(const string &host, ports port=ports{}) noexcept
从字符串解析IP地址
void println(Args &&... args)
打印多个值并换行
duration< int64_t, milli > milliseconds
毫秒持续时间

Traceroute 操作:

auto hops = sock.traceroute(*dest, 30, milliseconds(1000), 3);
for (size_t i = 0; i < hops.size(); ++i) {
println("{}: {} (reached={})", i + 1,
hops[i].address.is_valid() ? hops[i].address.to_string() : "*",
hops[i].reached);
}
vector< traceroute_hop > traceroute(const ip_address &dest, int max_hops=30, milliseconds probe_timeout=milliseconds(1000), int probes_per_hop=3)
执行Traceroute操作
注解
Ping 和 Traceroute 是网络诊断中最常用的工具, Ping 用于测试连通性和延迟,Traceroute 用于分析网络路径。
警告
原始套接字操作需要 root/管理员权限。 某些网络环境可能过滤 ICMP 数据包,导致 Ping/Traceroute 结果不准确。 Traceroute 的中间路由器可能不响应 ICMP Time Exceeded(显示为 *)。
参见
https://www.rfc-editor.org/rfc/rfc792.html
https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
https://en.wikipedia.org/wiki/Ping_(networking_utility)
https://en.wikipedia.org/wiki/Traceroute