Essentially we want to replicate
nmap -p 4000-4100 hostname
Source: this gist
For this particular use of nmap, I have this Python script, which outputs JSON
(so avoids the need to parse the output of nmap). It runs each attempt to connect
in a separate thread, each with a 1 second timeout, which is fine for a LAN.
#!/usr/bin/env python3
import json
import sys
import socket
from threading import Thread
def isOpen(ip,port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.settimeout(1.0)
s.connect((ip, int(port)))
s.shutdown(socket.SHUT_RDWR)
s.close()
return True
except Exception as e:
return False
class Pinger:
def __init__(self,host,baseport=7000,count=100):
self.host = host
self.baseport = baseport
self.count = count
self.targets = set(range(count))
self.openports = set()
self.threads = []
self.ports = set()
for n in self.targets:
thread = Thread(target=self.task,args=(n,))
self.threads.append(thread)
def task(self,n):
targets = self.targets
ports = self.ports
if n in targets:
targets.remove(n)
port = n + self.baseport
if isOpen(self.host,port):
ports.add(n)
def start(self):
for thread in self.threads:
thread.start()
def join(self):
for thread in self.threads:
thread.join()
def result(self):
return (self.host,list(sorted(self.ports)))
hosts = sys.argv[1:]
pingers = []
for host in hosts:
pingers.append((host,Pinger(host)))
for host, pinger in pingers:
pinger.start()
for host, pinger in pingers:
pinger.join()
data = {}
for host, pinger in pingers:
_, ports = pinger.result()
data[host] = ports
j = json.dumps(data)
print(j)