Project

General

Profile

Download (12.9 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
require("guiconfig.inc");
35 b63695db Scott Ullrich
36
$pgtitle = "Diagnostics: DHCP leases";
37 549b9772 Chris Buechler
38
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
39
40
if (($_GET['deleteip']) && (is_ipaddr($_GET['deleteip']))) {
41
	/* Stop DHCPD */
42
	killbyname("dhcpd");
43
	
44
	/* Read existing leases */
45
	$leases_contents = explode("\n", file_get_contents($leasesfile));
46
	$newleases_contents = array();
47
	$i=0;
48
	while ($i < count($leases_contents)) {
49
		/* Find the lease(s) we want to delete */
50
		if ($leases_contents[$i] == "lease {$_GET['deleteip']} {") {
51
			/* Skip to the end of the lease declaration */
52
			do {
53
				$i++;
54
			} while ($leases_contents[$i] != "}");
55
		} else {
56
			/* It's a line we want to keep, copy it over. */
57
			$newleases_contents[] = $leases_contents[$i];
58
		}
59
		$i++;
60
	}
61
62
	/* Write out the new leases file */
63
	$fd = fopen($leasesfile, 'w');
64
	fwrite($fd, implode("\n", $newleases_contents));
65
	fclose($fd);
66
67
	/* Restart DHCP Service */
68
	services_dhcpd_configure();
69 e4fdbcf2 Scott Ullrich
	header("Location: diag_dhcp_leases.php?all={$_GET['all']}");
70 549b9772 Chris Buechler
}
71
72 b63695db Scott Ullrich
include("head.inc");
73
74 5b237745 Scott Ullrich
?>
75
76
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
77 5fd0b016 Scott Ullrich
<script src="/javascript/sorttable.js"></script>
78 5b237745 Scott Ullrich
<?php include("fbegin.inc"); ?>
79 310b2c06 Bill Marquette
<p class="pgtitle"><?=$pgtitle?></p>
80 5b237745 Scott Ullrich
<?php
81
82
function leasecmp($a, $b) {
83 5742ca5e Scott Ullrich
        return strcmp($a[$_GET['order']], $b[$_GET['order']]);
84
}
85
86
function adjust_gmt($dt) {
87
        $ts = strtotime($dt . " GMT");
88
        return strftime("%Y/%m/%d %H:%M:%S", $ts);
89 5b237745 Scott Ullrich
}
90
91 428d20c4 Seth Mos
function remove_duplicate($array, $field)
92
{
93
  foreach ($array as $sub)
94
   $cmp[] = $sub[$field];
95 28409753 Chris Buechler
  $unique = array_unique(array_reverse($cmp,true));
96 428d20c4 Seth Mos
  foreach ($unique as $k => $rien)
97
   $new[] = $array[$k];
98
  return $new;
99 5b237745 Scott Ullrich
}
100
101 428d20c4 Seth Mos
$awk = "/usr/bin/awk";
102
/* this pattern sticks comments into a single array item */
103
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
104
/* We then split the leases file by } */
105 b4f7282c Seth Mos
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
106 5b237745 Scott Ullrich
107 428d20c4 Seth Mos
/* stuff the leases file in a proper format into a array by line */
108
exec("cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
109
$leases_count = count($leases_content);
110
111
$pools = array();
112 5b237745 Scott Ullrich
$leases = array();
113
$i = 0;
114 b4f7282c Seth Mos
$l = 0;
115
$p = 0;
116 5b237745 Scott Ullrich
117
// Put everything together again
118 428d20c4 Seth Mos
while($i < $leases_count) {
119
	/* split the line by space */
120
	$data = explode(" ", $leases_content[$i]);
121
	/* walk the fields */
122
	$f = 0;
123
	$fcount = count($data);
124 b4f7282c Seth Mos
	/* with less then 20 fields there is nothing useful */
125
	if($fcount < 20) {
126
		$i++;
127
		continue;
128
	}
129 428d20c4 Seth Mos
	while($f < $fcount) {
130 b4f7282c Seth Mos
		switch($data[$f]) {
131
			case "failover":
132
				$pools[$p]['name'] = $data[$f+2];
133
				$pools[$p]['mystate'] = $data[$f+7];
134
				$pools[$p]['peerstate'] = $data[$f+14];
135
				$pools[$p]['mydate'] = $data[$f+10];
136
				$pools[$p]['mydate'] .= " " . $data[$f+11];
137
				$pools[$p]['peerdate'] = $data[$f+17];
138
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
139
				$p++;
140
				$i++;
141
				continue 3;
142
			case "lease":
143
				$leases[$l]['ip'] = $data[$f+1];
144
				$leases[$l]['type'] = "dynamic";
145
				$f = $f+2;
146
				break;
147
			case "starts":
148
				$leases[$l]['start'] = $data[$f+2];
149
				$leases[$l]['start'] .= " " . $data[$f+3];
150
				$f = $f+3;
151
				break;
152
			case "ends":
153
				$leases[$l]['end'] = $data[$f+2];
154
				$leases[$l]['end'] .= " " . $data[$f+3];
155
				$f = $f+3;
156
				break;
157
			case "tstp":
158
				$f = $f+3;
159
				break;
160
			case "tsfp":
161
				$f = $f+3;
162
				break;
163
			case "atsfp":
164
				$f = $f+3;
165
				break;
166
			case "cltt":
167
				$f = $f+3;
168
				break;
169
			case "binding":
170 428d20c4 Seth Mos
				switch($data[$f+2]) {
171 b4f7282c Seth Mos
					case "active":
172
						$leases[$l]['act'] = "active";
173 428d20c4 Seth Mos
						break;
174 b4f7282c Seth Mos
					case "free":
175
						$leases[$l]['act'] = "expired";
176
						$leases[$l]['online'] = "offline";
177 428d20c4 Seth Mos
						break;
178 b4f7282c Seth Mos
					case "backup":
179
						$leases[$l]['act'] = "reserved";
180
						$leases[$l]['online'] = "offline";
181 428d20c4 Seth Mos
						break;
182
				}
183 b4f7282c Seth Mos
				$f = $f+1;
184
				break;
185
			case "next":
186
				/* skip the next binding statement */
187
				$f = $f+3;
188
				break;
189
			case "hardware":
190
				$leases[$l]['mac'] = $data[$f+2];
191
				/* check if it's online and the lease is active */
192
				if($leases[$l]['act'] == "active") {
193
					$online = exec("/usr/sbin/arp -an |/usr/bin/awk '/{$leases[$l]['ip']}/ {print}'|wc -l");
194
					if ($online == 1) {
195
						$leases[$l]['online'] = 'online';
196
					} else {
197
						$leases[$l]['online'] = 'offline';
198
					}
199 14cf741d Scott Ullrich
				}
200 b4f7282c Seth Mos
				$f = $f+2;
201
				break;
202
			case "client-hostname":
203
				if($data[$f+1] <> "") {
204
					$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
205
				} else {
206
					$hostname = gethostbyaddr($leases[$l]['ip']);
207
					if($hostname <> "") {
208
						$leases[$l]['hostname'] = $hostname;
209
					}
210
				}
211
				$f = $f+1;
212
				break;
213
			case "uid":
214
				$f = $f+1;
215
				break;
216 14cf741d Scott Ullrich
		}
217 428d20c4 Seth Mos
		$f++;
218 14cf741d Scott Ullrich
	}
219 b4f7282c Seth Mos
	$l++;
220 428d20c4 Seth Mos
	$i++;
221 5b237745 Scott Ullrich
}
222 428d20c4 Seth Mos
223
/* remove duplicate items by mac address */
224 9255cbc5 Seth Mos
if(count($leases) > 0) {
225 b4f7282c Seth Mos
	$leases = remove_duplicate($leases,"ip");
226 9255cbc5 Seth Mos
}
227 b4f7282c Seth Mos
228 9255cbc5 Seth Mos
if(count($pools) > 0) {
229
	$pools = remove_duplicate($pools,"name");
230
	asort($pools);
231
}
232 428d20c4 Seth Mos
233 9252431c Scott Ullrich
foreach($config['interfaces'] as $ifname => $ifarr) {
234
	if (is_array($config['dhcpd'][$ifname]['staticmap'])) {
235
		foreach($config['dhcpd'][$ifname]['staticmap'] as $static) {
236
			$slease = array();
237
			$slease['ip'] = $static['ipaddr'];
238
			$slease['type'] = "static";
239
			$slease['mac'] = $static['mac'];
240 30705af7 Chris Buechler
			$slease['start'] = "";
241
			$slease['end'] = "";
242 c5733422 Scott Ullrich
			$slease['hostname'] = htmlentities($static['hostname']);
243 9252431c Scott Ullrich
			$slease['act'] = "static";
244
			$online = exec("/usr/sbin/arp -an |/usr/bin/grep {$slease['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
245
			if ($online == 1) {
246
				$slease['online'] = 'online';
247
			} else {
248
				$slease['online'] = 'offline';
249
			}
250
			$leases[] = $slease;
251
		}
252
	}
253
}
254 5b237745 Scott Ullrich
255
if ($_GET['order'])
256
	usort($leases, "leasecmp");
257 428d20c4 Seth Mos
258
?>
259
260
<?php
261
/* only print pool status when we have one */
262
if(count($pools) > 0) {
263 5b237745 Scott Ullrich
?>
264 428d20c4 Seth Mos
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
265
  <tr>
266
    <td class="listhdrr">Failover Group</a></td>
267
    <td class="listhdrr">My State</a></td>
268
    <td class="listhdrr">Since</a></td>
269
    <td class="listhdrr">Peer State</a></td>
270
    <td class="listhdrr">Since</a></td>
271
  </tr>
272
<?php
273
foreach ($pools as $data) {
274
	echo "<tr>\n";
275
	echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}&nbsp;</td>\n";
276
	echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}&nbsp;</td>\n";
277
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}&nbsp;</td>\n";
278
	echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}&nbsp;</td>\n";
279
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}&nbsp;</td>\n";
280
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
281
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
282
	echo "</tr>\n";
283
}
284
285
?>
286
</table>
287
288
<?php
289
/* only print pool status when we have one */
290
}
291
?>
292
293
<p>
294
295 5fd0b016 Scott Ullrich
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
296 5b237745 Scott Ullrich
  <tr>
297
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=ip">IP address</a></td>
298
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=mac">MAC address</a></td>
299
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=hostname">Hostname</a></td>
300
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=start">Start</a></td>
301 9252431c Scott Ullrich
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=end">End</a></td>
302
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=online">Online</a></td>
303
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=act">Lease Type</a></td>
304 5b237745 Scott Ullrich
	</tr>
305
<?php
306
foreach ($leases as $data) {
307 9252431c Scott Ullrich
	if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) {
308
		if ($data['act'] != "active" && $data['act'] != "static") {
309 5b237745 Scott Ullrich
			$fspans = "<span class=\"gray\">";
310
			$fspane = "</span>";
311
		} else {
312
			$fspans = $fspane = "";
313
		}
314 69981800 Scott Ullrich
                $lip = ip2long($data['ip']);
315 5b2177e4 Scott Ullrich
		if ($data['act'] == "static") {
316
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
317 0e616855 Scott Ullrich
				if(is_array($dhcpifconf['staticmap'])) {
318
					foreach ($dhcpifconf['staticmap'] as $staticent) {
319
						if ($data['ip'] == $staticent['ipaddr']) {
320
							$data['if'] = $dhcpif;
321
							break;
322
						}
323 5b2177e4 Scott Ullrich
					}
324
				}
325
				/* exit as soon as we have an interface */
326
				if ($data['if'] != "")
327
					break;
328
			}
329
		} else {
330
                	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
331
                        	if (($lip >= ip2long($dhcpifconf['range']['from'])) && ($lip <= ip2long($dhcpifconf['range']['to']))) {
332
                                	$data['if'] = $dhcpif;
333
                                	break;
334
                        	}
335
			}
336 69981800 Scott Ullrich
                }		
337 5b237745 Scott Ullrich
		echo "<tr>\n";
338 5742ca5e Scott Ullrich
                echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
339 9252431c Scott Ullrich
                if ($data['online'] != "online") {
340 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";
341
                } else {
342 9252431c Scott Ullrich
                	echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}&nbsp;</td>\n";
343 37c0c49b Scott Ullrich
                }
344 c5733422 Scott Ullrich
                echo "<td class=\"listr\">{$fspans}" . htmlentities($data['hostname']) . "{$fspane}&nbsp;</td>\n";
345 30705af7 Chris Buechler
		if ($data['type'] != "static") {
346
			echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}&nbsp;</td>\n";
347
			echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}&nbsp;</td>\n";
348
		} else {
349
			echo "<td class=\"listr\">{$fspans} n/a {$fspane}&nbsp;</td>\n";
350
			echo "<td class=\"listr\">{$fspans} n/a {$fspane}&nbsp;</td>\n";
351
		}
352 9252431c Scott Ullrich
                echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}&nbsp;</td>\n";
353
                echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}&nbsp;</td>\n";
354
		
355
		if ($data['type'] == "dynamic") {
356 6a01ea44 Bill Marquette
                	echo "<td class=\"list\" valign=\"middle\"><a href=\"services_dhcp_edit.php?if={$data['if']}&mac={$data['mac']}&hostname={$data['hostname']}\">";
357 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";
358
		} else {
359
                	echo "<td class=\"list\" valign=\"middle\">";
360 b86e64c1 Scott Ullrich
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus_mo.gif\" width=\"17\" height=\"17\" border=\"0\"></td>\n";
361 9252431c Scott Ullrich
		}
362 7477df4f Scott Ullrich
                echo "<td valign=\"middle\"><a href=\"services_wol_edit.php?if={$data['if']}&mac={$data['mac']}&descr={$data['hostname']}\">";
363 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";
364 549b9772 Chris Buechler
365
		/* Only show the button for offline dynamic leases */
366
		if (($data['type'] == "dynamic") && ($data['online'] != "online")) {
367 e4fdbcf2 Scott Ullrich
			echo "<td class=\"list\" valign=\"middle\"><a href=\"diag_dhcp_leases.php?deleteip={$data['ip']}&all={$_GET['all']}\">";
368 549b9772 Chris Buechler
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"delete this dhcp lease\"></a></td>\n";
369
		}
370 5742ca5e Scott Ullrich
                echo "</tr>\n";
371 5b237745 Scott Ullrich
	}
372
}
373 428d20c4 Seth Mos
374 5b237745 Scott Ullrich
?>
375
</table>
376
<p>
377
<form action="diag_dhcp_leases.php" method="GET">
378
<input type="hidden" name="order" value="<?=$_GET['order'];?>">
379
<?php if ($_GET['all']): ?>
380
<input type="hidden" name="all" value="0">
381 9252431c Scott Ullrich
<input type="submit" class="formbtn" value="Show active and static leases only">
382 5b237745 Scott Ullrich
<?php else: ?>
383
<input type="hidden" name="all" value="1">
384 9252431c Scott Ullrich
<input type="submit" class="formbtn" value="Show all configured leases">
385 5b237745 Scott Ullrich
<?php endif; ?>
386
</form>
387 428d20c4 Seth Mos
<?php if($leases == 0): ?>
388 5b237745 Scott Ullrich
<p><strong>No leases file found. Is the DHCP server active?</strong></p>
389
<?php endif; ?>
390 fda1fdae Scott Ullrich
391 5b237745 Scott Ullrich
<?php include("fend.inc"); ?>
392
</body>
393
</html>