{ "info": { "author": "Eric ORAIN", "author_email": "", "bugtrack_url": null, "classifiers": [], "description": "# Networkscan\n\nNetworkscan is a fast host scanner written in python. It can be used in command line or as a python library.\n\nThe advantages of that program are:\n- it can perform fast pings (thanks to the use of coroutines)\n- it can be used as a command line program or as a python library\n- it can create a list of IP address hosts as a output for easy IP address manipulation\n- it can create a yaml host inventory compatible with Nornir\n\n---\n\n## Compatibility\n\nNetworkscan requires python 3 and the following python libraries:\n- asyncio \n- ipaddress\n- platform\n- sys\n\nIt works on Windows and Linux.\n\n---\n\n## Installation\n\n> pip install networkscan\n\n---\n\n## Command line usage\n\n### 1 - Available options\n\nHere are the available options for the software:\n``` bash\n(project1) [eorain@centos7 python]$ ./networkscan.py\n\nUsage: networkscan.py network_to_scan [-h] [-q] [-m] [-w [hosts.yaml]]\n\nOptions :\n network_to_scan The network or IP address to scan using fast pings.\n Examples: \"192.168.0.0/24\", \"10.0.0.1\", \"172.16.1.128/28\", etc.\n -h Help\n -m Mute mode (nothing is displayed on screen)\n -q Quiet mode (just the list of hosts found is displayed)\n -w [hosts.yaml] Write a yaml host file with an optional filename (default name is hosts.yaml)\n\n(project1) [eorain@centos7 python]$\n```\n\n### 2 - How to scan a /24 network\n\n> networkscan.py 192.168.0.0/24\n\n``` bash\n(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/24\nNetwork to scan: 192.168.0.0/24\nPrefix to scan: 24\nNumber of hosts to scan: 254\nScanning hosts...\nList of hosts found:\n192.168.0.10\n192.168.0.11\n192.168.0.12\n192.168.0.100\n192.168.0.101\n192.168.0.111\n192.168.0.1\nNumber of hosts found: 7\n(project1) [eorain@centos7 python]$\n```\n\n### 3 - How to scan a /28 network displaying just the name of the hosts (quiet mode)\n\n> networkscan.py 192.168.0.0/28 -q\n\n``` bash\n(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/28 -q\n192.168.0.1\n192.168.0.10\n192.168.0.11\n192.168.0.12\n(project1) [eorain@centos7 python]$\n```\n\n### 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)\n\n> networkscan.py 192.168.0.0/25 -q >inventory.txt\n\n``` bash\n(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/25 -q >inventory.txt\n(project1) [eorain@centos7 python]$\n(project1) [eorain@centos7 python]$ cat inventory.txt\n192.168.0.100\n192.168.0.101\n192.168.0.111\n192.168.0.1\n192.168.0.10\n192.168.0.11\n192.168.0.12\n(project1) [eorain@centos7 python]$\n```\n\n### 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)\n\n---\n\nPlease 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\".\n\n---\n\n> networkscan.py 192.168.0.0/23 -m -w\n\n``` bash\n(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.0/23 -m -w\n(project1) [eorain@centos7 python]$ ls hos*\nhosts.yaml\n(project1) [eorain@centos7 python]$\n```\n\n**hosts.yaml:**\n\n``` yaml\n---\ndevice1:\n hostname: 192.168.0.1\n groups:\n - device_discovered\n\ndevice2:\n hostname: 192.168.0.100\n groups:\n - device_discovered\n\ndevice3:\n hostname: 192.168.0.101\n groups:\n - device_discovered\n\ndevice4:\n hostname: 192.168.0.10\n groups:\n - device_discovered\n\ndevice5:\n hostname: 192.168.0.11\n groups:\n - device_discovered\n\ndevice6:\n hostname: 192.168.0.12\n groups:\n - device_discovered\n\ndevice7:\n hostname: 192.168.0.111\n groups:\n - device_discovered\n\n```\n\n---\n\n## Python library usage\n\n### 1 - A simple script\n\nThe following script just scan a network then displays the list of host found.\n\n**python script:**\n``` python\n#!/usr/bin/env python3\n\n# Import Python library\nimport networkscan\n\n# Main function\nif __name__ == '__main__':\n\n # Define the network to scan\n my_network = \"192.168.0.0/24\"\n\n # Create the object\n my_scan = networkscan.Networkscan(my_network)\n\n # Run the scan of hosts using pings\n my_scan.run()\n\n # Display the IP address of all the hosts found\n for i in my_scan.list_of_hosts_found:\n print(i)\n\n```\n\n**output:**\n```\n192.168.0.100\n192.168.0.101\n192.168.0.111\n192.168.0.1\n192.168.0.10\n192.168.0.11\n192.168.0.12\n```\n\n### 2 - An advanced script\n\nThis script scans a network then it creates a yaml file with the list of hosts found.\n\nwrite_file() method accepts two optional parameters: \n\n``` python\n def write_file(self, file_type=0, filename=\"hosts.yaml\"):\n \"\"\" Method to write a file with the list of the detected hosts \"\"\"\n\n # Input:\n #\n # - file_type (integer, optional): 0, Nornir file (default value)\n # 1, Text file as output file\n # - filename (string, optional): the name of the file to be written (\"hosts.yaml\"\n # is the default value)\n #\n # Ouput:\n # A text file with the list of detected hosts (\"hosts.yaml\" is the default value)\n # return 0 if no error occured\n```\n\n**python script:**\n``` python\n#!/usr/bin/env python3\n\n# Import Python library\nimport networkscan\n\n# Main function\nif __name__ == '__main__':\n\n # Define the network to scan\n my_network = \"192.168.0.0/24\"\n\n # Create the object\n my_scan = networkscan.Networkscan(my_network)\n\n # Display information\n print(\"Network to scan: \" + str(my_scan.network))\n print(\"Prefix to scan: \" + str(my_scan.network.prefixlen))\n print(\"Number of hosts to scan: \" + str(my_scan.nbr_host))\n\n # Run the network scan\n print(\"Scanning hosts...\")\n\n # Run the scan of hosts using pings\n my_scan.run()\n\n # Display information\n print(\"List of hosts found:\")\n\n # Display the IP address of all the hosts found\n for i in my_scan.list_of_hosts_found:\n print(i)\n\n # Display information\n print(\"Number of hosts found: \" + str(my_scan.nbr_host_found))\n\n # Write the file on disk\n res = my_scan.write_file()\n\n # Error while writting the file?\n if res:\n # Yes\n print(\"Write error with file \" + my_scan.filename)\n\n else:\n # No error\n print(\"Data saved into file \" + my_scan.filename)\n\n```\n\n---\n\n## Performance\n\nHere are the results I had with a single process with 1 second timeout ping using asyncio and without asyncio.\n\n\nNumber of hosts | 1 | 2 | 2 | 6 | 14 | 30 | 62 | 126 | 254 | 510 | 1022\n| :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | \nNetwork | /32 | /31 | /30 | /29 | /28 | /27 | /26 | /25 | /24 | /23 | /22\nNetworkscan (sec) | 0,184 | 1,178 | 1,163 | 1,213 | 1,232 | 1,411 | 1,951 | 2,23 | 5,104 | 7,055 | 18,196\nWithout 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\n\n## What's next with the Nornir yaml file?\n\nWhen you have scanned a network you have typed the entered the following command and you have got that output:\n\n``` bash\n(project1) [eorain@centos7 python]$ ./networkscan.py 192.168.0.96/28 -w\nNetwork to scan: 192.168.0.96/28\nPrefix to scan: 28\nNumber of hosts to scan: 14\nScanning hosts...\nList of hosts found:\n192.168.0.100\n192.168.0.101\nNumber of hosts found: 2\nWritting file\nData saved into file hosts.yaml\n(project1) [eorain@centos7 python]$\n ```\n\nThe file hosts.yaml has been created.\n\n**hosts.yaml**\n``` yaml\n---\n---\ndevice1:\n hostname: 192.168.0.100\n groups:\n - device_discovered\n\ndevice2:\n hostname: 192.168.0.101\n groups:\n - device_discovered\n\n ```\n\nAfter 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.\n\nThere are two cases:\n- either all the devices are different devices with eventually different credentials\n- or they are from the same type and have the credentials\n\n### a) Different devices\n\nIn the first case you will have to fill the login, password and platform reference on all the devices. 3 fields are added:\n- username\n- password\n- platform\n\nHere is an example:\n\n**hosts.yaml**\n``` yaml\n---\ndevice1:\n hostname: 192.168.0.100\n username: cisco\n password: cisco\n platform: ios\n groups:\n - device_discovered\n\ndevice2:\n hostname: 192.168.0.101\n username: juni\n password: per\n platform: junos\n groups:\n - device_discovered\n\n ```\n\n### b) Same devices and same credentials\n\nIf 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).\n\nHere is an example with Cisco IOS equipments:\n\n**groups.yaml**\n``` yaml\n---\ndevice_discovered:\n username: cisco\n password: cisco\n platform: ios\n```\n\n### c) Ready to use Nornir\n\nIf 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).\n\nJust copy the content of the \"nornir_arp.py\" into a file.\n\n**nornir_arp.py**\n\n``` python\n#!/usr/bin/env python3\n\n# Import Python library\nfrom nornir import InitNornir\nfrom nornir.plugins.functions.text import print_title, print_result\nfrom nornir.plugins.tasks import networking\n\n\n# Main function\ndef main():\n\n # Create a Nornir object\n nr = InitNornir(\n core={\"num_workers\": 100},\n inventory={\n \"plugin\": \"nornir.plugins.inventory.simple.SimpleInventory\",\n \"options\": {\n \"host_file\": \"inventory/hosts.yaml\",\n \"group_file\": \"inventory/groups.yaml\"\n }\n }\n )\n\n # Run Nornir task (here getting the ARP table of the devices)\n result = nr.run(task=networking.napalm_get,name=\" ARP table \",getters=[\"arp_table\"])\n\n # Display the result\n print_title(\"Display ARP table of the network devices\")\n print_result(result)\n\n\n# Main function call\nif __name__ == '__main__':\n main()\n```\n\nYou should get that file structure:\n``` bash\n|--- nornir_arp.py\n|--- inventory\n|\u00a0 \u00a0 --- groups.yaml\n| \u00a0\u00a0 --- hosts.yaml\n|\n```\n\nYou can then run your Nornir program in python.\n\n``` bash\n(project1) [eorain@centos7 python]$ ./nornir_arp.py\n**** Display ARP table of the network devices **********************************\n ARP table *********************************************************************\n* device1 ** changed : False ***************************************************\nvvvv ARP table ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO\n{ 'arp_table': [ { 'age': 2.0,\n 'interface': 'Ethernet2/0',\n 'ip': '192.168.0.1',\n 'mac': 'AC:74:99:B3:27:EF'},\n { 'age': 10.0,\n 'interface': 'Ethernet2/0',\n 'ip': '192.168.0.11',\n 'mac': '8A:78:01:80:87:DD'},\n { 'age': 0.0,\n 'interface': 'Ethernet2/0',\n 'ip': '192.168.0.100',\n 'mac': '8A:FF:18:CC:00:48'}]}\n^^^^ END ARP table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n* device2 ** changed : False ***************************************************\nvvvv ARP table ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO\n{ 'arp_table': [ { 'age': 2.0,\n 'interface': 'Ethernet2/0',\n 'ip': '192.168.0.1',\n 'mac': 'AC:74:99:B3:27:EF'},\n { 'age': 10.0,\n 'interface': 'Ethernet2/0',\n 'ip': '192.168.0.11',\n 'mac': '8A:78:01:80:87:DD'},\n { 'age': 0.0,\n 'interface': 'Ethernet2/0',\n 'ip': '192.168.0.101',\n 'mac': '88:78:44:0A:DE:13'},\n { 'age': 0.0,\n 'interface': 'Ethernet2/2',\n 'ip': '192.168.255.1',\n 'mac': '88:78:44:0A:DE:19'}]}\n^^^^ END ARP table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n(project1) [eorain@centos7 python]$\n```\n\n\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ericorain/python/tree/master/networkscan", "keywords": "ping networkscan scanner", "license": "Apache License", "maintainer": "", "maintainer_email": "", "name": "networkscan", "package_url": "https://pypi.org/project/networkscan/", "platform": "ALL", "project_url": "https://pypi.org/project/networkscan/", "project_urls": { "Homepage": "https://github.com/ericorain/python/tree/master/networkscan" }, "release_url": "https://pypi.org/project/networkscan/1.0.9/", "requires_dist": null, "requires_python": ">=3.7", "summary": "ping scanner using asyncio", "version": "1.0.9" }, "last_serial": 5463724, "releases": { "1.0.9": [ { "comment_text": "", "digests": { "md5": "a5fc97356ad7658dd4fa313253e0cd38", "sha256": "07344e5e5b2d7afaf5703c0ea475d33a9d3b568f23e2cc3611ffa957e4cc91b9" }, "downloads": -1, "filename": "networkscan-1.0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "a5fc97356ad7658dd4fa313253e0cd38", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 13007, "upload_time": "2019-06-28T22:03:14", "url": "https://files.pythonhosted.org/packages/5b/de/2cc3af6dcf040a46c81d6d0697d1acbb77a19fb72005576676f6ab576d46/networkscan-1.0.9-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a5fc97356ad7658dd4fa313253e0cd38", "sha256": "07344e5e5b2d7afaf5703c0ea475d33a9d3b568f23e2cc3611ffa957e4cc91b9" }, "downloads": -1, "filename": "networkscan-1.0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "a5fc97356ad7658dd4fa313253e0cd38", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 13007, "upload_time": "2019-06-28T22:03:14", "url": "https://files.pythonhosted.org/packages/5b/de/2cc3af6dcf040a46c81d6d0697d1acbb77a19fb72005576676f6ab576d46/networkscan-1.0.9-py3-none-any.whl" } ] }