Python network "scanner"


So i wanted to know what hosts in my network are up and what are their mac addresses.

nmap -sn does a good job, but the output is not the best to parse imho .. and also mac addresses are only shown to root..

So i looked at python3-nmap and wrote a little script to do that .. of course it still won't show the MAC addresses there for non root .

Too lazy to call "arp" and then parse the output i looked for an alternative and found the arpreq module which queries the kernel apr table - and since just before i scanned for hosts that should have everything. -- Also tried with SCAPY, but same problem .. only for root will it show that ..(i am aware as to why but don't really want to go into that now)

Added reverse dns lookup too afterwards.

Maybe someone else will need this or find some part of it useful:

#!/usr/bin/env python3

import re
import sys

import nmap3
from dns import reversename, resolver  # from dnspython package

USE_SCAPY = False  # only works as root ..

    from scapy import all as sa
    import arpreq

DEBUG = False
DEBUG2 = False  # includes dir(..)

class HostInfo:
    _ip = None
    _mac = None
    _dns = None

    def __init__(self, ip=None, mac=None, dns=None):
        self.ip = ip
        self.mac = mac
        self.dns = dns

    def __str__(self):
        return 'IP: %s - MAC: %s - DNS: %s' % (self.ip, self.mac, self.dns)

    def ip(self):
        return self._ip

    def ip(self, value):
        self._ip = value

    def mac(self):
        return self._mac

    def mac(self, value):
        self._mac = value

    def dns(self):
        return self._dns

    def dns(self, value):
        self._dns = value

class NetworkScanner:
    _n = None
    _sa = None
    _nm_hosts = []
    _hostlist = []

    def __init__(self):
        self._n = nmap3.Nmap()
        if DEBUG2:

    def find_hosts(self, subnet, scan_type="-sn"):
        self._nm_hosts = self._n.nmap_list_scan(subnet, scan_type)
        for host in self._nm_hosts:
            h = HostInfo(host['addr'])
            if DEBUG:
            if USE_SCAPY:
                h.mac = sa.getmacbyip(host['addr'])  # only works as root ..
                # use aprreq to query the kernel arp table since it should have it anyway
                h.mac = arpreq.arpreq(host['addr'])
            rev_name = reversename.from_address(h.ip)
                h.dns = str(resolver.query(rev_name, "PTR")[0])
            except Exception as e:
                if DEBUG:
        return self._nm_hosts, self._hostlist

if __name__ == '__main__':
    ns = NetworkScanner()
    subnet = input('Enter subnet name (CIDR notation): ')
    cidr_pat = re.compile("^([0-9]{1,3}\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$")
    if cidr_pat.match(subnet):
        print('Querying subnet {0}'.format(subnet))
        print('Invalid Subnet specification')
    hosts, hl = ns.find_hosts(subnet)
    for hi in hl:
    if DEBUG2:

The next part will be to generate my (part of) DHCP config for fixed addresses from this .. or at least a template for it since I intend to use it with DNS of course

Currently unrated


There are currently no comments

New Comment


required (not published)