Thanks for the input guys, here's a followup after I've been playing with splunk for a little while.
Since no DHCP logs are available, the only way I can solve this is to execute an NBTSTAT on a list of IP addresses. The question was, when/how do you do this.
First off, NBTSTAT isn't available through splunk and/or Ubuntu, so I installed the nmblookup binary from my distro (on Ubuntu, I did sudo apt-cache search nmblookup and installed the resulting package)
I then created the following Python script in $SPLUNKBASE/etc/apps/myapp/bin/nmblookup.py:
def lookup(ip):
if ipval.match(ip):
process = subprocess.Popen([nmb_bin, '-A', ip],executable = nmb_bin, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.read()
lines = output.split('\n')
for l in lines:
ipmatch = ipre.match(l)
if ipmatch != None:
return ipmatch.group(1)
else:
print ip + " is an invalid ip address"
return None
def main():
if len(sys.argv) != 3:
print "Usage: python nmblookup.py [ip field] [host field]"
sys.exit(0);
ipf = sys.argv[1]
hostf = sys.argv[2]
r = csv.reader(sys.stdin)
w = None
header = []
first = True
for line in r:
if first:
header = line
if ipf not in header or hostf not in header:
print "Host and IP Fields not in header"
sys.exit(0)
csv.writer(sys.stdout).writerow(header)
w = csv.DictWriter(sys.stdout, header)
first = False
continue
result = {}
i = 0
while i < len(header):
if i < len(line):
result[header[i]] = line[i]
else:
result[header[i]] = ''
i += 1
# Perform the lookup
if len(result[ipf]) and len(result[hostf]):
w.writerow(result)
elif len(result[ipf]):
hostname = lookup(result[ipf])
result[hostf] = hostname
w.writerow(result)46
nmb_bin = "/usr/bin/nmblookup"
ipval = re.compile(r"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b")
ipre = re.compile("^\s+(.*)\s+<00>\s+-\s+M\s+ ")
main()
Once this was done, I registered the command inside of transforms.conf:
46
[nbtstat_hostlookup]
external_cmd = nmblookup.py clientip clienthost
fields_list = clientip clienthost46
46
Now comes the crux of the matter. I created a scheduled search that queries my log sources every 7 minutes (DHCP might vary, so this is a best-effort basis based on how many logs you get).
This search builds a list of IP addresses observed inside my indexed log sources along with the time, executes the nbtstat and then generates a lookup table that I can use at a later date!
Here's the search string, I'll leave the remainder of the setup to you (don't hesitate to ask if you need help figuring out the rest).
| eval DHCP=if(cidrmatch("192.168.0.0/24",src_ip),"TRUE","FALSE") | search DHCP="TRUE" | stats first(_time) as time by src_ip | sort src_ip desc | lookup nbtstat_hostlookup clientip as src_ip OUTPUT clienthost | where isnotnull(clienthost) | fields time,src_ip,clienthost | fields - _time,_raw,_indextime,_cd,_serial,_si,_sourcetype | append[inputlookup nbtstat_lookup_table] | outputlookup nbtstat_lookup_table
... View more