If you have been given a list of IP addresses of a few machines on your network and you are asked to write a script to find out which hosts are inactive periodically, you would want to create a network scanner type program without installing anything on the target host computers.
This recipe requires installing the Scapy library (> 2.2), which can be obtained at http://www.secdev.org/projects/scapy/files/scapy-latest.zip.
We can use Scapy, a mature network-analyzing, third-party library, to launch an ICMP scan. Since we would like to do it periodically, we need Python's sched
module to schedule the scanning tasks.
Listing 3.7 shows us how to detect inactive machines, as follows:
#!/usr/bin/env python # Python Network Programming Cookbook -- Chapter – 3 # This program is optimized for Python 2.7. # It may run on any other version with/without modifications. # This recipe requires scapy-2.2.0 or higher import argparse import time import sched from scapy.all import sr, srp, IP, UDP, ICMP, TCP, ARP, Ether RUN_FREQUENCY = 10 scheduler = sched.scheduler(time.time, time.sleep) def detect_inactive_hosts(scan_hosts): """ Scans the network to find scan_hosts are live or dead scan_hosts can be like 10.0.2.2-4 to cover range. See Scapy docs for specifying targets. """ global scheduler scheduler.enter(RUN_FREQUENCY, 1, detect_inactive_hosts, (scan_hosts, )) inactive_hosts = [] try: ans, unans = sr(IP(dst=scan_hosts)/ICMP(),retry=0, timeout=1) ans.summary(lambda(s,r) : r.sprintf("%IP.src% is alive")) for inactive in unans: print "%s is inactive" %inactive.dst inactive_hosts.append(inactive.dst) print "Total %d hosts are inactive" %(len(inactive_hosts)) except KeyboardInterrupt: exit(0) if __name__ == "__main__": parser = argparse.ArgumentParser(description='Python networking utils') parser.add_argument('--scan-hosts', action="store", dest="scan_hosts", required=True) given_args = parser.parse_args() scan_hosts = given_args.scan_hosts scheduler.enter(1, 1, detect_inactive_hosts, (scan_hosts, )) scheduler.run()
The output of this script will be something like the following command:
$ sudo python 3_7_detect_inactive_machines.py --scan-hosts=10.0.2.2-4 Begin emission: .*...Finished to send 3 packets. . Received 6 packets, got 1 answers, remaining 2 packets 10.0.2.2 is alive 10.0.2.4 is inactive 10.0.2.3 is inactive Total 2 hosts are inactive Begin emission: *.Finished to send 3 packets. Received 3 packets, got 1 answers, remaining 2 packets 10.0.2.2 is alive 10.0.2.4 is inactive 10.0.2.3 is inactive Total 2 hosts are inactive
The preceding script first takes a list of network hosts, scan_hosts
, from the command line. It then creates a schedule to launch the detect_inactive_hosts()
function after a one-second delay. The target function takes the scan_hosts
argument and calls Scapy's sr()
function.
This function schedules itself to rerun after every 10 seconds by calling the schedule.enter()
function once again. This way, we run this scanning task periodically.
Scapy's sr()
scanning function takes an IP, protocol and some scan-control information. In this case, the IP()
method passes scan_hosts
as the destination hosts to scan, and the protocol is specified as ICMP. This can also be TCP or UDP. We do not specify a retry and one-second timeout to run this script faster. However, you can experiment with the options that suit you.
The scanning sr()
function returns the hosts that answer and those that don't as a tuple. We check the hosts that don't answer, build a list, and print that information.
3.22.74.232