86 lines
2.4 KiB
Plaintext
86 lines
2.4 KiB
Plaintext
|
#!/usr/bin/python
|
||
|
# Monitor leases if ISC-DHCPD
|
||
|
|
||
|
import os, sys, time, re, calendar
|
||
|
|
||
|
conf_file = None
|
||
|
for path in [ '/etc/dhcpd.conf', '/etc/dhcp/dhcpd.conf', '/usr/local/etc/dhcpd.conf' ]:
|
||
|
if os.path.exists(path):
|
||
|
conf_file = path
|
||
|
break
|
||
|
|
||
|
leases_file = None
|
||
|
for path in [
|
||
|
'/var/lib/dhcp/db/dhcpd.leases',
|
||
|
'/var/lib/dhcp/dhcpd.leases',
|
||
|
'/var/lib/dhcpd/dhcpd.leases', # CentOS
|
||
|
]:
|
||
|
if os.path.exists(path):
|
||
|
leases_file = path
|
||
|
break
|
||
|
|
||
|
# If no configuration and leases are found, we assume that
|
||
|
# no dhcpd is running.
|
||
|
if not conf_file or not leases_file:
|
||
|
sys.exit(0)
|
||
|
|
||
|
pidof_dhcpd = os.popen("pidof dhcpd").read().strip()
|
||
|
sys.stdout.write('<<<isc_dhcpd>>>\n[general]\nPID: %s\n' % pidof_dhcpd)
|
||
|
|
||
|
sys.stdout.write('[pools]\n')
|
||
|
|
||
|
|
||
|
def parse_config(filename):
|
||
|
for line in file(filename):
|
||
|
line = line.strip()
|
||
|
if line.startswith("include"):
|
||
|
included_file = re.search('include\s+"(.*)"', line).group(1)
|
||
|
parse_config(included_file)
|
||
|
elif line.startswith("range"):
|
||
|
sys.stdout.write(line[5:].strip("\t ;") + "\n")
|
||
|
|
||
|
parse_config(conf_file)
|
||
|
|
||
|
|
||
|
# lease 10.1.1.81 {
|
||
|
# starts 3 2015/09/09 11:42:20;
|
||
|
# ends 3 2015/09/09 19:42:20;
|
||
|
# tstp 3 2015/09/09 19:42:20;
|
||
|
# cltt 3 2015/09/09 11:42:20;
|
||
|
# binding state free;
|
||
|
# hardware ethernet a4:5e:60:de:1f:c3;
|
||
|
# uid "\001\244^`\336\037\303";
|
||
|
# set ddns-txt = "318c69bae8aeae6f8c723e96de933c7149";
|
||
|
# set ddns-fwd-name = "Sebastians-MBP.dhcp.mathias-kettner.de";
|
||
|
# }
|
||
|
|
||
|
sys.stdout.write('[leases]\n')
|
||
|
now = time.time()
|
||
|
ip_address = None
|
||
|
binding_state = None
|
||
|
seen_addresses = set()
|
||
|
for line in file(leases_file):
|
||
|
parts = line.strip().rstrip(";").split()
|
||
|
if not parts:
|
||
|
continue
|
||
|
|
||
|
if parts[0] == "lease":
|
||
|
ip_address = parts[1]
|
||
|
elif parts[0] == "ends":
|
||
|
if parts[1] != "never":
|
||
|
ends_date_string = parts[2] + " " + parts[3]
|
||
|
ends_date = calendar.timegm(time.strptime(ends_date_string, "%Y/%m/%d %H:%M:%S"))
|
||
|
if ends_date < now:
|
||
|
ip_address = None # skip this address, this lease is outdated
|
||
|
|
||
|
elif parts[0] == "binding" and parts[1] == "state":
|
||
|
binding_state = parts[2]
|
||
|
|
||
|
elif parts[0] == "}":
|
||
|
if ip_address and binding_state == "active" and ip_address not in seen_addresses:
|
||
|
sys.stdout.write("%s\n" % ip_address)
|
||
|
seen_addresses.add(ip_address)
|
||
|
ip_address = None
|
||
|
binding_state = None
|
||
|
|