ICMP (Internet Control Message Protocol)

  1. ICMP是TCP/IP协议集中的一个子协议,属于网络层协议, 主要用于在主机与路由器之间传递控制信息, 包括报告错误、交换受限控制和状态信息等。通过这些消息来对网络或主机的故障提供参考依据。
  2. 当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。

Ping 原理

术语描述:

利用网络上机器IP地址的唯一性,给目标IP地址发送一个数据包,再要求对方返回一个同样大小的数据包来确定两台网络机器是否连接相通,时延是多少。

举例说明:

  1. 两台主机A和B, 其中B的IP地址为192.168.0.7。
  2. 在A上运行 “ping 192.168.0.7”, 首先会构建固定格式的ICMP请求数据包, 由ICMP协议将这个数据包和B的IP地址传给IP层协议,IP层协议构造IP数据包,并得到B的MAC地址,一起传给数据链路层构建数据帧。
  3. B收到该数据帧,检查该数据帧的目的地址是够是自己的MAC地址,若不符合,丢弃;若符合,从数据帧中提起IP数据包,传给B的IP层协议;IP层进行相关检测,将ICMP数据包提取出来传给ICMP协议,ICMP协议构造应答包,用第2条相同方发给B。

获取B的MAC地址(物理地址)

  1. 同一网段

IP层协议通过本身的子网掩码和B的IP地址,检查是否属于同一网段。若在同一网段,直接在本网络内查找B的MAC地址。如果A和B曾经进行过通信,在A的ARP缓存表应该会有B的IP与MAC的映射。如果没有,则发ARP请求广播。

  1. 不同网段

IP层协议通过本身的子网掩码和B的IP地址,检查是否属于同一网段。若不在同一网段,则直接取路由的MAC地址。路由得到该数据帧,再跟B进行联系,若找不到,则给A发超时信息。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class IP(Structure):

_fields_ = [
("ihl", c_ubyte, 4),
("version", c_ubyte, 4),
("tos", c_ubyte),
("len", c_ushort),
("id", c_ushort),
("offset", c_ushort),
("ttl", c_ubyte),
("protocol_num", c_ubyte),
("sum", c_ushort),
("src", c_uint32),
("dst", c_uint32)
]

def __new__(cls, socket_buffer=None):
return cls.from_buffer_copy(socket_buffer)

def __init__(self, socket_buffer=None):
pass


class ICMP(Structure):

_fields_ = [
("type", c_ubyte),
("code", c_ubyte),
("checksum", c_ushort),
("unused", c_ushort),
("next_hop_mtu", c_ushort)
]

def __new__(cls, socket_buffer):
return cls.from_buffer_copy(socket_buffer)

def __init__(self, socket_buffer):
pass



Published with Hexo and Theme by Kael
X