Project

General

Profile

Download (12 KB) Statistics
| Branch: | Tag: | Revision:
1 4d875b4f Scott Ullrich
<?php
2 b46bfcf5 Bill Marquette
/* $Id$ */
3 5b237745 Scott Ullrich
/*
4
	diag_dhcp_leases.php
5 4d875b4f Scott Ullrich
	Copyright (C) 2004 Scott Ullrich
6 5b237745 Scott Ullrich
	All rights reserved.
7 4d875b4f Scott Ullrich
8
	originially part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11
12 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14 4d875b4f Scott Ullrich
15 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17 4d875b4f Scott Ullrich
18 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
19
	   notice, this list of conditions and the following disclaimer in the
20
	   documentation and/or other materials provided with the distribution.
21 4d875b4f Scott Ullrich
22 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
	POSSIBILITY OF SUCH DAMAGE.
32
*/
33
34 6b07c15a Matthew Grooms
##|+PRIV
35
##|*IDENT=page-status-dhcpleases
36
##|*NAME=Status: DHCP leases page
37
##|*DESCR=Allow access to the 'Status: DHCP leases' page.
38
##|*MATCH=diag_dhcp_leases.php*
39
##|-PRIV
40
41
42 5b237745 Scott Ullrich
require("guiconfig.inc");
43 b63695db Scott Ullrich
44 d88c6a9f Scott Ullrich
$pgtitle = array("Status","DHCP leases");
45 b63695db Scott Ullrich
include("head.inc");
46
47 5b237745 Scott Ullrich
?>
48
49
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
50 5fd0b016 Scott Ullrich
<script src="/javascript/sorttable.js"></script>
51 5b237745 Scott Ullrich
<?php include("fbegin.inc"); ?>
52
<?php
53
54
function leasecmp($a, $b) {
55 5742ca5e Scott Ullrich
        return strcmp($a[$_GET['order']], $b[$_GET['order']]);
56
}
57
58
function adjust_gmt($dt) {
59
        $ts = strtotime($dt . " GMT");
60
        return strftime("%Y/%m/%d %H:%M:%S", $ts);
61 5b237745 Scott Ullrich
}
62
63 428d20c4 Seth Mos
function remove_duplicate($array, $field)
64
{
65
  foreach ($array as $sub)
66
   $cmp[] = $sub[$field];
67
  $unique = array_unique($cmp);
68
  foreach ($unique as $k => $rien)
69
   $new[] = $array[$k];
70
  return $new;
71 5b237745 Scott Ullrich
}
72
73 428d20c4 Seth Mos
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
74
$awk = "/usr/bin/awk";
75
/* this pattern sticks comments into a single array item */
76
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
77
/* We then split the leases file by } */
78 b4f7282c Seth Mos
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
79 5b237745 Scott Ullrich
80 428d20c4 Seth Mos
/* stuff the leases file in a proper format into a array by line */
81
exec("cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
82
$leases_count = count($leases_content);
83
84 468b0d65 Seth Mos
exec("/usr/sbin/arp -an", $rawdata);
85
$arpdata = array();
86
foreach ($rawdata as $line) {
87
	$elements = explode(' ',$line);
88
	if ($elements[3] != "(incomplete)") {
89
		$arpent = array();
90
		$arpent['ip'] = trim(str_replace(array('(',')'),'',$elements[1]));
91
		// $arpent['mac'] = trim($elements[3]);
92
		// $arpent['interface'] = trim($elements[5]);
93
	$arpdata[] = $arpent['ip'];
94
	}
95
}
96
97 428d20c4 Seth Mos
$pools = array();
98 5b237745 Scott Ullrich
$leases = array();
99
$i = 0;
100 b4f7282c Seth Mos
$l = 0;
101
$p = 0;
102 5b237745 Scott Ullrich
103
// Put everything together again
104 428d20c4 Seth Mos
while($i < $leases_count) {
105
	/* split the line by space */
106
	$data = explode(" ", $leases_content[$i]);
107
	/* walk the fields */
108
	$f = 0;
109
	$fcount = count($data);
110 b4f7282c Seth Mos
	/* with less then 20 fields there is nothing useful */
111
	if($fcount < 20) {
112
		$i++;
113
		continue;
114
	}
115 428d20c4 Seth Mos
	while($f < $fcount) {
116 b4f7282c Seth Mos
		switch($data[$f]) {
117
			case "failover":
118
				$pools[$p]['name'] = $data[$f+2];
119
				$pools[$p]['mystate'] = $data[$f+7];
120
				$pools[$p]['peerstate'] = $data[$f+14];
121
				$pools[$p]['mydate'] = $data[$f+10];
122
				$pools[$p]['mydate'] .= " " . $data[$f+11];
123
				$pools[$p]['peerdate'] = $data[$f+17];
124
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
125
				$p++;
126
				$i++;
127
				continue 3;
128
			case "lease":
129
				$leases[$l]['ip'] = $data[$f+1];
130
				$leases[$l]['type'] = "dynamic";
131
				$f = $f+2;
132
				break;
133
			case "starts":
134
				$leases[$l]['start'] = $data[$f+2];
135
				$leases[$l]['start'] .= " " . $data[$f+3];
136
				$f = $f+3;
137
				break;
138
			case "ends":
139
				$leases[$l]['end'] = $data[$f+2];
140
				$leases[$l]['end'] .= " " . $data[$f+3];
141
				$f = $f+3;
142
				break;
143
			case "tstp":
144
				$f = $f+3;
145
				break;
146
			case "tsfp":
147
				$f = $f+3;
148
				break;
149
			case "atsfp":
150
				$f = $f+3;
151
				break;
152
			case "cltt":
153
				$f = $f+3;
154
				break;
155
			case "binding":
156 428d20c4 Seth Mos
				switch($data[$f+2]) {
157 b4f7282c Seth Mos
					case "active":
158
						$leases[$l]['act'] = "active";
159 428d20c4 Seth Mos
						break;
160 b4f7282c Seth Mos
					case "free":
161
						$leases[$l]['act'] = "expired";
162
						$leases[$l]['online'] = "offline";
163 428d20c4 Seth Mos
						break;
164 b4f7282c Seth Mos
					case "backup":
165
						$leases[$l]['act'] = "reserved";
166
						$leases[$l]['online'] = "offline";
167 428d20c4 Seth Mos
						break;
168
				}
169 b4f7282c Seth Mos
				$f = $f+1;
170
				break;
171
			case "next":
172
				/* skip the next binding statement */
173
				$f = $f+3;
174
				break;
175
			case "hardware":
176
				$leases[$l]['mac'] = $data[$f+2];
177
				/* check if it's online and the lease is active */
178 468b0d65 Seth Mos
				if (in_array($leases[$l]['ip'], $arpdata)) {
179
					$leases[$l]['online'] = 'online';
180
				} else {
181
					$leases[$l]['online'] = 'offline';
182 14cf741d Scott Ullrich
				}
183 b4f7282c Seth Mos
				$f = $f+2;
184
				break;
185
			case "client-hostname":
186
				if($data[$f+1] <> "") {
187
					$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
188
				} else {
189
					$hostname = gethostbyaddr($leases[$l]['ip']);
190
					if($hostname <> "") {
191
						$leases[$l]['hostname'] = $hostname;
192
					}
193
				}
194
				$f = $f+1;
195
				break;
196
			case "uid":
197
				$f = $f+1;
198
				break;
199 14cf741d Scott Ullrich
		}
200 428d20c4 Seth Mos
		$f++;
201 14cf741d Scott Ullrich
	}
202 b4f7282c Seth Mos
	$l++;
203 428d20c4 Seth Mos
	$i++;
204 5b237745 Scott Ullrich
}
205 428d20c4 Seth Mos
206
/* remove duplicate items by mac address */
207 9255cbc5 Seth Mos
if(count($leases) > 0) {
208 b4f7282c Seth Mos
	$leases = remove_duplicate($leases,"ip");
209 9255cbc5 Seth Mos
}
210 b4f7282c Seth Mos
211 9255cbc5 Seth Mos
if(count($pools) > 0) {
212
	$pools = remove_duplicate($pools,"name");
213
	asort($pools);
214
}
215 428d20c4 Seth Mos
216 9252431c Scott Ullrich
foreach($config['interfaces'] as $ifname => $ifarr) {
217
	if (is_array($config['dhcpd'][$ifname]['staticmap'])) {
218
		foreach($config['dhcpd'][$ifname]['staticmap'] as $static) {
219
			$slease = array();
220
			$slease['ip'] = $static['ipaddr'];
221
			$slease['type'] = "static";
222
			$slease['mac'] = $static['mac'];
223
			$slease['start'] = gmdate("M d Y H:i:s", time());
224
			$slease['end'] = gmdate("M d Y H:i:s", time());
225
			$slease['end'] = gmdate("M d Y H:i:s", strtotime('+5 minutes'));
226 08cf5428 Scott Ullrich
			$slease['hostname'] = htmlentities($static['hostname']);
227 9252431c Scott Ullrich
			$slease['act'] = "static";
228
			$online = exec("/usr/sbin/arp -an |/usr/bin/grep {$slease['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
229
			if ($online == 1) {
230
				$slease['online'] = 'online';
231
			} else {
232
				$slease['online'] = 'offline';
233
			}
234
			$leases[] = $slease;
235
		}
236
	}
237
}
238 5b237745 Scott Ullrich
239
if ($_GET['order'])
240
	usort($leases, "leasecmp");
241 428d20c4 Seth Mos
242
?>
243
244
<?php
245
/* only print pool status when we have one */
246
if(count($pools) > 0) {
247 5b237745 Scott Ullrich
?>
248 428d20c4 Seth Mos
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
249
  <tr>
250
    <td class="listhdrr">Failover Group</a></td>
251
    <td class="listhdrr">My State</a></td>
252
    <td class="listhdrr">Since</a></td>
253
    <td class="listhdrr">Peer State</a></td>
254
    <td class="listhdrr">Since</a></td>
255
  </tr>
256
<?php
257
foreach ($pools as $data) {
258
	echo "<tr>\n";
259
	echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}&nbsp;</td>\n";
260
	echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}&nbsp;</td>\n";
261
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}&nbsp;</td>\n";
262
	echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}&nbsp;</td>\n";
263
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}&nbsp;</td>\n";
264
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
265
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
266
	echo "</tr>\n";
267
}
268
269
?>
270
</table>
271
272
<?php
273
/* only print pool status when we have one */
274
}
275
?>
276
277
<p>
278
279 5fd0b016 Scott Ullrich
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
280 5b237745 Scott Ullrich
  <tr>
281
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=ip">IP address</a></td>
282
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=mac">MAC address</a></td>
283
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=hostname">Hostname</a></td>
284
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=start">Start</a></td>
285 9252431c Scott Ullrich
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=end">End</a></td>
286
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=online">Online</a></td>
287
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=act">Lease Type</a></td>
288 5b237745 Scott Ullrich
	</tr>
289
<?php
290
foreach ($leases as $data) {
291 9252431c Scott Ullrich
	if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) {
292
		if ($data['act'] != "active" && $data['act'] != "static") {
293 5b237745 Scott Ullrich
			$fspans = "<span class=\"gray\">";
294
			$fspane = "</span>";
295
		} else {
296
			$fspans = $fspane = "";
297
		}
298 69981800 Scott Ullrich
                $lip = ip2long($data['ip']);
299 5b2177e4 Scott Ullrich
		if ($data['act'] == "static") {
300
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
301 0e616855 Scott Ullrich
				if(is_array($dhcpifconf['staticmap'])) {
302
					foreach ($dhcpifconf['staticmap'] as $staticent) {
303
						if ($data['ip'] == $staticent['ipaddr']) {
304
							$data['if'] = $dhcpif;
305
							break;
306
						}
307 5b2177e4 Scott Ullrich
					}
308
				}
309
				/* exit as soon as we have an interface */
310
				if ($data['if'] != "")
311
					break;
312
			}
313
		} else {
314 612bb4f3 Scott Ullrich
                	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {	
315 5b2177e4 Scott Ullrich
                        	if (($lip >= ip2long($dhcpifconf['range']['from'])) && ($lip <= ip2long($dhcpifconf['range']['to']))) {
316
                                	$data['if'] = $dhcpif;
317
                                	break;
318
                        	}
319
			}
320 69981800 Scott Ullrich
                }		
321 5b237745 Scott Ullrich
		echo "<tr>\n";
322 5742ca5e Scott Ullrich
                echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
323 9252431c Scott Ullrich
                if ($data['online'] != "online") {
324 37c0c49b Scott Ullrich
                        echo "<td class=\"listr\">{$fspans}<a href=\"services_wol.php?if={$data['if']}&mac={$data['mac']}\" title=\"send Wake on Lan packet to mac\">{$data['mac']}</a>{$fspane}&nbsp;</td>\n";
325
                } else {
326 9252431c Scott Ullrich
                	echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}&nbsp;</td>\n";
327 37c0c49b Scott Ullrich
                }
328 08cf5428 Scott Ullrich
                echo "<td class=\"listr\">{$fspans}"  . htmlentities($data['hostname']) . "{$fspane}&nbsp;</td>\n";
329 5742ca5e Scott Ullrich
                echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}&nbsp;</td>\n";
330
                echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}&nbsp;</td>\n";
331 9252431c Scott Ullrich
                echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}&nbsp;</td>\n";
332
                echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}&nbsp;</td>\n";
333
		
334
		if ($data['type'] == "dynamic") {
335 6a01ea44 Bill Marquette
                	echo "<td class=\"list\" valign=\"middle\"><a href=\"services_dhcp_edit.php?if={$data['if']}&mac={$data['mac']}&hostname={$data['hostname']}\">";
336 9252431c Scott Ullrich
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"add a static mapping for this MAC address\"></a></td>\n";
337
		} else {
338
                	echo "<td class=\"list\" valign=\"middle\">";
339 b86e64c1 Scott Ullrich
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus_mo.gif\" width=\"17\" height=\"17\" border=\"0\"></td>\n";
340 9252431c Scott Ullrich
		}
341
342 7477df4f Scott Ullrich
                echo "<td valign=\"middle\"><a href=\"services_wol_edit.php?if={$data['if']}&mac={$data['mac']}&descr={$data['hostname']}\">";
343 37c0c49b Scott Ullrich
		echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_wol_all.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"add a Wake on Lan mapping for this MAC address\"></a></td>\n";
344 5742ca5e Scott Ullrich
                echo "</tr>\n";
345 5b237745 Scott Ullrich
	}
346
}
347 428d20c4 Seth Mos
348 5b237745 Scott Ullrich
?>
349
</table>
350
<p>
351
<form action="diag_dhcp_leases.php" method="GET">
352
<input type="hidden" name="order" value="<?=$_GET['order'];?>">
353
<?php if ($_GET['all']): ?>
354
<input type="hidden" name="all" value="0">
355 9252431c Scott Ullrich
<input type="submit" class="formbtn" value="Show active and static leases only">
356 5b237745 Scott Ullrich
<?php else: ?>
357
<input type="hidden" name="all" value="1">
358 9252431c Scott Ullrich
<input type="submit" class="formbtn" value="Show all configured leases">
359 5b237745 Scott Ullrich
<?php endif; ?>
360
</form>
361 428d20c4 Seth Mos
<?php if($leases == 0): ?>
362 5b237745 Scott Ullrich
<p><strong>No leases file found. Is the DHCP server active?</strong></p>
363
<?php endif; ?>
364 fda1fdae Scott Ullrich
365 5b237745 Scott Ullrich
<?php include("fend.inc"); ?>
366
</body>
367
</html>