Project

General

Profile

Download (14.7 KB) Statistics
| Branch: | Tag: | Revision:

univnautes / usr / local / www / status_dhcp_leases.php @ a1b66bec

1
<?php
2
/* $Id$ */
3
/*
4
	status_dhcp_leases.php
5
	Copyright (C) 2004-2009 Scott Ullrich
6
	All rights reserved.
7

    
8
	originally part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

    
18
	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

    
22
	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
/*
35
	pfSense_BUILDER_BINARIES:	/usr/bin/awk	/bin/cat	/usr/sbin/arp	/usr/bin/wc	/usr/bin/grep
36
	pfSense_MODULE:	dhcpserver
37
*/
38

    
39
##|+PRIV
40
##|*IDENT=page-status-dhcpleases
41
##|*NAME=Status: DHCP leases page
42
##|*DESCR=Allow access to the 'Status: DHCP leases' page.
43
##|*MATCH=status_dhcp_leases.php*
44
##|-PRIV
45

    
46
require("guiconfig.inc");
47
require_once("config.inc");
48

    
49
$pgtitle = array(gettext("Status"),gettext("DHCP leases"));
50
$shortcut_section = "dhcp";
51

    
52
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
53

    
54
if (($_GET['deleteip']) && (is_ipaddr($_GET['deleteip']))) {
55
	/* Stop DHCPD */
56
	killbyname("dhcpd");
57

    
58
	/* Read existing leases */
59
	/* $leases_contents has the lines of the file, including the newline char at the end of each line. */
60
	$leases_contents = file($leasesfile);
61
	$newleases_contents = array();
62
	$i=0;
63
	while ($i < count($leases_contents)) {
64
		/* Find the lease(s) we want to delete */
65
		if ($leases_contents[$i] == "lease {$_GET['deleteip']} {\n") {
66
			/* Skip to the end of the lease declaration */
67
			do {
68
				$i++;
69
			} while ($leases_contents[$i] != "}\n");
70
		} else {
71
			/* It's a line we want to keep, copy it over. */
72
			$newleases_contents[] = $leases_contents[$i];
73
		}
74
		$i++;
75
	}
76

    
77
	/* Write out the new leases file */
78
	$fd = fopen($leasesfile, 'w');
79
	fwrite($fd, implode("\n", $newleases_contents));
80
	fclose($fd);
81

    
82
	/* Restart DHCP Service */
83
	services_dhcpd_configure();
84
	header("Location: status_dhcp_leases.php?all={$_GET['all']}");
85
}
86

    
87
include("head.inc");
88

    
89
?>
90

    
91
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
92
<?php include("fbegin.inc"); ?>
93
<?php
94

    
95
function leasecmp($a, $b) {
96
	return strcmp($a[$_GET['order']], $b[$_GET['order']]);
97
}
98

    
99
function adjust_gmt($dt) {
100
	global $config;
101
	$dhcpd = $config['dhcpd'];
102
	foreach ($dhcpd as $dhcpditem) {
103
		$dhcpleaseinlocaltime = $dhcpditem['dhcpleaseinlocaltime'];
104
		if ($dhcpleaseinlocaltime == "yes")
105
			break;
106
	}
107
	if ($dhcpleaseinlocaltime == "yes") {
108
		$ts = strtotime($dt . " GMT");
109
		return strftime("%Y/%m/%d %I:%M:%S%p", $ts);
110
	} else
111
		return $dt;
112
}
113

    
114
function remove_duplicate($array, $field)
115
{
116
	foreach ($array as $sub)
117
		$cmp[] = $sub[$field];
118
	$unique = array_unique(array_reverse($cmp,true));
119
	foreach ($unique as $k => $rien)
120
		$new[] = $array[$k];
121
	return $new;
122
}
123

    
124
$awk = "/usr/bin/awk";
125
/* this pattern sticks comments into a single array item */
126
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
127
/* We then split the leases file by } */
128
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
129

    
130
/* stuff the leases file in a proper format into a array by line */
131
exec("/bin/cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
132
$leases_count = count($leases_content);
133
exec("/usr/sbin/arp -an", $rawdata);
134
$arpdata_ip = array();
135
$arpdata_mac = array();
136
foreach ($rawdata as $line) {
137
	$elements = explode(' ',$line);
138
	if ($elements[3] != "(incomplete)") {
139
		$arpent = array();
140
		$arpdata_ip[] = trim(str_replace(array('(',')'),'',$elements[1]));
141
		$arpdata_mac[] = strtolower(trim($elements[3]));
142
	}
143
}
144
unset($rawdata);
145
$pools = array();
146
$leases = array();
147
$i = 0;
148
$l = 0;
149
$p = 0;
150

    
151
// Put everything together again
152
foreach($leases_content as $lease) {
153
	/* split the line by space */
154
	$data = explode(" ", $lease);
155
	/* walk the fields */
156
	$f = 0;
157
	$fcount = count($data);
158
	/* with less than 20 fields there is nothing useful */
159
	if($fcount < 20) {
160
		$i++;
161
		continue;
162
	}
163
	while($f < $fcount) {
164
		switch($data[$f]) {
165
			case "failover":
166
				$pools[$p]['name'] = trim($data[$f+2], '"');
167
				$pools[$p]['name'] = "{$pools[$p]['name']} (" . convert_friendly_interface_to_friendly_descr(substr($pools[$p]['name'], 5)) . ")";
168
				$pools[$p]['mystate'] = $data[$f+7];
169
				$pools[$p]['peerstate'] = $data[$f+14];
170
				$pools[$p]['mydate'] = $data[$f+10];
171
				$pools[$p]['mydate'] .= " " . $data[$f+11];
172
				$pools[$p]['peerdate'] = $data[$f+17];
173
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
174
				$p++;
175
				$i++;
176
				continue 3;
177
			case "lease":
178
				$leases[$l]['ip'] = $data[$f+1];
179
				$leases[$l]['type'] = "dynamic";
180
				$f = $f+2;
181
				break;
182
			case "starts":
183
				$leases[$l]['start'] = $data[$f+2];
184
				$leases[$l]['start'] .= " " . $data[$f+3];
185
				$f = $f+3;
186
				break;
187
			case "ends":
188
				$leases[$l]['end'] = $data[$f+2];
189
				$leases[$l]['end'] .= " " . $data[$f+3];
190
				$f = $f+3;
191
				break;
192
			case "tstp":
193
				$f = $f+3;
194
				break;
195
			case "tsfp":
196
				$f = $f+3;
197
				break;
198
			case "atsfp":
199
				$f = $f+3;
200
				break;
201
			case "cltt":
202
				$f = $f+3;
203
				break;
204
			case "binding":
205
				switch($data[$f+2]) {
206
					case "active":
207
						$leases[$l]['act'] = "active";
208
						break;
209
					case "free":
210
						$leases[$l]['act'] = "expired";
211
						$leases[$l]['online'] = "offline";
212
						break;
213
					case "backup":
214
						$leases[$l]['act'] = "reserved";
215
						$leases[$l]['online'] = "offline";
216
						break;
217
				}
218
				$f = $f+1;
219
				break;
220
			case "next":
221
				/* skip the next binding statement */
222
				$f = $f+3;
223
				break;
224
			case "rewind":
225
				/* skip the rewind binding statement */
226
				$f = $f+3;
227
				break;
228
			case "hardware":
229
				$leases[$l]['mac'] = $data[$f+2];
230
				/* check if it's online and the lease is active */
231
				if (in_array($leases[$l]['ip'], $arpdata_ip)) {
232
					$leases[$l]['online'] = 'online';
233
				} else {
234
					$leases[$l]['online'] = 'offline';
235
				}
236
				$f = $f+2;
237
				break;
238
			case "client-hostname":
239
				if($data[$f+1] <> "") {
240
					$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
241
				} else {
242
					$hostname = gethostbyaddr($leases[$l]['ip']);
243
					if($hostname <> "") {
244
						$leases[$l]['hostname'] = $hostname;
245
					}
246
				}
247
				$f = $f+1;
248
				break;
249
			case "uid":
250
				$f = $f+1;
251
				break;
252
		}
253
		$f++;
254
	}
255
	$l++;
256
	$i++;
257
	/* slowly chisel away at the source array */
258
	array_shift($leases_content);
259
}
260
/* remove the old array */
261
unset($lease_content);
262

    
263
/* remove duplicate items by mac address */
264
if(count($leases) > 0) {
265
	$leases = remove_duplicate($leases,"ip");
266
}
267

    
268
if(count($pools) > 0) {
269
	$pools = remove_duplicate($pools,"name");
270
	asort($pools);
271
}
272

    
273
foreach($config['interfaces'] as $ifname => $ifarr) {
274
	if (is_array($config['dhcpd'][$ifname]) &&
275
		is_array($config['dhcpd'][$ifname]['staticmap'])) {
276
		foreach($config['dhcpd'][$ifname]['staticmap'] as $static) {
277
			$slease = array();
278
			$slease['ip'] = $static['ipaddr'];
279
			$slease['type'] = "static";
280
			$slease['mac'] = $static['mac'];
281
			$slease['start'] = "";
282
			$slease['end'] = "";
283
			$slease['hostname'] = htmlentities($static['hostname']);
284
			$slease['act'] = "static";
285
			$slease['online'] = in_array(strtolower($slease['mac']), $arpdata_mac) ? 'online' : 'offline';
286
			$leases[] = $slease;
287
		}
288
	}
289
}
290

    
291
if ($_GET['order'])
292
	usort($leases, "leasecmp");
293

    
294
/* only print pool status when we have one */
295
if(count($pools) > 0) {
296
?>
297
<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0" summary="dhcp leases">
298
  <tr>
299
    <td class="listhdrr"><?=gettext("Failover Group"); ?></a></td>
300
    <td class="listhdrr"><?=gettext("My State"); ?></a></td>
301
    <td class="listhdrr"><?=gettext("Since"); ?></a></td>
302
    <td class="listhdrr"><?=gettext("Peer State"); ?></a></td>
303
    <td class="listhdrr"><?=gettext("Since"); ?></a></td>
304
  </tr>
305
<?php
306
foreach ($pools as $data) {
307
	echo "<tr>\n";
308
	echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}</td>\n";
309
	echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}</td>\n";
310
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}</td>\n";
311
	echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}</td>\n";
312
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}</td>\n";
313
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
314
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
315
	echo "</tr>\n";
316
}
317

    
318
?>
319
</table>
320

    
321
<?php
322
/* only print pool status when we have one */
323
}
324
?>
325

    
326
<br/>
327

    
328
<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0" summary="dhcp leases">
329
  <tr>
330
    <td class="listhdrr"><a href="#"><?=gettext("IP address"); ?></a></td>
331
    <td class="listhdrr"><a href="#"><?=gettext("MAC address"); ?></a></td>
332
    <td class="listhdrr"><a href="#"><?=gettext("Hostname"); ?></a></td>
333
    <td class="listhdrr"><a href="#"><?=gettext("Start"); ?></a></td>
334
    <td class="listhdrr"><a href="#"><?=gettext("End"); ?></a></td>
335
    <td class="listhdrr"><a href="#"><?=gettext("Online"); ?></a></td>
336
    <td class="listhdrr"><a href="#"><?=gettext("Lease Type"); ?></a></td>
337
	</tr>
338
<?php
339
// Load MAC-Manufacturer table
340
$mac_man = load_mac_manufacturer_table();
341
foreach ($leases as $data) {
342
	if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) {
343
		if ($data['act'] != "active" && $data['act'] != "static") {
344
			$fspans = "<span class=\"gray\">";
345
			$fspane = "&nbsp;</span>";
346
		} else {
347
			$fspans = "";
348
			$fspane = "&nbsp;";
349
		}
350
		$lip = ip2ulong($data['ip']);
351
		if ($data['act'] == "static") {
352
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
353
				if(is_array($dhcpifconf['staticmap'])) {
354
					$staticmap_array_index = 0;
355
					foreach ($dhcpifconf['staticmap'] as $staticent) {
356
						if ($data['ip'] == $staticent['ipaddr']) {
357
							$data['if'] = $dhcpif;
358
							break;
359
						}
360
						$staticmap_array_index++;
361
					}
362
				}
363
				/* exit as soon as we have an interface */
364
				if ($data['if'] != "")
365
					break;
366
			}
367
		} else {
368
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
369
				if (!is_array($dhcpifconf['range']))
370
					continue;
371
				if (($lip >= ip2ulong($dhcpifconf['range']['from'])) && ($lip <= ip2ulong($dhcpifconf['range']['to']))) {
372
					$data['if'] = $dhcpif;
373
					break;
374
				}
375
			}
376
		}
377
		echo "<tr>\n";
378
		echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}</td>\n";
379
		$mac=$data['mac'];
380
		$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]);
381
		if ($data['online'] != "online") {
382
			if(isset($mac_man[$mac_hi])){ // Manufacturer for this MAC is defined
383
				echo "<td class=\"listr\">{$fspans}<a href=\"services_wol.php?if={$data['if']}&amp;mac=$mac\" title=\"" . gettext("$mac - send Wake on LAN packet to this MAC address") ."\">{$mac}</a><br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>{$fspane}</td>\n";
384
			} else {
385
				echo "<td class=\"listr\">{$fspans}<a href=\"services_wol.php?if={$data['if']}&amp;mac={$data['mac']}\" title=\"" . gettext("send Wake on LAN packet to this MAC address") ."\">{$data['mac']}</a>{$fspane}</td>\n";
386
			}
387
		} else {
388
			if(isset($mac_man[$mac_hi])){ // Manufacturer for this MAC is defined
389
				echo "<td class=\"listr\">{$fspans}{$mac}<br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>{$fspane}</td>\n";
390
			} else {
391
				echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}</td>\n";
392
			}
393
		}
394
		echo "<td class=\"listr\">{$fspans}"  . htmlentities($data['hostname']) . "{$fspane}</td>\n";
395
		if ($data['type'] != "static") {
396
			echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}</td>\n";
397
			echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}</td>\n";
398
		} else {
399
			echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n";
400
			echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n";
401
		}
402
		echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}</td>\n";
403
		echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}</td>\n";
404
		echo "<td valign=\"middle\">&nbsp;";
405
		if ($data['type'] == "dynamic") {
406
			echo "<a href=\"services_dhcp_edit.php?if={$data['if']}&amp;mac={$data['mac']}&amp;hostname={$data['hostname']}\">";
407
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"" . gettext("add a static mapping for this MAC address") ."\" alt=\"add\" /></a>&nbsp;\n";
408
		} else {
409
			echo "<a href=\"services_dhcp_edit.php?if={$data['if']}&amp;id={$staticmap_array_index}\">";
410
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_e.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"" . gettext("edit the static mapping for this entry") ."\" alt=\"add\" />&nbsp;\n";
411
		}
412

    
413
		echo "<a href=\"services_wol_edit.php?if={$data['if']}&amp;mac={$data['mac']}&amp;descr={$data['hostname']}\">";
414
		echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_wol_all.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"" . gettext("add a Wake on LAN mapping for this MAC address") ."\" alt=\"add\" /></a>&nbsp;\n";
415

    
416
		/* Only show the button for offline dynamic leases */
417
		if (($data['type'] == "dynamic") && ($data['online'] != "online")) {
418
			echo "<a href=\"status_dhcp_leases.php?deleteip={$data['ip']}&amp;all=" . htmlspecialchars($_GET['all']) . "\">";
419
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"" . gettext("delete this DHCP lease") . "\" alt=\"delete\" /></a>&nbsp;\n";
420
		}
421
	echo "</td></tr>\n";
422
	}
423
}
424

    
425
?>
426
</table>
427
<br/>
428
<form action="status_dhcp_leases.php" method="get">
429
<input type="hidden" name="order" value="<?=htmlspecialchars($_GET['order']);?>" />
430
<?php if ($_GET['all']): ?>
431
<input type="hidden" name="all" value="0" />
432
<input type="submit" class="formbtn" value="<?=gettext("Show active and static leases only"); ?>" />
433
<?php else: ?>
434
<input type="hidden" name="all" value="1" />
435
<input type="submit" class="formbtn" value="<?=gettext("Show all configured leases"); ?>" />
436
<?php endif; ?>
437
</form>
438
<?php if($leases == 0): ?>
439
<p><strong><?=gettext("No leases file found. Is the DHCP server active"); ?>?</strong></p>
440
<?php endif; ?>
441

    
442
<?php include("fend.inc"); ?>
443
</body>
444
</html>
(185-185/256)