Python network "scanner"

(0 comments)

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 ..

if USE_SCAPY:
    from scapy import all as sa
else:
    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)

    @property
    def ip(self):
        return self._ip

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

    @property
    def mac(self):
        return self._mac

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

    @property
    def dns(self):
        return self._dns

    @dns.setter
    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:
            print(dir(self._n))

    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:
                print(host)
            if USE_SCAPY:
                h.mac = sa.getmacbyip(host['addr'])  # only works as root ..
            else:
                # use aprreq to query the kernel arp table since it should have it anyway
                h.mac = arpreq.arpreq(host['addr'])
            self._hostlist.append(h)
            rev_name = reversename.from_address(h.ip)
            try:
                h.dns = str(resolver.query(rev_name, "PTR")[0])
            except Exception as e:
                if DEBUG:
                    print(e)
        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))
    else:
        print('Invalid Subnet specification')
        sys.exit(1)
    hosts, hl = ns.find_hosts(subnet)
    for hi in hl:
        print(hi)
    if DEBUG2:
        print(dir(sa))

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

Comments

There are currently no comments

New Comment

required

required (not published)

optional

required

Recent Posts

Archive

2020
2019
2018
2014
2012
2011
2010
2009
2008
2007

Categories

Authors

Feeds

RSS / Atom