ping scanner using asyncio
Project description
Networkscan
Networkscan is a fast host scanner written in python. It can be used in command line or as a python library.
The advantages of that program are:
- it can perform fast pings (thanks to the use of coroutines)
- it can be used as a command line program or as a python library
- it can create a list of IP address hosts as a output for easy IP address manipulation
- it can create a yaml host inventory compatible with Nornir
Compatibility
Networkscan requires python 3 and the following python libraries:
- asyncio
- ipaddress
- platform
- sys
It works on Windows and Linux.
Installation
pip install networkscan
Command line usage
1 - Available options
Here are the available options for the software:
(project1) [eorain@centos7 python]$ ./networkscan.py Usage: networkscan.py network_to_scan [-h] [-q] [-m] [-w [hosts.yaml]] Options : network_to_scan The network or IP address to scan using fast pings. Examples: "192.168.0.0/24", "10.0.0.1", "172.16.1.128/28", etc. -h Help -m Mute mode (nothing is displayed on screen) -q Quiet mode (just the list of hosts found is displayed) -w [hosts.yaml] Write a yaml host file with an optional filename (default name is hosts.yaml) (project1) [eorain@centos7 python]$
2 - How to scan a /24 network
networkscan.py 192.168.0.0/24
(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/24 Network to scan: 192.168.0.0/24 Prefix to scan: 24 Number of hosts to scan: 254 Scanning hosts... List of hosts found: 192.168.0.10 192.168.0.11 192.168.0.12 192.168.0.100 192.168.0.101 192.168.0.111 192.168.0.1 Number of hosts found: 7 (project1) [eorain@centos7 python]$
3 - How to scan a /28 network displaying just the name of the hosts (quiet mode)
networkscan.py 192.168.0.0/28 -q
(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/28 -q 192.168.0.1 192.168.0.10 192.168.0.11 192.168.0.12 (project1) [eorain@centos7 python]$
4 - How to scan a /25 network then to save the list of hosts into a text file (quiet mode and redirection of the output into a file)
networkscan.py 192.168.0.0/25 -q >inventory.txt
(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/25 -q >inventory.txt (project1) [eorain@centos7 python]$ (project1) [eorain@centos7 python]$ cat inventory.txt 192.168.0.100 192.168.0.101 192.168.0.111 192.168.0.1 192.168.0.10 192.168.0.11 192.168.0.12 (project1) [eorain@centos7 python]$
4 - How to scan a /23 network then save the list of hosts into a yaml file compatible with Nornir syntax (mute mode and creation of a yaml file)
Please note that when no file is specified with the parameter "-w" then a "hosts.yaml" file is created by default. With the command "networkscan.py 192.168.0.0/23 -m -w foo.yaml" you do create a file named "foo.yaml".
networkscan.py 192.168.0.0/23 -m -w
(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/23 -m -w (project1) [eorain@centos7 python]$ ls hos* hosts.yaml (project1) [eorain@centos7 python]$
hosts.yaml:
--- device1: hostname: 192.168.0.1 groups: - device_discovered device2: hostname: 192.168.0.100 groups: - device_discovered device3: hostname: 192.168.0.101 groups: - device_discovered device4: hostname: 192.168.0.10 groups: - device_discovered device5: hostname: 192.168.0.11 groups: - device_discovered device6: hostname: 192.168.0.12 groups: - device_discovered device7: hostname: 192.168.0.111 groups: - device_discovered
Python library usage
1 - A simple script
The following script just scan a network then displays the list of host found.
python script:
#!/usr/bin/env python3 # Import Python library import networkscan # Main function if __name__ == '__main__': # Define the network to scan my_network = "192.168.0.0/24" # Create the object my_scan = networkscan.Networkscan(my_network) # Run the scan of hosts using pings my_scan.run() # Display the IP address of all the hosts found for i in my_scan.list_of_hosts_found: print(i)
output:
192.168.0.100
192.168.0.101
192.168.0.111
192.168.0.1
192.168.0.10
192.168.0.11
192.168.0.12
2 - An advanced script
This script scans a network then it creates a yaml file with the list of hosts found.
write_file() method accepts two optional parameters:
def write_file(self, file_type=0, filename="hosts.yaml"): """ Method to write a file with the list of the detected hosts """ # Input: # # - file_type (integer, optional): 0, Nornir file (default value) # 1, Text file as output file # - filename (string, optional): the name of the file to be written ("hosts.yaml" # is the default value) # # Ouput: # A text file with the list of detected hosts ("hosts.yaml" is the default value) # return 0 if no error occured
python script:
#!/usr/bin/env python3 # Import Python library import networkscan # Main function if __name__ == '__main__': # Define the network to scan my_network = "192.168.0.0/24" # Create the object my_scan = networkscan.Networkscan(my_network) # Display information print("Network to scan: " + str(my_scan.network)) print("Prefix to scan: " + str(my_scan.network.prefixlen)) print("Number of hosts to scan: " + str(my_scan.nbr_host)) # Run the network scan print("Scanning hosts...") # Run the scan of hosts using pings my_scan.run() # Display information print("List of hosts found:") # Display the IP address of all the hosts found for i in my_scan.list_of_hosts_found: print(i) # Display information print("Number of hosts found: " + str(my_scan.nbr_host_found)) # Write the file on disk res = my_scan.write_file() # Error while writting the file? if res: # Yes print("Write error with file " + my_scan.filename) else: # No error print("Data saved into file " + my_scan.filename)
Performance
Here are the results I had with a single process with 1 second timeout ping using asyncio and without asyncio.
Number of hosts | 1 | 2 | 2 | 6 | 14 | 30 | 62 | 126 | 254 | 510 | 1022 |
---|---|---|---|---|---|---|---|---|---|---|---|
Network | /32 | /31 | /30 | /29 | /28 | /27 | /26 | /25 | /24 | /23 | /22 |
Networkscan (sec) | 0,184 | 1,178 | 1,163 | 1,213 | 1,232 | 1,411 | 1,951 | 2,23 | 5,104 | 7,055 | 18,196 |
Without asyncio (timeout 1 sec) | N/A | 1,136 | 1,115 | 5,485 | 10,194 | 26,852 | 67,258 | 130,334 | 253,168 | 321,908 | 865,858 |
What's next with the Nornir yaml file?
When you have scanned a network you have typed the entered the following command and you have got that output:
(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.96/28 -w Network to scan: 192.168.0.96/28 Prefix to scan: 28 Number of hosts to scan: 14 Scanning hosts... List of hosts found: 192.168.0.100 192.168.0.101 Number of hosts found: 2 Writting file Data saved into file hosts.yaml (project1) [eorain@centos7 python]$
The file hosts.yaml has been created.
hosts.yaml
--- --- device1: hostname: 192.168.0.100 groups: - device_discovered device2: hostname: 192.168.0.101 groups: - device_discovered
After scanning your network and creating a Nornir inventory file ("hosts.yaml") you might wonder what to do next. You can notice that the "hosts.yaml" does not include the password, login and platform information.
There are two cases:
- either all the devices are different devices with eventually different credentials
- or they are from the same type and have the credentials
a) Different devices
In the first case you will have to fill the login, password and platform reference on all the devices. 3 fields are added:
- username
- password
- platform
Here is an example:
hosts.yaml
--- device1: hostname: 192.168.0.100 username: cisco password: cisco platform: ios groups: - device_discovered device2: hostname: 192.168.0.101 username: juni password: per platform: junos groups: - device_discovered
b) Same devices and same credentials
If you are in this situation things are easier. You probably noticed that all the devices belongs to the "device_discovered" group. You can create a group file with a reference to that group then to add the missing value to the group file (with no change on the "hosts.yaml" file).
Here is an example with Cisco IOS equipments:
groups.yaml
--- device_discovered: username: cisco password: cisco platform: ios
c) Ready to use Nornir
If you are done with a) or b) now you are ready to write your code with Nornir. It is better to put your yaml files into a folder (here "inventory" folder).
Just copy the content of the "nornir_arp.py" into a file.
nornir_arp.py
#!/usr/bin/env python3 # Import Python library from nornir import InitNornir from nornir.plugins.functions.text import print_title, print_result from nornir.plugins.tasks import networking # Main function def main(): # Create a Nornir object nr = InitNornir( core={"num_workers": 100}, inventory={ "plugin": "nornir.plugins.inventory.simple.SimpleInventory", "options": { "host_file": "inventory/hosts.yaml", "group_file": "inventory/groups.yaml" } } ) # Run Nornir task (here getting the ARP table of the devices) result = nr.run(task=networking.napalm_get,name=" ARP table ",getters=["arp_table"]) # Display the result print_title("Display ARP table of the network devices") print_result(result) # Main function call if __name__ == '__main__': main()
You should get that file structure:
|--- nornir_arp.py |--- inventory | --- groups.yaml | --- hosts.yaml |
You can then run your Nornir program in python.
(project1) [eorain@centos7 python]$ ./nornir_arp.py **** Display ARP table of the network devices ********************************** ARP table ********************************************************************* * device1 ** changed : False *************************************************** vvvv ARP table ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO { 'arp_table': [ { 'age': 2.0, 'interface': 'Ethernet2/0', 'ip': '192.168.0.1', 'mac': 'AC:74:99:B3:27:EF'}, { 'age': 10.0, 'interface': 'Ethernet2/0', 'ip': '192.168.0.11', 'mac': '8A:78:01:80:87:DD'}, { 'age': 0.0, 'interface': 'Ethernet2/0', 'ip': '192.168.0.100', 'mac': '8A:FF:18:CC:00:48'}]} ^^^^ END ARP table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * device2 ** changed : False *************************************************** vvvv ARP table ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO { 'arp_table': [ { 'age': 2.0, 'interface': 'Ethernet2/0', 'ip': '192.168.0.1', 'mac': 'AC:74:99:B3:27:EF'}, { 'age': 10.0, 'interface': 'Ethernet2/0', 'ip': '192.168.0.11', 'mac': '8A:78:01:80:87:DD'}, { 'age': 0.0, 'interface': 'Ethernet2/0', 'ip': '192.168.0.101', 'mac': '88:78:44:0A:DE:13'}, { 'age': 0.0, 'interface': 'Ethernet2/2', 'ip': '192.168.255.1', 'mac': '88:78:44:0A:DE:19'}]} ^^^^ END ARP table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (project1) [eorain@centos7 python]$
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Filename, size | File type | Python version | Upload date | Hashes |
---|---|---|---|---|
Filename, size networkscan-1.0.9-py3-none-any.whl (13.0 kB) | File type Wheel | Python version py3 | Upload date | Hashes View |
Hashes for networkscan-1.0.9-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 07344e5e5b2d7afaf5703c0ea475d33a9d3b568f23e2cc3611ffa957e4cc91b9 |
|
MD5 | a5fc97356ad7658dd4fa313253e0cd38 |
|
BLAKE2-256 | 5bde2cc3af6dcf040a46c81d6d0697d1acbb77a19fb72005576676f6ab576d46 |