ICMP协议与自动化ping实现
ICMP协议
全称为互联网控制消息协议(Internet Control Message Protocol,缩写:ICMP),它用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,使管理者可以对所发生的问题作出诊断。
ICMP 协议依靠IP协议来完成它的任务,它是IP协议的主要部分。它与传输协议(如TCP协议和UDP协议)显著不同:它一般不用于在两点间传输数据。它通常不由网络程序直接使用,除了ping和traceroute这两个特别的例子。
ICMP报文结构
报头
ICMP报头从IP报头的第160位开始(IP首部20字节)(除非使用了IP报头的可选部分)。
- Type - ICMP的类型,标识生成的错误报文;
- Code - 进一步划分ICMP的类型,该字段用来查找产生错误的原因.;例如,ICMP的目标不可达类型可以把这个位设为1至15等来表示不同的意思。
- Checksum - 校验码部分,这个字段包含有从ICMP报头和数据部分计算得来的,用于检查错误的数据,其中此校验码字段的值视为0。
- ID - 这个字段包含了ID值,在Echo Reply类型的消息中要返回这个字段。
- Sequence - 这个字段包含一个序号,同样要在Echo Reply类型的消息中要返回这个字段。
填充数据
填充的数据紧接在ICMP报头的后面(以8位为一组):
- Linux的"ping"工具填充的ICMP除了8个8位组的报头以外,默认情况下还另外填充数据使得总大小为64字节。
- Windows的"ping.exe"填充的ICMP除了8个8位组的报头以外,默认情况下还另外填充数据使得总大小为40字节。
报文类型
类型 | 代码 | 状态 | 描述 | 查询 | 差错 |
---|---|---|---|---|---|
0 - Echo Reply | 0 | 表示路由存在 | echo响应 (被程序ping使用) | ● | |
8 - 请求回显 | 0 | Echo请求 | ● |
PING
ping是一种计算机网上工具,用来测试数据包能否透过IP协议到达特定主机。ping的运作原理是向目标主机传出一个ICMP echo@要求数据包,并等待接收echo回应数据包。程序会按时间和成功响应的次数估算丢失数据包率(丢包率)和数据包往返时间(网络时延,Round-trip delay time)。
ping是用ICMP的"Echo request"(类别代码:8)和"Echo reply"(类别代码:0)消息来实现的。
自动化ping脚本(基于scapy实现)
使用scapy库实现
# 铸造数据包(host是目标IP,ttl可以使用默认值,id和seq可以不赋值),padding是填充字段
packet = IP(dst=host, ttl=64, id=1)/ICMP(id=100, seq=1)/b'padding'
# 发送数据包(等待时间2秒)
ping = sr1(packet, timeout=2, verbose=False)
# 是否有异常
if ping.type == 0 and ping.code == 0:
print '设备ping通'
else:
print '设备失联'
- 生产环境中,应该对单个目标IP多次尝试
- 同时,使用多线程或多进程对较多目标IP同时做ping测试。
- 最好在ping.type前增加try…except,因为有些时候异常报文中没有type或code字段。
scapy核心方法介绍
构造数据包
IP()/ICMP()/"TEST"
常见发送数据包方法
- send/sendp/sr/sr1/srp方法 发送数据包函数使用
- sr()函数:用来发送数据包和接收响应。该函数返回有回应的数据包和没有回应的数据包;该函数也算得上是scapy的核心了,他会返回两个列表数据,一个是answer list 另一个是unanswered list。
- 函数sr1():是sr()一个变种,只返回应答发送的分组(或分组集)。这两个函数发送的数据包必须是第3层数据包(IP,ARP等)。
- 注意:实际中,可能没有收到任何回复,结果为None。
- 函数SRP():位于第2层(以太网,802.3,等)。
- 函数send():在第三层工作
- 函数sendp():在第二层工作
>>> send(IP(dst="192.168.115.188")/ICMP()) send函数工作在第三层
.
Sent 1 packets.
>>> sendp(Ether()/IP(dst="192.168.115.188",ttl=(1,4)),iface="eth0")
....
Sent 4 packets.
>>> sendp("hello ,i am walfred ",iface="eth0",loop=1,inter=0.2)
sendp函数工作在第二层,你可以选择网卡和协议
...............................................................
..........^C
Sent 322 packets.
sr1方法详解
- sr1函数:Send packets at layer 3 and return only the first answer(在第3层发送数据包,只返回有回应的回复包)
参数详解
- x: packet(数据包/集)
- nofilter: put 1 to avoid use of BPF filters(设置1:以避免使用BPF过滤器)
- promisc=None
- if positive, how many times to resend unanswered packets(如果是正数,要重新发送未回复数据包的次数)
- if negative, how many times to retry when no more packets are answered(如果为负,当没有更多的包被应答时,要重试次数)
- timeout: how much time to wait after the last packet has been sent(最后一个包发送后要等待多长时间,超时等待)
- verbose: set verbosity level(集冗长等级)(报文的非关键信息)
- level of verbosity, from 0 (almost mute) to 3 (verbose)
- 默认是2;False的效果与0类似。
- multi: whether to accept multiple answers for the same stimulus(是否接受同一刺激的多个回复)
- filter: provide a BPF filter(提供BPF过滤器)
- iface: listen answers only on the given interface(只在指定的接口监听应答)
- 如:eth0, eth1等