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