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
Share on Twitter Share on Facebook
Comments
There are currently no comments
New Comment