Rewrite pingnet.py to use multiple threads
--HG-- extra : amend_source : 595a48f6b8cd4de9bc22e5731e816240e63ab8ffmaster
parent
0cea591bb6
commit
79355a87ea
127
pingnet.py
127
pingnet.py
|
@ -1,36 +1,113 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python
|
||||||
|
import argparse
|
||||||
import ipaddr
|
import ipaddr
|
||||||
import os
|
import os
|
||||||
import socket
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
try:
|
||||||
|
import queue
|
||||||
|
except ImportError: # Python 2
|
||||||
|
import Queue as queue
|
||||||
|
|
||||||
def main():
|
|
||||||
for arg in sys.argv[1:]:
|
class WaitQueue(queue.Queue):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.event = threading.Event()
|
||||||
|
queue.Queue.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class Queuer(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, iterable):
|
||||||
|
self.iterable = iterable
|
||||||
|
self.queue = WaitQueue()
|
||||||
|
self.go = True
|
||||||
|
super(Queuer, self).__init__()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.go = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
for item in self.iterable:
|
||||||
|
if not self.go:
|
||||||
|
break
|
||||||
|
self.queue.put(item)
|
||||||
|
self.queue.event.set()
|
||||||
|
|
||||||
|
|
||||||
|
class Pinger(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, q):
|
||||||
|
self.queue = q
|
||||||
|
self.go = True
|
||||||
|
self.quiet = False
|
||||||
|
super(Pinger, self).__init__()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.go = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.queue.event.wait()
|
||||||
|
while self.go:
|
||||||
try:
|
try:
|
||||||
net = ipaddr.IPv4Network(arg)
|
ip = self.queue.get(False)
|
||||||
except ipaddr.AddressValueError:
|
except queue.Empty:
|
||||||
sys.stderr.write('Invalid network address: {}\n'.format(arg))
|
break
|
||||||
else:
|
|
||||||
for ip in net.iterhosts():
|
|
||||||
p = subprocess.Popen(['ping', '-c1', '-W1', str(ip)],
|
|
||||||
stdout=open(os.devnull, 'w'),
|
|
||||||
stderr=open(os.devnull, 'w'),
|
|
||||||
stdin=open(os.devnull))
|
|
||||||
try:
|
try:
|
||||||
p.wait()
|
self.ping(str(ip))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print()
|
break
|
||||||
raise SystemExit
|
|
||||||
try:
|
def ping(self, host):
|
||||||
hostname = '{} ({})'.format(
|
p = subprocess.Popen(['ping', '-c', '1', '-W', '1', host],
|
||||||
ip,
|
stdin=open(os.devnull),
|
||||||
socket.gethostbyaddr(str(ip))[0],
|
stdout=open(os.devnull, 'w'),
|
||||||
)
|
stderr=subprocess.STDOUT)
|
||||||
except socket.herror:
|
p.wait()
|
||||||
hostname = ip
|
if p.returncode == 0:
|
||||||
state = 'in use' if p.returncode == 0 else 'not responding'
|
if not self.quiet:
|
||||||
print('{} is {}'.format(hostname, state))
|
sys.stdout.write('{0} is in use\n'.format(host))
|
||||||
|
else:
|
||||||
|
sys.stdout.write('{0} is available\n'.format(host))
|
||||||
|
|
||||||
|
|
||||||
|
class main(object):
|
||||||
|
|
||||||
|
def _parse_args(self):
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--quiet', '-q', action='store_true',
|
||||||
|
help='Only print available addresses')
|
||||||
|
parser.add_argument('--num-threads', type=int, default=10,
|
||||||
|
metavar='COUNT',
|
||||||
|
help='Number of simultaneous pings to run')
|
||||||
|
parser.add_argument('networks', nargs='+', metavar='network',
|
||||||
|
help='Network to ping, in CIDR notation')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
args = self._parse_args()
|
||||||
|
self.queuer = Queuer(h for n in args.networks
|
||||||
|
for h in ipaddr.IPv4Network(n).iterhosts())
|
||||||
|
self.pingers = []
|
||||||
|
signal.signal(signal.SIGINT, self.quit)
|
||||||
|
self.queuer.start()
|
||||||
|
for __ in range(0, args.num_threads):
|
||||||
|
pinger = Pinger(self.queuer.queue)
|
||||||
|
pinger.quiet = args.quiet
|
||||||
|
self.pingers.append(pinger)
|
||||||
|
pinger.start()
|
||||||
|
while len(threading.enumerate()) > 1:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def quit(self, signum, frame):
|
||||||
|
self.queuer.stop()
|
||||||
|
for pinger in self.pingers:
|
||||||
|
pinger.stop()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue