#coding:utf-8
#!/usr/bin/env python
import
osimport
argparse
import
socket
import
struct
import
select
import
time
#icmp_echo_request = 8 #
platform specific
#超時時間
default_timeout = 2
#ping到次數
default_count = 4
class
pinger(object):
"""pings to a host -- the pythonic way
"""def
__init__(self, target_host, count=default_count, timeout=default_timeout):
''':param target_host: 目標主機
:param count: ping的次數
:param timeout: 超時時間
:return:
'''self.target_host =target_host
self.count =count
self.timeout =timeout
defdo_checksum(self, source_string):
"""驗證包的完整性
"""sum =0
#不小於長度的最小偶數
max_count = (len(source_string)/2)*2count =0
while count val = ord(source_string[count + 1])*256 +ord(source_string[count])
sum = sum +val
sum = sum & 0xffffffffcount = count + 2
if max_countsum = sum + ord(source_string[len(source_string) - 1])
sum = sum & 0xffffffffsum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
answer = ~sum
answer = answer & 0xffffanswer = answer >> 8 | (answer << 8 & 0xff00)
return
answer
defreceive_pong(self, sock, id, timeout):
"""接受ping的返回值.
"""time_remaining =timeout
while
true:
start_time =time.time()
readable =select.select([sock], , , time_remaining)
time_spent = (time.time() -start_time)
if readable[0] == : #
timeout
return
time_received =time.time()
recv_packet, addr = sock.recvfrom(1024)
icmp_header = recv_packet[20:28]
type, code, checksum, packet_id, sequence =struct.unpack(
"bbhhh
", icmp_header
)if packet_id ==id:
bytes_in_double = struct.calcsize("d"
) time_sent = struct.unpack("
d", recv_packet[28:28 +bytes_in_double])[0]
return time_received -time_sent
time_remaining = time_remaining -time_spent
if time_remaining <=0:
return
defsend_ping(self, sock, id):
"""傳送ping到目標主機
"""target_addr =socket.gethostbyname(self.target_host)
my_checksum =0
#create a dummy heder with a 0 checksum.
header = struct.pack("
bbhhh
", icmp_echo_request, 0, my_checksum, id, 1)
bytes_in_double = struct.calcsize("d"
) data = (192 - bytes_in_double) * "q"
data = struct.pack("
d", time.time()) +data
#get the checksum on the data and the dummy header.
my_checksum = self.do_checksum(header +data)
header =struct.pack(
"bbhhh
", icmp_echo_request, 0, socket.htons(my_checksum), id, 1)
packet = header +data
sock.sendto(packet, (target_addr, 1))
defping_once(self):
"""returns the delay (in seconds) or none on timeout.
"""icmp = socket.getprotobyname("
icmp")
try:
sock =socket.socket(socket.af_inet, socket.sock_raw, icmp)
except
socket.error, (errno, msg):
if errno == 1:
#not superuser, so operation not permitted
msg += "
icmp messages 只能由root程序發起
"raise
socket.error(msg)
except
exception, e:
"exception: %s
" %(e)
my_id = os.getpid() & 0xffffself.send_ping(sock, my_id)
delay =self.receive_pong(sock, my_id, self.timeout)
sock.close()
return
delay
defping(self):
"""run the ping process
"""for i in
xrange(self.count):
"ping to %s...
" %self.target_host,
try:
delay =self.ping_once()
except
socket.gaierror, e:
"ping failed. (socket error: '%s')
" % e[1]
break
if delay ==none:
"ping failed. (timeout within %ssec.)
" %self.timeout
else
: delay = delay * 1000
"get pong in %0.4fms
" %delay
if__name__ == '
__main__':
parser = argparse.argumentparser(description='
python ping')
parser.add_argument(
'--target-host
', action="
store
", dest="
target_host
", required=true)
given_args =parser.parse_args()
target_host =given_args.target_host
pinger = pinger(target_host=target_host)
pinger.ping()
ICMP協議之ping實現
1.相關icmp協議概述 這裡只講解與ping有關的icmp訊息型別,主機傳送回送訊息 type 8 被請求主機回送響應訊息 type 0 基本格式如下 回送訊息 echo 回送響應訊息 echo reply 其中 code 0,checksum為校驗和,重點注意從icmp的頭部 即type開始 到...
ping 原理與ICMP協議
ping 原理與icmp協議 ping的原理 ping程式是用來探測主機到主機之間是否可通訊,如果不能ping到某台主機,表明不能和這台主機建立連線。ping使用的是icmp協議,它傳送icmp回送請求訊息給目的主機。icmp協議規定 目的主機必須返回icmp回送應答訊息給源主機。如果源主機在一定時...
ping 原理與ICMP協議
ping 的原理 ping 程式是用來探測主機到主機之間是否可通訊,如果不能ping到某台主機,表明不能和這台主機建立連線。ping 使用的是icmp協議,它傳送icmp回送請求訊息給目的主機。icmp協議規定 目的主機必須返回icmp回送應答訊息給源主機。如果源主機在一定時間內收到應答,則認為主機...