Module: check_mk
Branch: master
Commit: d06762d9329b88a998188d08cef21cbb4363b84b
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=d06762d9329b88…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Fri Nov 6 14:31:21 2015 +0100
#2741 FIX isc_dhcpd: Fix problem where outdated leases where counted as active
---
.werks/2741 | 9 +++++
ChangeLog | 1 +
agents/plugins/isc_dhcpd | 92 ++++++++++++++++++++++++++++++++--------------
3 files changed, 74 insertions(+), 28 deletions(-)
diff --git a/.werks/2741 b/.werks/2741
new file mode 100644
index 0000000..d2afb35
--- /dev/null
+++ b/.werks/2741
@@ -0,0 +1,9 @@
+Title: isc_dhcpd: Fix problem where outdated leases where counted as active
+Level: 1
+Component: checks
+Compatible: compat
+Version: 1.2.7i4
+Date: 1446816658
+Class: fix
+
+
diff --git a/ChangeLog b/ChangeLog
index d09590c..cfc075e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -53,6 +53,7 @@
* 2725 FIX: Dynamic levels: Enforce config of levels for filesystems larger than 0
bytes...
* 2726 FIX: veeam_backup_status: Fixed missing agent section error in case of aborted
tasks
* 2727 FIX: ibm_imm_health: Fixed unhandled exception when SNMP info is missing
+ * 2741 FIX: isc_dhcpd: Fix problem where outdated leases where counted as active
Multisite:
* 2684 Added icons for downloading agent data / walks of hosts...
diff --git a/agents/plugins/isc_dhcpd b/agents/plugins/isc_dhcpd
index 7ac606b..22482d6 100755
--- a/agents/plugins/isc_dhcpd
+++ b/agents/plugins/isc_dhcpd
@@ -1,34 +1,70 @@
-#!/bin/bash
-# Plugin for checking a DHCP daemon running on Linux.
-# If you conf or leases file is not at one of the places
-# we look for then please add that path to the list
-# and give us feedback at feedback(a)check-mk.org
-
-for path in /etc/dhcpd.conf /etc/dhcp/dhcpd.conf ; do
- if [ -e $path ] ; then
- CONF_FILE=$path
+#!/usr/bin/python
+
+import os, sys, time
+
+conf_file = None
+for path in [ '/etc/dhcpd.conf', '/etc/dhcp/dhcpd.conf' ]:
+ if os.path.exists(path):
+ conf_file = path
break
- fi
-done
-for path in /var/lib/dhcp/db/dhcpd.leases /var/lib/dhcp/dhcpd.leases; do
- if [ -e $path ] ; then
- LEASES_FILE=$path
+leases_file = None
+for path in [ '/var/lib/dhcp/db/dhcpd.leases',
'/var/lib/dhcp/dhcpd.leases' ]:
+ if os.path.exists(path):
+ leases_file = path
break
- fi
-done
# If no configuration and leases are found, we assume that
# no dhcpd is running.
-if [ -z "$CONF_FILE" -o -z "$LEASES_FILE" ] ; then exit ; fi
-
-echo '<<<isc_dhcpd>>>'
-echo "[general]"
-echo "PID: $(pidof dhcpd)"
-echo "[pools]"
-sed -nr -e 's/;//g' -e '/^[[:space:]]*range */s///p' < $CONF_FILE
-echo "[leases]"
-sed -nr -e 's/;//g' \
- -e '/^lease */s/.* ([0-9.]+) .*/\1/p' \
- -e '/^ *binding state */s///p' < $LEASES_FILE |
- sed 'N;s/\n/ /' | sed -n '/ active/s///p' | sort -u
+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')
+for line in file(conf_file):
+ line = line.strip().rstrip(";").rstrip()
+ if line.startswith("range"):
+ sys.stdout.write(line[5:].strip() + "\n")
+
+# 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":
+ ends_date_string = parts[2] + " " + parts[3]
+ ends_date = time.mktime(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
+