Projet

Général

Profil

Télécharger (14,9 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / usr / local / www / status_dhcp_leases.php @ 3c4cddc7

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 then 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
					foreach ($dhcpifconf['staticmap'] as $staticent) {
355
						if ($data['ip'] == $staticent['ipaddr']) {
356
							$data['if'] = $dhcpif;
357
							break;
358
						}
359
					}
360
				}
361
				/* exit as soon as we have an interface */
362
				if ($data['if'] != "")
363
					break;
364
			}
365
		} else {
366
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
367
				if (!is_array($dhcpifconf['range']))
368
					continue;
369
                        	if (($lip >= ip2ulong($dhcpifconf['range']['from'])) && ($lip <= ip2ulong($dhcpifconf['range']['to']))) {
370
                                	$data['if'] = $dhcpif;
371
                                	break;
372
                        	}
373
			}
374
                }		
375
		echo "<tr>\n";
376
                echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}</td>\n";
377
		$mac=$data['mac']; 
378
		$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]);
379
                if ($data['online'] != "online") {
380
			if(isset($mac_man[$mac_hi])){ // Manufacturer for this MAC is defined
381
	                        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";
382
			}else{	
383
                        	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";
384
			}
385
                }else{
386
			if(isset($mac_man[$mac_hi])){ // Manufacturer for this MAC is defined
387
				echo "<td class=\"listr\">{$fspans}{$mac}<br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>{$fspane}</td>\n";
388
	                }else{
389
                		echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}</td>\n";
390
			}
391
                }
392
                echo "<td class=\"listr\">{$fspans}"  . htmlentities($data['hostname']) . "{$fspane}</td>\n";
393
				if ($data['type'] != "static") {
394
					echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}</td>\n";
395
					echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}</td>\n";
396
				} else {
397
					echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n";
398
					echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n";
399
				}
400
                echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}</td>\n";
401
                echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}</td>\n";
402
                echo "<td valign=\"middle\">&nbsp;";
403
		if ($data['type'] == "dynamic") {
404
			echo "<a href=\"services_dhcp_edit.php?if={$data['if']}&amp;mac={$data['mac']}&amp;hostname={$data['hostname']}\">";
405
			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";
406
		} else {
407
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus_mo.gif\" width=\"17\" height=\"17\" border=\"0\" alt=\"add\" />&nbsp;\n";
408
		}
409

    
410
                echo "<a href=\"services_wol_edit.php?if={$data['if']}&amp;mac={$data['mac']}&amp;descr={$data['hostname']}\">";
411
		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";
412

    
413
		/* Only show the button for offline dynamic leases */
414
		if (($data['type'] == "dynamic") && ($data['online'] != "online")) {
415
			echo "<a href=\"status_dhcp_leases.php?deleteip={$data['ip']}&amp;all=" . htmlspecialchars($_GET['all']) . "\">";
416
			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";
417
		}
418
                echo "</td></tr>\n";
419
	}
420
}
421

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

    
439
<?php include("fend.inc"); ?>
440
</body>
441
</html>
(185-185/256)