diff --git a/ping.py b/ping.py
index 73400fa..f276b6d 100644
--- a/ping.py
+++ b/ping.py
@@ -1,103 +1,29 @@
-#!/usr/bin/env python
-
-"""
- A pure python ping implementation using raw socket.
-
-
- Note that ICMP messages can only be sent from processes running as root.
-
-
- Derived from ping.c distributed in Linux's netkit. That code is
- copyright (c) 1989 by The Regents of the University of California.
- That code is in turn derived from code written by Mike Muuss of the
- US Army Ballistic Research Laboratory in December, 1983 and
- placed in the public domain. They have my thanks.
-
- Bugs are naturally mine. I'd be glad to hear about them. There are
- certainly word - size dependenceies here.
-
- Copyright (c) Matthew Dixon Cowles, .
- Distributable under the terms of the GNU General Public License
- version 2. Provided with no warranties of any sort.
-
- Original Version from Matthew Dixon Cowles:
- -> ftp://ftp.visi.com/users/mdc/ping.py
-
- Rewrite by Jens Diemer:
- -> http://www.python-forum.de/post-69122.html#69122
-
-
- Revision history
- ~~~~~~~~~~~~~~~~
-
- March 11, 2010
- changes by Samuel Stauffer:
- - replaced time.clock with default_timer which is set to
- time.clock on windows and time.time on other systems.
-
- May 30, 2007
- little rewrite by Jens Diemer:
- - change socket asterisk import to a normal import
- - replace time.time() with time.clock()
- - delete "return None" (or change to "return" only)
- - in checksum() rename "str" to "source_string"
-
- November 22, 1997
- Initial hack. Doesn't do much, but rather than try to guess
- what features I (or others) will want in the future, I've only
- put in what I need now.
-
- December 16, 1997
- For some reason, the checksum bytes are in the wrong order when
- this is run under Solaris 2.X for SPARC but it works right under
- Linux x86. Since I don't know just what's wrong, I'll swap the
- bytes always and then do an htons().
-
- December 4, 2000
- Changed the struct.pack() calls to pack the checksum and ID as
- unsigned. My thanks to Jerome Poincheval for the fix.
-
- Januari 27, 2015
- Changed receive response to not accept ICMP request messages.
- It was possible to receive the very request that was sent.
-
- Last commit info:
- ~~~~~~~~~~~~~~~~~
- $LastChangedDate: $
- $Rev: $
- $Author: $
-"""
-
-
-import os, sys, socket, struct, select, time
-
-if sys.platform == "win32":
- # On Windows, the best timer is time.clock()
- default_timer = time.clock
+import os, sys, socket, struct, select, time, base64
+
+if sys.platform.startswith('win'):
+ default_timer = time.perf_counter()
+elif sys.platform.startswith('linux'):
+ default_timer = time.perf_counter()
+if sys.platform.startswith('darwin'):
+ #default_timer = time.clock()
+ default_timer = time.perf_counter()
else:
- # On most other platforms the best timer is time.time()
- default_timer = time.time
+ default_timer = time.perf_counter()
-# 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_to = (len(source_string)//2)*2
count = 0
- while count> 16) + (sum & 0xffff)
@@ -110,54 +36,58 @@ def checksum(source_string):
return answer
-
-def receive_one_ping(my_socket, ID, timeout):
+def recieve_one_ping(my_socket, ID, timeout):
"""
receive the ping from the socket.
"""
- timeLeft = timeout
+ time_left = timeout
while True:
- startedSelect = default_timer()
- whatReady = select.select([my_socket], [], [], timeLeft)
- howLongInSelect = (default_timer() - startedSelect)
- if whatReady[0] == []: # Timeout
+ started_select = default_timer
+ what_ready = select.select([my_socket], [], [], time_left)
+ how_long_in_select = (default_timer - started_select) # removed default_timer()
+ if what_ready[0] == []:
return
- timeReceived = default_timer()
- recPacket, addr = my_socket.recvfrom(1024)
- icmpHeader = recPacket[20:28]
- type, code, checksum, packetID, sequence = struct.unpack(
- "bbHHh", icmpHeader
+ time_recieved = default_timer
+ rec_packet, addr = my_socket.recvfrom(1024) # changed recv_from to recvfrom
+ icmp_header = rec_packet[20:28]
+ type, code, checksum, packet_id, sequence = struct.unpack(
+ 'bbHHh', icmp_header
)
- # Filters out the echo request itself.
- # This can be tested by pinging 127.0.0.1
+ # Filters out the echo request itself.
+ # This can be tested by pinging 127.0.0.1
# You'll see your own request
- if type != 8 and packetID == ID:
- bytesInDouble = struct.calcsize("d")
- timeSent = struct.unpack("d", recPacket[28:28 + bytesInDouble])[0]
- return timeReceived - timeSent
+ if type != 8 and packet_id == ID:
+ bytes_in_double = struct.calcsize('d')
+ time_sent = struct.unpack('d', rec_packet[28:28 + bytes_in_double])[0]
+ return time_recieved - time_sent
- timeLeft = timeLeft - howLongInSelect
- if timeLeft <= 0:
+ time_left = time_left - how_long_in_select
+ if time_left <= 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)
+ 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)
- bytesInDouble = struct.calcsize("d")
- data = (192 - bytesInDouble) * "Q"
- data = struct.pack("d", default_timer()) + data
+ bytes_in_double = struct.calcsize('d')
+ data = (192 - bytes_in_double) * 'Q'
+ data = struct.pack('d', default_timer) + bytes(data.encode('utf-8'))
+ # base64.b64encode(bytes(data.encode('utf-8')))
# Calculate the checksum on the data and the dummy header.
+
+ # data = base64.b64decode(data) works half the time or fails with incorrect padding
+ #
+
+ data = decode_base64(data)
my_checksum = checksum(header + data)
# Now that we have the right checksum, we put that in. It's just easier
@@ -168,7 +98,6 @@ def send_one_ping(my_socket, dest_addr, ID):
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.
@@ -176,7 +105,7 @@ def do_one(dest_addr, timeout):
icmp = socket.getprotobyname("icmp")
try:
my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
- except socket.error, (errno, msg):
+ except socket.error (errno, msg): # removed ',' from excep, socket.error, (errno, msg)
if errno == 1:
# Operation not permitted
msg = msg + (
@@ -189,32 +118,38 @@ def do_one(dest_addr, timeout):
my_ID = os.getpid() & 0xFFFF
send_one_ping(my_socket, dest_addr, my_ID)
- delay = receive_one_ping(my_socket, my_ID, timeout)
-
+ delay = recieve_one_ping(my_socket, my_ID, timeout)
my_socket.close()
return delay
-
def verbose_ping(dest_addr, timeout = 2, count = 4):
"""
Send >count< ping to >dest_addr< with the given >timeout< and display
the result.
"""
- for i in xrange(count):
- print "ping %s..." % dest_addr,
+
+ for i in range(count): # changed xrange() to range()
+ print("ping %s..." % dest_addr,) # removed , maybe take out end=''
try:
delay = do_one(dest_addr, timeout)
- except socket.gaierror, e:
- print "failed. (socket error: '%s')" % e[1]
+
+ except socket.gaierror as e:
+ print("failed. (socket error: '%s')" % e) # e[1]
break
+
if delay == None:
- print "failed. (timeout within %ssec.)" % timeout
+ print("failed. (timeout within %ssec.)" % timeout)
else:
delay = delay * 1000
- print "get ping in %0.4fms" % delay
+ print("get ping in %0.4fms" % delay)
print
+def decode_base64(your_data):
+ padding = len(your_data) % 4
+ if padding != 0:
+ your_data += b'='* (4 - padding)
+ return base64.b64decode(your_data)
if __name__ == '__main__':
verbose_ping("heise.de")
diff --git a/ping_py_changes.txt b/ping_py_changes.txt
new file mode 100644
index 0000000..408409a
--- /dev/null
+++ b/ping_py_changes.txt
@@ -0,0 +1,35 @@
+Added the following changes:
+
+changed if sys.platform() to sys.platform.startswith() at lines 3, 6, and 9
+
+Added two extra if statements line 6, and 9 for detecting linux and mac
+
+removed () from default_timer at lines 46, 48, 52 and 82
+
+Changes time.clock() which is depreciated to time.perf_counter() as lines 3 , 6
+9, and 14
+
+Changed count_to = (len(source_string) / 2) * 2 to
+count_to = (len(source_string) // 2) * 2 at line 20
+
+Changed ord(ord(source_string[count + 1]) * 256 + ord(source_string[count])) to
+(source_string[count + 1]) * 256 + source_string[count] at line 23
+
+
+Renamed variables into more readable format.
+
+
+Changed except socket.error, (errno, msg): to except socket.error (errno, msg)
+at line 104
+
+Changed except socket.gaierror, e: to except socket.gaierror as e: at line 130
+
+Changed xrange() to range at line 125 because xrange was changed to range in
+python 3+
+
+Changed print("ping %s..." % dest_addr,) to print("ping %s..." % dest_addr)
+at line 126
+
+added padding function
+
+added encoding at line 83 and decoding at line 90