Thursday, July 16, 2009

Python - ping one or many addresses at once

# ping a range or a single ip address 
# This implementation creates a thread for each ip address 
# you wish to ping. 
# 
# this version utilizes the os' ping and 
# drives the ping through os.popen 
# 
# if you are looking for a pure python version you should try this 
# 
# if you are looking for a better way to drive 
# subprocesses then look here 

import os, time, sys
from threading import Thread
 
def usage():
    print """ 
    usage: ping_o_matic.py ip_or_ip_range 
 
    This script pings an ip address or a range of ip addresses and 
    returns the result of the ping. If a '*' character is not found 
    in the ipaddress then the script assumes that you are pinging a 
    single ip by ip or dns. 
    If a range of ip addresses is passed then only a class c network 
    can be pinged, nothing larger. 
    example: 
    ping_o_matic.py 192.168.1.1 # pings the ip address 192.168.1.1 
    ping_o_matic.py 192.168.1.* # pings entire class c subnet of 192.168.1.1-255 
    """ 
 
class pingy(Thread): # class inherits from thread 
    def __init__(self, ip):
        Thread.__init__(self) # calls super init 
        self.information = ("yet to run", "no response","Active")
        self.ip = ip
        self.status = 0 # corresponds to the information tuple -- 0 = "yet to run" 
    def run(self):
        pingexe = os.popen("ping -n 2 "+self.ip, "r")
        self.status = 1 #running but no response yet 
        while True:
            line = pingexe.readline()
            if not line: # if done pinging 
                break 
            if line.find(self.ip) and line.find("Reply") > -1: # they exist: 
                self.status = 2 # 2=Active 
    def getStatus(self):
        return self.information[self.status]
 
if __name__ == '__main__':
    # only accept one parameter -- the rest are ignored 
    try:
        ipaddr = sys.argv[1]
    except:
        usage()
        sys.exit()
 
    
 
    pinglist = []
    ip = ipaddr
    if ipaddr.find('*') == -1:
        current = pingy(ip)
        pinglist.append(current)
        current.start()
    else: # then its a range of IPs 
        lastDot = ipaddr.find('*')
        for host in range(0,255):
            ip = ipaddr[0:lastDot]+str(host)
            current = pingy(ip)
            pinglist.append(current)
            current.start()
    for pig in pinglist: # loop through all threads and collect and display status 
        pig.join()
        print pig.ip, ", ", pig.getStatus()
 
#output (for me): 
#python pingmanyatonce.py 10.0.0.1 
#10.0.0.1 ,  Active 
# 
# 
#python pingmanyatonce.py 10.0.0.* 
#10.0.0.0 ,  no response 
#10.0.0.1 ,  Active 
#10.0.0.2 ,  Active 
#10.0.0.3 ,  no response 
#10.0.0.4 ,  no response 
#10.0.0.5 ,  no response 
#10.0.0.6 ,  no response 
#10.0.0.7 ,  no response 
#... # and it keeps going for the entire subnet... 
 
 

# try out the full source

No comments:

Post a Comment