使用python 实现icmp测试主机存活性
代码:
#!/usr/bin/env python
#coding:utf-8
import
os, sys, socket, struct, select, time
# From /usr/include/linux/icmp.h; your milage may vary.
ICMP_ECHO_REQUEST
=
8
# Seems to be the same on Solaris.
def
checksum(source_string):
"""
I'm not too confident that this is right but testing seems
to suggest that it gives the same answers as in_cksum in ping.c
"""
sum
=
0
countTo
=
(
len
(source_string)
/
2
)
*
2
count
=
0
while
count<countTo:
thisVal
=
ord
(source_string[count
+
1
])
*
256
+
ord
(source_string[count])
sum
=
sum
+
thisVal
sum
=
sum
&
0xffffffff
# Necessary?
count
=
count
+
2
if
countTo<
len
(source_string):
sum
=
sum
+
ord
(source_string[
len
(source_string)
-
1
])
sum
=
sum
&
0xffffffff
# Necessary?
sum
=
(
sum
>>
16
)
+
(
sum
&
0xffff
)
sum
=
sum
+
(
sum
>>
16
)
answer
=
~
sum
answer
=
answer &
0xffff
# Swap bytes. Bugger me if I know why.
answer
=
answer >>
8
| (answer <<
8
&
0xff00
)
return
answer
def
receive_one_ping(my_socket,
ID
, timeout):
"""
receive the ping from the socket.
"""
timeLeft
=
timeout
while
True
:
startedSelect
=
time.time()
whatReady
=
select.select([my_socket], [], [], timeLeft)
howLongInSelect
=
(time.time()
-
startedSelect)
if
whatReady[
0
]
=
=
[]:
# Timeout
return
timeReceived
=
time.time()
recPacket, addr
=
my_socket.recvfrom(
1024
)
icmpHeader
=
recPacket[
20
:
28
]
type
, code, checksum, packetID, sequence
=
struct.unpack(
"bbHHh"
, icmpHeader
)
if
packetID
=
=
ID
:
bytesInDouble
=
struct.calcsize(
"d"
)
timeSent
=
struct.unpack(
"d"
, recPacket[
28
:
28
+
bytesInDouble])[
0
]
return
timeReceived
-
timeSent
timeLeft
=
timeLeft
-
howLongInSelect
if
timeLeft <
=
0
:
return
def
send_one_ping(my_socket, dest_addr,
ID
):
"""
Send one ping to the given >dest_addr<.
"""
dest_addr
=
socket.gethostbyname(dest_addr)
# Header is type (8), code (8), checksum (16), id (16), sequence (16)
my_checksum
=
0
# Make a dummy heder with a 0 checksum.
header
=
struct.pack(
"bbHHh"
, ICMP_ECHO_REQUEST,
0
, my_checksum,
ID
,
1
)
#压包
#a1 = struct.unpack("bbHHh",header) #my test
bytesInDouble
=
struct.calcsize(
"d"
)
data
=
(
192
-
bytesInDouble)
*
"Q"
data
=
struct.pack(
"d"
, time.time())
+
data
# Calculate the checksum on the data and the dummy header.
my_checksum
=
checksum(header
+
data)
# Now that we have the right checksum, we put that in. It's just easier
# to make up a new header than to stuff it into the dummy.
header
=
struct.pack(
"bbHHh"
, ICMP_ECHO_REQUEST,
0
, socket.htons(my_checksum),
ID
,
1
)
packet
=
header
+
data
my_socket.sendto(packet, (dest_addr,
1
))
# Don't know about the 1
def
do_one(dest_addr, timeout):
"""
Returns either the delay (in seconds) or none on timeout.
"""
icmp
=
socket.getprotobyname(
"icmp"
)
try
:
my_socket
=
socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
except
socket.error, (errno, msg):
if
errno
=
=
1
:
# Operation not permitted
msg
=
msg
+
(
" - Note that ICMP messages can only be sent from processes"
" running as root."
)
raise
socket.error(msg)
raise
# raise the original error
my_ID
=
os.getpid() &
0xFFFF
send_one_ping(my_socket, dest_addr, my_ID)
delay
=
receive_one_ping(my_socket, my_ID, timeout)
my_socket.close()
return
delay
def
verbose_ping(dest_addr, timeout
=
2
, count
=
100
):
"""
Send >count< ping to >dest_addr< with the given >timeout< and display
the result.
"""
for
i
in
xrange
(count):
print
"ping %s..."
%
dest_addr,
try
:
delay
=
do_one(dest_addr, timeout)
except
socket.gaierror, e:
print
"failed. (socket error: '%s')"
%
e[
1
]
break
if
delay
=
=
None
:
print
"failed. (timeout within %ssec.)"
%
timeout
else
:
delay
=
delay
*
1000
print
"get ping in %0.4fms"
%
delay
if
__name__
=
=
'__main__'
:
verbose_ping(
"www.163.com"
,
2
,
1
)
用到的模块解析:
struct:
最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结。
了解c语言的人,一定会知道struct结构体在c语言中的作用,它定义了一种结构,里面包含不同类型的数据(int,char,bool等等),方便对某一结构对象进行处理。而在网络通信当中,大多传递的数据是以二进制流(binary data)存在的。当传递字符串时,不必担心太多的问题,而当传递诸如int、char之类的基本数据的时候,就需要有一种机制将某些特定的结构体类型打包成二进制流的字符串然后再网络传输,而接收端也应该可以通过某种机制进行解包还原出原始的结构体数据。python中的struct模块就提供了这样的机制,该模块的主要作用就是对python基本类型值与用python字符串格式表示的C struct类型间的转化(This module performs conversions between Python values and C structs represented as Python strings.)。stuct模块提供了很简单的几个函数,下面写几个例子。
struct提供用format specifier方式对数据进行打包和解包(Packing and Unpacking)。例如:
1
2
3
4
5
6
7
8
9
10
11
12
|
import struct
import binascii
values = ( 1 , 'abc' , 2.7 )
s = struct.Struct( 'I3sf' )
packed_data = s.pack( * values)
unpacked_data = s.unpack(packed_data)
print 'Original values:' , values
print 'Format string :' , s. format
print 'Uses :' , s.size, 'bytes'
print 'Packed Value :' , binascii.hexlify(packed_data)
print 'Unpacked Type :' , type (unpacked_data), ' Value:' , unpacked_data
|
输出:
Original values: (1, 'abc', 2.7)
Format string : I3sf
Uses : 12 bytes
Packed Value : 0100000061626300cdcc2c40
Unpacked Type : <type 'tuple'> Value: (1, 'abc', 2.700000047683716)
代码中,首先定义了一个元组数据,包含int、string、float三种数据类型,然后定义了struct对象,并制定了format‘I3sf’,I 表示int,3s表示三个字符长度的字符串,f 表示 float。最后通过struct的pack和unpack进行打包和解包。通过输出结果可以发现,value被pack之后,转化为了一段二进制字节串,而unpack可以把该字节串再转换回一个元组,但是值得注意的是对于float的精度发生了改变,这是由一些比如操作系统等客观因素所决定的。打包之后的数据所占用的字节数与C语言中的struct十分相似。
select 模块:
Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统)
select方法:
进程指定内核监听哪些文件描述符(最多监听1024个fd)的哪些事件,当没有文件描述符事件发生时,进程被阻塞;当一个或者多个文件描述符事件发生时,进程被唤醒。
当我们调用select()时:
1 上下文切换转换为内核态
2 将fd从用户空间复制到内核空间
3 内核遍历所有fd,查看其对应事件是否发生
4 如果没发生,将进程阻塞,当设备驱动产生中断或者timeout时间后,将进程唤醒,再次进行遍历
5 返回遍历后的fd
6 将fd从内核空间复制到用户空间
fd:file descriptor 文件描述符
fd_r_list, fd_w_list, fd_e_list = .秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
转载于:https://blog.51cto.com/linux1989/1925082
使用python 实现icmp测试主机存活性相关推荐
- 渗透测试工程师——第一部分 信息扫描实验系列 001主机存活性探测实验
主机存活性探测实验 实验目的 实验原理 1.TCP/IP协议 网络协议 传输控制协议(TCP) 2.Ping命令的原理 实验环境 1.操作系统 2.实验工具 实验步骤 步骤1:Ping命令(Windo ...
- ping 计算机名判断机器是否在线,通过ping命令检测主机的存活性
判断所有的业务系统中主机的存活性ping 问题描述:现在有一上线项目,用的环境为vsphere 虚拟化技术.由于不能随时判断各虚拟主机的存活性,保证业务系统的正常运行,现在需要编写一个脚本判断主机的存 ...
- 《黑客秘笈——渗透测试实用指南》—第1章1.1节搭建渗透测试主机
本节书摘来自异步社区<黑客秘笈--渗透测试实用指南>一书中的第1章1.1节搭建渗透测试主机,作者[美]Peter Kim(彼得 基姆),更多章节内容可以访问云栖社区"异步社区&q ...
- [linux] ifconfig 显示配置网络设备 、 route 显示操作路由表 、 ping 测试主机连通...
ifconfig 显示配置网络设备 ifconfig [网络设备] [参数] ifconfig 命令用来查看和配置网络设备.当网络环境发生改变时可通过此命令对网络进行相应的配置. 被用来获取网络接口配 ...
- 10.9 ping:测试主机之间网络的连通性
ping命令 可用于测试主机之间网络的连通性.执行ping命令会使用ICMP传输协议,发出要求回应的信息,若远端主机的网络功能没有问题,就会回应该信息,因而可得知该主机运作正常. ping命令的参数选 ...
- python是什么牌子主机_python 收集主机信息
这篇文章是之前几篇的一个小综合.也是通过收集主机的一些参数信息,熟悉python里的文件读取,字符切割,字典存储等知识. 文章结构: (1) 文章目的,需要收集的信息,并逐个分析如何获取信息. (2) ...
- Linux测试主机之间连通性和端口是否开放的方法
文章目录 测试主机之间的连通性 测试端口是否开放(curl) 测试端口是否开放(wget) 测试端口是否开放(ssh) 下面每一种测试方式都给出了成功通信的截图,如果与截图不相符可以根据你控制台的报错 ...
- python全栈测试开发_用于全栈自动化测试的最佳Python工具
我知道大多数测试人员会说Java是他们创建自动化测试的首选语言. 但是我最喜欢的是Python.为什么?为什么是Python ? Al Sweigart,<自动化那些无聊的东西>的作者,P ...
- ping命令 ——测试主机间网络连通性
ping命令 --测试主机间网络连通性 一.ping命令 1.概述 2.格式 3.常用参数 4.实例 ①.检查连通性 ②.仅仅连ping 5次后停止 ③.设置ping 5 次,每次间隔0.5秒 ④.p ...
最新文章
- Swift 5进入发布倒计时
- JAVA基础学习day21--IO流三-File、Properties、PrintWriter与合并、分割流
- 虚拟化涉及的关键技术都有哪些,分别实现了什么功能?
- 你的灯亮着吗阅读笔记之一
- Android Sqlite
- Java多线程网络爬虫(时光网为例)
- excel重复上一步快捷键_工作再忙也要学会的十个Excel快捷键
- 操作系统的运行机制体系结构
- 检测到python编程环境中存在多个版本_windows配置Python多版本共存
- Intellij IDEA 14.x 菜单项中Compile、Make和Build的区别
- 【软考】软件设计师知识点整理(待更新)
- echars中国地图,省份名字居中
- 如何解决您的虚拟主机中有文件触发了安全防护报警规则,可能存在webshell网页木马...
- 极品五笔输入法2009_考场指南!2020年注会机考计算器使用指南及输入法切换
- 闪迪u盘量产工具万能版_加密保护,更高性能!闪迪酷奂CZ74 U盘新品果然够惊艳...
- 使用百度网盘自动同步Zotero的文献
- Java 创建一个Customer类,类中的属性有姓名、年龄、性别,然后创建两个Customer对象,把这两个对象存储在ArrayList对象中,然后再从ArrayList对象中读取出来。
- 2020暨南大学计算机专硕考研经验分享
- Java 时间相关 获取某月的某一天
- WORD2010 页眉横线和页面顶端距离相同显示不一样