/python_ping

A pure python ICMP ping implementation using raw sockets.

Primary LanguagePythonOtherNOASSERTION

A pure python ping implementation using raw sockets.

Note that ICMP messages can only be sent from processes running as root (in Windows, you must run this script as 'Administrator').

Original Version from Matthew Dixon Cowles

  • copyleft 1989-2013 by the python-ping team, see AUTHORS for more details.
  • license: GNU GPL v2, see LICENSE for more details.

CLI Usage

~/python-ping$ sudo ./ping.py
usage: ping.py [-h] [--test] [-q] [--ipv6] [-c count] [-s packetsize]
               [-W timeout]
               [destination]

Send ICMP ECHO_REQUEST to network hosts

positional arguments:
  destination    destination

optional arguments:
  -h, --help     show this help message and exit
  --test         Run a basic test suite
  -q, --quiet    Quiet output. Nothing is displayed except the summary lines
                 at startup time and when finished.
  --ipv6         Run using IPv6, instead of the default (IPv4)
  -c count       Stop after sending count ECHO_REQUEST packets.
  -s packetsize  Specifies the number of data bytes to be sent. The default is
                 56, which translates into 64 ICMP data bytes when combined
                 with the 8 bytes of ICMP header data.
  -W timeout     Time to wait for a response, in seconds.
~/python-ping$ sudo ./ping.py google.com
PYTHON PING google.com (173.194.33.34):  56 bytes of data.
64 bytes from google.com (173.194.33.34): icmp_seq=0 ttl=57 time=11.353 ms
64 bytes from google.com (173.194.33.34): icmp_seq=1 ttl=57 time=11.085 ms
64 bytes from google.com (173.194.33.34): icmp_seq=2 ttl=57 time=10.786 ms

--- google.com PYTHON PING statistics ---
3 packets transmitted, 3 received, 0.0% packet loss, time 33ms
round-trip (ms)  min/avg/max = 10.786/11.075/11.353
~/python-ping$ sudo ./ping.py 8.8.8.8
PYTHON PING 8.8.8.8 (8.8.8.8):  56 bytes of data.
64 bytes from 8.8.8.8: icmp_seq=0 ttl=49 time=20.363 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=49 time=17.155 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=49 time=32.250 ms

--- 8.8.8.8 PYTHON PING statistics ---
3 packets transmitted, 3 received, 0.0% packet loss, time 69ms
round-trip (ms)  min/avg/max = 17.155/23.256/32.250

Module Usage

#!/usr/bin/env python

from python_ping import ping

# host = Host you want to ping
p = ping.Ping(host, timeout=3000, quiet=True, silent=True, ipv6=False)
stats = p.run(1)  # PingStats

# class PingStats:
#     destination_ip
#     destination_host
#     destination_port
#     packets_sent
#     packets_received
#     lost_rate
#     min_time
#     max_time
#     total_time
#     average_time

TODOs

  • Fix unit tests
  • Improve documentation
  • Improve CLI interface
  • Refactor ping.py
  • Add a "suprocess ping", with output parser

contribute

Fork this repo on GitHub and send pull requests. Thank you.

Revision history

Aug. 13, 2013

  • Adding 'silent' option when running as imported module. 'quiet' prints just the summary, 'silent' suppresses all outputs. [pferate]

Aug. 09, 2013

  • Now pep8 compliant [pferate]

Jul. 16, 2013

  • Refactored codebase back to a class, retaining all other updates. [pferate]
  • Added a better CLI (still more to add, but currently has more options available) [pferate]

Jul. 09, 2013

  • Added exit code [pferate]

June 19, 2013

  • Added support for IPv6. Taken from implementation of Lars Strand.

March 19, 2013

  • Fixing bug to prevent divide by 0 during run-time.

January 26, 2012

  • Fixing BUG #4 - competability with python 2.x [tested with 2.7] - Packet data building is different for 2.x and 3.x. 'cose of the string/bytes difference.
  • Fixing BUG #10 - the multiple resolv issue. - When pinging domain names insted of hosts (for exmaple google.com) you can get different IP every time you try to resolv it, we should resolv the host only once and stick to that IP.
  • Fixing BUGs #3 #10 - Doing hostname resolv only once.
  • Fixing BUG #14 - Removing all 'global' stuff. - You should not use globul! Its bad for you...and its not thread safe!
  • Fix - forcing the use of different times on linux/windows for more accurate mesurments. (time.time - linux/ time.clock - windows)
  • Adding quiet_ping function - This way we'll be able to use this script as external lib.
  • Changing default timeout to 3s. (1second is not enought)
  • Switching data syze to packet size. It's easyer for the user to ignore the fact that the packet headr is 8b and the datasize 64 will make packet with

Oct. 17, 2011

Oct. 12, 2011

Merge sources and create a seperate github repository:

Add a simple CLI interface.

September 12, 2011

Bugfixes + cleanup by Jens Diemer Tested with Ubuntu + Windows 7

September 6, 2011

Cleanup by Martin Falatic. Restored lost comments and docs. Improved functionality: constant time between pings, internal times consistently use milliseconds. Clarified annotations (e.g., in the checksum routine). Using unsigned data in IP & ICMP header pack/unpack unless otherwise necessary. Signal handling. Ping-style output formatting and stats.

August 3, 2011

Ported to py3k by Zach Ware. Mostly done by 2to3; also minor changes to deal with bytes vs. string changes (no more ord() in checksum() because >source_string< is actually bytes, added .encode() to data in send_one_ping()). That's about it.

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.

November 8, 2009

Fixes by George Notaras, reported by Chris Hallman:

Improved compatibility with GNU/Linux systems.

Changes in this release:

Re-use time.time() instead of time.clock(). The 2007 implementation worked only under Microsoft Windows. Failed on GNU/Linux. time.clock() behaves differently under the two OSes.

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"

December 4, 2000

Changed the struct.pack() calls to pack the checksum and ID as unsigned. My thanks to Jerome Poincheval for the fix.

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().

Links

Sourcecode at GitHub https://github.com/jedie/python-ping
Python Package Index http://pypi.python.org/pypi/python-ping/
IRC #pylucid on freenode.net