当前位置: 首页 > Python > 正文

python实现ping程序

ICMP检查(ICMP ping)是一种常见的网络主机检查方式。当需要判断网络上的某台主机是否在线时,只需要简单是使用ping检查一下就可以了,当然这也可以检查本地网络状态。基于ping命令的网络扫描,也是扫描器中经常使用的一种方式。比如大名鼎鼎的nmap。今天就和大家分享一下,如何使用python来进行ICMP ping检查。

关于ICMP协议以及ping程序原理,可以看看我的上一篇博文:ICMP协议与ping原理

 

方法一、使用python脚本调用系统中的ping命令简单实现:

但是,很多情况下,系统中的ping可执行文件是不可用,或者无法访问。这时,就需要使用一个纯python的检查脚本了。下面是ICMP ping的python实现脚本。这个脚本中定义了一个Pinger类,使用的一个校验检验和的do_checksum()方法,一个发送ping数据报文的send_ping()方法,接受ping数据报文的receive_ping()方法和一个执行这个类的ping()主方法。下面是具体的代码:

下面定义了do_checksum()方法,进行检验和的校验,校验方法如下:

  1. 把校验和字段置为0
  2. 将icmp包(包括header和data)以16bit(2个字节)为一组,并将所有组相加(二进制求和)
  3. 若高16bit不为0,则将高16bit与低16bit反复相加,直到高16bit的值为0,从而获得一个只有16bit长度的值
  4. 将此16bit值进行按位求反操作,将所得值替换到校验和字段

具体算法可以参考:【TCP/IP】检验和算法

下面是接受ICMP类型码为8的ICMP回应报文的方法。在未到达超时时间之前socket处于阻塞状态一直等待响应,当有数据传回时就接受响应,然后提取包含标识符ID的ICMP报文首部和包含发送时间值的ICMP内容部分,计算请求-响应的延时间隔。

下面定义的send_ping()方法,获取远程主机的DNS主机名,然后使用struct模块创建一个ICMP_ECHO_REQUEST数据包,将查验请求的数据发送到目标主机。在此发送前也需要进行do_checksum()方法的校验。

下面定义了一个ping_once()方法,向远程主机发送一次查验:将ICMP协议传给socket()方法,创建一个原始的ICMP套接字。由于ping程序需要使用SOCK_RAW来构建数据包,所以需要root权限才能运行这个程序。因此,本程序需要使用root权限运行,下面的异常处理部分就是来负责未使用root运行时抛出的异常。

下面这个ping()是执行这个类的主要方法。在for循环中调用ping_once()方法,发送ping数据报文,并返回结果。

完整代码链接: icmp_ping_tool.py

参考:

《TCP/IP详解 卷2:实现》

《Python网络编程攻略》



这篇博文由 s0nnet 于2015年05月28日发表在 Python 分类下, 欢迎你在下面发表评论
如无特别说明,独木の白帆发表的文章均为原创,欢迎大家转载,转载请注明: python实现ping程序 | 独木の白帆
关键字: ,
【上一篇】【下一篇】

python实现ping程序:目前有2 条留言

  1. 我想用Python实现ping的服务器端,该怎么写呢?就是截获别的机器ping我的ICMP数据包,然后用Python生成响应数据包发送回去。

    2016-12-20 下午4:42 [回复]
  2. 沙发
    地狱:

    需要管理员权限才可以运行 except socket.error, (errno, msg): if errno == 10013: # Not superuser, so operation not permitted msg += “ICMP messages can only be sent from root user processes” raise socket.error(msg)我用windows测试错误代码是10013不是1工具写的不错~

    2017-01-11 上午2:45 [回复]

发表评论

快捷键:Ctrl+Enter