"Pong" est utile pour pinguer des centaines de machines rapidement avec une syntaxe courte...
Pong est multithreads, ce qui lui permet de pinguer plusieurs machines en même temps.
Comment ca marche ? Basiquement, comme ping :
pong 172.16.0.1
Plus spécifiquement :
pong 172.16.50,52,54,60.1-25
cette commande ping 100 machines
autre exemple : pong 172.16.1,2.1-5:172.20.1,2,3.1-25:192.168.1.1-10
Ca donne quoi sur une console ?
mymachine% pong 172.16.52.1-10
IP MAC Status Times (ms)
172.16.52.1 0F:14:2F:3F:37:F0 Up 0.247 1.988
172.16.52.2 Down
172.16.52.3 Down
172.16.52.4 Down
172.16.52.5 00:1F:22:FE:AA:FA Up 0.263 0.868
172.16.52.6 00:14:2F:3F:46:F9 Up 0.220 0.730
172.16.52.7 00:1F:22:3F:46:F9 Up 0.226 4.058
172.16.52.8 00:14:2F:3F:46:7F Up 0.238 3.742
172.16.52.9 00:1F:22:3F:68:FF Up 0.256 2.980
172.16.52.10 00:1F:2F:3F:45:5F Up 0.250 1.333
Pong Report : 10 IPs Ponged in : 0h 0m 2s 0909ms
7 Hosts Up
3 Hosts Down
0 Hosts Weird
Pong accepte plein d'options d'affichage de sorte à contraindre la sortie ecran à ce que l'on souhaite ...
Utile pour créer des logs ...
Pong V3.00 est un soft sous licence GPLv3
Développé/Fonctionne sous Python 2.5.1
Paquet DEB pour Debian ou Ubuntu :
http://www.kik-it.com/downloads/PYTHON_STUFF/Pong.deb
Source / Exemple :
#!/usr/bin/python
# -*- coding: utf_8 -*-
u"""
program : Pong V 3.0
file : pong.py
author : Frédérick Lemasson < djassper [at] gmail [dot] com >
licence : GPL v3.0
created : 2007-08-27
revised : 2007-09-03
purpose : Ping lots of IPs (V4) using a single command line and prints a report
exemple : pong 172.16.1,2.1-5:172.20.1,2,3.1-25:192.168.1.1-10
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details :
http://www.gnu.org/licenses
http://www.gnu.org/licenses/gpl-3.0.html
http://www.gnu.org/philosophy/
"""
from __future__ import with_statement
import os
#import re
import time
import sys
from threading import Thread
from optparse import OptionParser
pong=sys.modules['__main__']
usage = u"""
pong [options] IPCode
IPCode is translated to IPs following the rules :
Special characters you can use in octets (only one per octet) :
"-" means range, Exemple : 1-5 means 1,2,3,4,5
"*" means range [0-255]
"," means list, Exemple : 1,3,12 means 1,3,12
You can use ":" between IPCodes :
IPCodes exemples : 172.16.1,2.1-5:172.20.1,2,3.1-25
192.168.1.*
10.1.1.100
Pong Copyright (C) 2007 Frédérick Lemasson - France
This program comes with ABSOLUTELY NO WARRANTY.
This is GPL free software, and you are welcome to redistribute it under
certain conditions. If you Improve/Modify/Debug Pong,
you ["must" AND "will be happy to"] send me an email.
for details type "pong --licence".
"""
parser = OptionParser(usage)
#Simple Options
parser.add_option("-u", "--HideUp", dest="HideUp", action="store_true", default=False, help="Hide Hosts Up")
parser.add_option("-d", "--HideDown", dest="HideDown", action="store_true", default=False, help="Hide Hosts Down")
parser.add_option("-w", "--HideWeird", dest="HideWeird", action="store_true", default=False, help="Hide Hosts Weird")
parser.add_option("-i", "--HideIP", dest="HideIP", action="store_true", default=False, help="Hide IPs from report")
parser.add_option("-s", "--HideStatus", dest="HideStatus", action="store_true", default=False, help="Hide Status from report")
parser.add_option("-m", "--HideMAC", dest="HideMAC", action="store_true", default=False, help="Hide MACs from report")
parser.add_option("-t", "--HideTimes", dest="HideTimes", action="store_true", default=False, help="Hide Times from report")
parser.add_option("-c", "--HideHeaders", dest="HideHeaders", action="store_true", default=False, help="Don't show the Columns Headers")
parser.add_option("-r", "--HideReport", dest="HideReport", action="store_true", default=False, help="Don't show the report")
parser.add_option("-b", "--Beep", dest="Beep", action="store_true", default=False, help="Beeps when a host is either Down or Weird")
parser.add_option("--licence", dest="licence", action="store_true", default=False, help="Prints Pong Licence informations")
#Parameter Options
parser.add_option("-e", "--Exclude", dest="Exclude", metavar="IPCode", help="Exclude IPs from ping list")
parser.add_option("-f", "--InputFile", dest="InputFile", help="Specify a file containing IPCodes to ping, one IPCode per line")
parser.add_option("-R", "--Report", dest="Report", help="Build/Update a long term Report")
parser.add_option("-L", "--Limit", type="int", dest="Limit", help="Sets the long term Report occurences limit")
parser.add_option("-W", "--Wait", type="int", dest="Wait", default=1, help="Time to wait for a response, in seconds, default is 1s")
(options, args) = parser.parse_args()
if options.licence:
print usage,pong.__doc__
sys.exit()
if len(args) != 1 and not options.InputFile:
parser.error("incorrect number of arguments")
### Functions ###
class NDict(dict):
""" Customized dict, don't raise KeyError exception, return None instead """
def __getitem__(self, key):
if self.has_key(key):
return dict.__getitem__(self, key)
else:
return ""
class Pong(Thread):
""" Sends pings in parallel using Thread module """
def __init__ (self,ip):
Thread.__init__(self)
self.ip = ip
self.status = -1
self.times= ""
def run(self):
ping = os.popen("ping -q -c2 -W"+str(options.Wait)+" "+self.ip,"r")
while 1:
line = ping.readline()
if not line: break
if "," in line and self.status==-1:
Result = int(line.split(",")[1].strip().split()[0])
if Result in [0,1,2]: self.status = Result
if "=" in line and self.times=="":
Result = line.split("=")[1].strip().split("/")
self.times = str(Result[0]) + " " +str(Result[2])
def Beep():
print >> sys.stderr, "\a",
def TimeFrom(StartTime):
""" Returns Time elapsed between now and given time (returns in format : h m s ms)"""
StopTime=time.time()
Took=StopTime - StartTime
Foo=time.gmtime(Took)
return str(Foo[3])+"h "+str(Foo[4])+"m "+str(Foo[5])+"s "+str(Took).split(".")[1][:4]+"ms"
def Range2List(TheRange):
""" Turns octet range user input in python list"""
TheRange=TheRange.split("-")
return range(int(TheRange[0]),int(TheRange[1])+1)
def List2List(TheList):
""" Turns octet list user input in python list"""
TheCleanList=[]
for item in TheList.split(","):
TheCleanList.append(int(item))
return TheCleanList
def ClearFile(TheFile):
with open(TheFile,"w") as f:
f.write("")
def ReadFile(TheFile):
""" Returns complete text file"""
with open(TheFile,"rb") as f:
return f.read()
def WriteFile(TheFile,Content):
with open(TheFile,"w") as f:
f.write(Content)
def AppendFile(TheFile,Content):
with open(TheFile,"a") as f:
f.write(Content)
def Read2Dic(TheFile):
key=0
TheDic={}
for line in file(TheFile):
key += 1
TheDic[str(key)] = line
return TheDic
def Report2Dic(TheFile):
TheDic=NDict()
for line in file(TheFile):
Data=line.split()
TheDic[str(Data[0])] = str(" ".join(Data[1:]))
return TheDic
def Dic2Report(TheDic, TheReport):
sortedkeys = TheDic.keys()
sortedkeys.sort()
#NatSort(sortedkeys)
with open(TheReport,"a") as f:
for k in sortedkeys:
f.write(k+" "+TheDic[k]+"\n")
def GetIPsMAC():
""" Populate global Dict MACs which contains IP as Key and MAC as Value"""
global MACs
arptable = ReadFile("/proc/net/arp")
for line in arptable.split("\n"):
if not line: break
Item=line.split()
MACs[Item[0]]=Item[3]
def IPCode2List(TheIPCodes):
""" Used in exclude mode to turn IPCodes into a IPs List"""
IPCodes=TheIPCodes.split(":")
TheList=[]
for IPCode in IPCodes:
if IPCode=="":continue
Octets=IPCode.split(".")
for Current in range(len(Octets)):
if Octets[Current]=="*" : Octets[Current]="0-255" #Broadcast included but ping will zap it, could be handled though
if Octets[Current].find("-")!=-1: #Octet Codes for a range
Octets[Current]=Range2List(Octets[Current])
elif Octets[Current].find(",")!=-1: #Octet codes for a list
Octets[Current]=List2List(Octets[Current])
else: #Octet codes for himself
Octets[Current]=[int(Octets[Current])]
for Octet0 in Octets[0]:
for Octet1 in Octets[1]:
for Octet2 in Octets[2]:
for Octet3 in Octets[3]:
TheList.append(str(Octet0)+"."+str(Octet1)+"."+str(Octet2)+"."+str(Octet3))
return TheList
### Variables ###
StartTime=time.time()
report = ("Down","Weird","Up")
PingsUp=0
PingsDown=0
PingsWeird=0
MACs=NDict()
Data=NDict()
if options.Exclude:
ExclusionList=IPCode2List(options.Exclude)
else:
ExclusionList=[]
if options.InputFile:
IPCodes=ReadFile(options.InputFile).replace("\n",":").split(":")
else:
#User input exemple : 172.16.50,52,60.1-25:172.20.150,154.1-20
IPCodes=args[0].split(":")
if options.Report:
Report=NDict()
if os.path.exists(options.Report):
Report=Report2Dic(options.Report)
else:
ClearFile(options.Report)
### Code ###
if not options.HideHeaders:
Headers=""
Headers+="IP".ljust(16) if not options.HideIP else ""
Headers+="MAC".ljust(19) if not options.HideMAC else ""
Headers+="Status".ljust(8) if not options.HideStatus else ""
Headers+="Times (ms)".ljust(18) if not options.HideTimes else ""
print Headers
for IPCode in IPCodes:
if IPCode=="":continue
Octets=IPCode.split(".")
for Current in range(len(Octets)):
if Octets[Current]=="*" : Octets[Current]="0-255" #Broadcast included but ping will zap it, could be handled though
if Octets[Current].find("-")!=-1: #Octet Codes for a range
Octets[Current]=Range2List(Octets[Current])
elif Octets[Current].find(",")!=-1: #Octet codes for a list
Octets[Current]=List2List(Octets[Current])
else: #Octet codes for himself
Octets[Current]=[int(Octets[Current])]
for Octet0 in Octets[0]:
for Octet1 in Octets[1]:
for Octet2 in Octets[2]:
pinglist = []
Data=NDict()
#Build complete IPs and send Pings Threads
for Octet3 in Octets[3]:
IP = str(Octet0)+"."+str(Octet1)+"."+str(Octet2)+"."+str(Octet3)
if IP in ExclusionList: continue
current = Pong(IP)
pinglist.append(current)
current.start()
#Join Pings Threads responses / define their status
for pinged in pinglist:
pinged.join()
#Set Counters and what to print
if pinged.status==0:
PingsDown += 1
if options.Beep:Beep()
if options.HideDown:continue
elif pinged.status==1:
PingsWeird += 1
if options.Beep:Beep()
if options.HideWeird:continue
elif pinged.status==2:
PingsUp += 1
if options.HideUp:continue
#Populate IP Datas on Status
Data[pinged.ip]={}
Data[pinged.ip]["Status"]=report[pinged.status]
Data[pinged.ip]["Times"]=pinged.times
#Pings Just returned, Populate MACs Dict with fresh arp table
if not options.HideMAC:GetIPsMAC()
IPs=Data.keys()
#ReLoop in last Octet and print results
for Octet3 in Octets[3]:
IP = str(Octet0)+"."+str(Octet1)+"."+str(Octet2)+"."+str(Octet3)
if IP in IPs:
if not options.HideMAC:Data[IP]["Mac"]=MACs[IP] if MACs[IP]!="00:00:00:00:00:00" else ""
Line=""
Line+=IP.ljust(16) if not options.HideIP else ""
Line+=Data[IP]["Mac"].ljust(19) if not options.HideMAC else ""
Line+=Data[IP]["Status"].ljust(8) if not options.HideStatus else ""
Line+=Data[IP]["Times"].ljust(18) if not options.HideTimes else ""
print Line
if options.Report:
Infos=Line.split()
Report[str(Infos[0])]+=" ".join(Infos[1:])+"/"
#Report[str(Infos[0])]=Report[str(Infos[0])][0:-1]
if options.Limit:
#keeps the last options.Limits occurences
occurences=Report[str(Infos[0])].split("/")
if len(occurences)-1>options.Limit:
Report[str(Infos[0])]="/".join(occurences[-options.Limit-1:])
if not options.HideReport:
print ""
print "Pong Report : "+str(PingsUp+PingsDown+PingsWeird).rjust(8) +" IPs Ponged in :",TimeFrom(StartTime)
print " "+str(PingsUp).rjust(8)+" Hosts Up"
print " "+str(PingsDown).rjust(8)+" Hosts Down"
print " "+str(PingsWeird).rjust(8)+" Hosts Weird"
print ""
if options.Report:
ClearFile(options.Report)
Dic2Report(Report, options.Report)
Conclusion :
Si quelqun se sent de faire en sorte que Pong marche sous Windows (pas compliqué il n'y a que la syntaxe/traitement du ping à changer) j'en serai flaté ...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.