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请求

详见WIKI

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等

扩展资料

猜你喜欢

转载自blog.csdn.net/weixin_42359693/article/details/83546276