Project

General

Profile

Download (13.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	status_dhcpv6_leases.php
5
	Copyright (C) 2004-2009 Scott Ullrich
6
	Copyright (C) 2011 Seth Mos
7
	All rights reserved.
8

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

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

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

    
19
	2. Redistributions in binary form must reproduce the above copyright
20
	   notice, this list of conditions and the following disclaimer in the
21
	   documentation and/or other materials provided with the distribution.
22

    
23
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
	POSSIBILITY OF SUCH DAMAGE.
33
*/
34

    
35
/*
36
	pfSense_BUILDER_BINARIES:	/usr/bin/awk	/bin/cat	/usr/sbin/arp	/usr/bin/wc	/usr/bin/grep
37
	pfSense_MODULE:	dhcpserver
38
*/
39

    
40
##|+PRIV
41
##|*IDENT=page-status-dhcpv6leases
42
##|*NAME=Status: DHCPv6 leases page
43
##|*DESCR=Allow access to the 'Status: DHCPv6 leases' page.
44
##|*MATCH=status_dhcpv6_leases.php*
45
##|-PRIV
46

    
47
require("guiconfig.inc");
48

    
49
$pgtitle = array(gettext("Status"),gettext("DHCPv6 leases"));
50

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

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

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

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

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

    
85
include("head.inc");
86

    
87
?>
88

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

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

    
97
function adjust_gmt($dt) {
98
        $ts = strtotime($dt . " GMT");
99
        return strftime("%Y/%m/%d %H:%M:%S", $ts);
100
}
101

    
102
function remove_duplicate($array, $field)
103
{
104
  foreach ($array as $sub)
105
   $cmp[] = $sub[$field];
106
  $unique = array_unique(array_reverse($cmp,true));
107
  foreach ($unique as $k => $rien)
108
   $new[] = $array[$k];
109
  return $new;
110
}
111

    
112
$awk = "/usr/bin/awk";
113

    
114
/* this pattern sticks comments into a single array item */
115
$cleanpattern = "'{ gsub(\"^#.*\", \"\");} { gsub(\"^server-duid.*\", \"\");} { gsub(\";\", \"\"); print;}'";
116
/* We then split the leases file by } */
117
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
118

    
119
/* stuff the leases file in a proper format into a array by line */
120
exec("/bin/cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern} | /usr/bin/grep '^ia-na'", $leases_content);
121
$leases_count = count($leases_content);
122
exec("/usr/sbin/ndp -an", $rawdata);
123
$arpdata = array();
124
foreach ($rawdata as $line) {
125
	$elements = preg_split('/\s+/ ',$line);
126
	if ($elements[1] != "(incomplete)") {
127
		$arpent = array();
128
		$arpent['ip'] = trim(str_replace(array('(',')'),'',$elements[0]));
129
		// $arpent['mac'] = trim($elements[3]);
130
		// $arpent['interface'] = trim($elements[5]);
131
	$arpdata[] = $arpent['ip'];
132
	}
133
}
134

    
135
$pools = array();
136
$leases = array();
137
$i = 0;
138
$l = 0;
139
$p = 0;
140

    
141
// Put everything together again
142
while($i < $leases_count) {
143
	/* split the line by space */
144
	$data = explode(" ", $leases_content[$i]);
145
	/* walk the fields */
146
	$f = 0;
147
	$fcount = count($data);
148
	/* with less then 15 fields there is nothing useful */
149
	if($fcount < 15) {
150
		$i++;
151
		continue;
152
	}
153
	while($f < $fcount) {
154
		switch($data[$f]) {
155
			case "failover":
156
				$pools[$p]['name'] = $data[$f+2];
157
				$pools[$p]['mystate'] = $data[$f+7];
158
				$pools[$p]['peerstate'] = $data[$f+14];
159
				$pools[$p]['mydate'] = $data[$f+10];
160
				$pools[$p]['mydate'] .= " " . $data[$f+11];
161
				$pools[$p]['peerdate'] = $data[$f+17];
162
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
163
				$p++;
164
				$i++;
165
				continue 3;
166
			case "ia-na":
167
				if ($data[$f+1][0] == '"') {
168
					$duid = "";
169
					/* FIXME: This needs a safety belt to prevent an infinite loop */
170
					while ($data[$f][strlen($data[$f])-1] != '"') {
171
						$duid .= " " . $data[$f+1];
172
						$f++;
173
					}
174
					$leases[$l]['duid'] = $duid;
175
				} else {
176
					$leases[$l]['duid'] = $data[$f+1];
177
				}
178
				$leases[$l]['type'] = "dynamic";
179
				$f = $f+2;
180
				break;
181
			case "iaaddr":
182
				$leases[$l]['ip'] = $data[$f+1];
183
				if (in_array($leases[$l]['ip'], $arpdata)) {
184
					$leases[$l]['online'] = 'online';
185
				} else {
186
					$leases[$l]['online'] = 'offline';
187
				}
188
				$f = $f+2;
189
				break;
190
			case "starts":
191
				$leases[$l]['start'] = $data[$f+2];
192
				$leases[$l]['start'] .= " " . $data[$f+3];
193
				$f = $f+3;
194
				break;
195
			case "ends":
196
				$leases[$l]['end'] = $data[$f+2];
197
				$leases[$l]['end'] .= " " . $data[$f+3];
198
				$f = $f+3;
199
				break;
200
			case "tstp":
201
				$f = $f+3;
202
				break;
203
			case "tsfp":
204
				$f = $f+3;
205
				break;
206
			case "atsfp":
207
				$f = $f+3;
208
				break;
209
			case "cltt":
210
				$f = $f+3;
211
				break;
212
			case "binding":
213
				switch($data[$f+2]) {
214
					case "active":
215
						$leases[$l]['act'] = "active";
216
						break;
217
					case "free":
218
						$leases[$l]['act'] = "expired";
219
						$leases[$l]['online'] = "offline";
220
						break;
221
					case "backup":
222
						$leases[$l]['act'] = "reserved";
223
						$leases[$l]['online'] = "offline";
224
						break;
225
				}
226
				$f = $f+1;
227
				break;
228
			case "next":
229
				/* skip the next binding statement */
230
				$f = $f+3;
231
				break;
232
			case "hardware":
233
				$f = $f+2;
234
				break;
235
			case "client-hostname":
236
				if($data[$f+1] <> "") {
237
					$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
238
				} else {
239
					$hostname = gethostbyaddr($leases[$l]['ip']);
240
					if($hostname <> "") {
241
						$leases[$l]['hostname'] = $hostname;
242
					}
243
				}
244
				$f = $f+1;
245
				break;
246
			case "uid":
247
				$f = $f+1;
248
				break;
249
		}
250
		$f++;
251
	}
252
	$l++;
253
	$i++;
254
}
255

    
256
if(count($leases) > 0) {
257
	$leases = remove_duplicate($leases,"ip");
258
}
259

    
260
if(count($pools) > 0) {
261
	$pools = remove_duplicate($pools,"name");
262
	asort($pools);
263
}
264

    
265
foreach($config['interfaces'] as $ifname => $ifarr) {
266
	if (is_array($config['dhcpdv6'][$ifname]) && 
267
		is_array($config['dhcpdv6'][$ifname]['staticmap'])) {
268
		foreach($config['dhcpdv6'][$ifname]['staticmap'] as $static) {
269
			$slease = array();
270
			$slease['ipv6'] = $static['ipaddr'];
271
			$slease['type'] = "static";
272
			$slease['mac'] = $static['mac'];
273
			$slease['start'] = "";
274
			$slease['end'] = "";
275
			$slease['hostname'] = htmlentities($static['hostname']);
276
			$slease['act'] = "static";
277
			$online = exec("/usr/sbin/ndp -an |/usr/bin/grep {$slease['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
278
			if ($online == 1) {
279
				$slease['online'] = 'online';
280
			} else {
281
				$slease['online'] = 'offline';
282
			}
283
			$leases[] = $slease;
284
		}
285
	}
286
}
287

    
288
if ($_GET['order'])
289
	usort($leases, "leasecmp");
290

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

    
315
?>
316
</table>
317

    
318
<?php
319
/* only print pool status when we have one */
320
}
321
?>
322

    
323
<p>
324

    
325
<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
326
  <tr>
327
    <td class="listhdrr"><a href="#"><?=gettext("IPv6 address"); ?></a></td>
328
    <td class="listhdrr"><a href="#"><?=gettext("DUID"); ?></a></td>
329
    <td class="listhdrr"><a href="#"><?=gettext("Hostname"); ?></a></td>
330
    <td class="listhdrr"><a href="#"><?=gettext("Start"); ?></a></td>
331
    <td class="listhdrr"><a href="#"><?=gettext("End"); ?></a></td>
332
    <td class="listhdrr"><a href="#"><?=gettext("Online"); ?></a></td>
333
    <td class="listhdrr"><a href="#"><?=gettext("Lease Type"); ?></a></td>
334
	</tr>
335
<?php
336
foreach ($leases as $data) {
337
	if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) {
338
		if ($data['act'] != "active" && $data['act'] != "static") {
339
			$fspans = "<span class=\"gray\">";
340
			$fspane = "</span>";
341
		} else {
342
			$fspans = $fspane = "";
343
		}
344
                // $lip = ip2ulong($data['ip']);
345
		if ($data['act'] == "static") {
346
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
347
				if(is_array($dhcpifconf['staticmap'])) {
348
					foreach ($dhcpifconf['staticmap'] as $staticent) {
349
						if ($data['ip'] == $staticent['ipaddr']) {
350
							$data['if'] = $dhcpif;
351
							break;
352
						}
353
					}
354
				}
355
				/* exit as soon as we have an interface */
356
				if ($data['if'] != "")
357
					break;
358
			}
359
		} else {
360
                	foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {	
361
                        	if (($lip >= ip2ulong($dhcpifconf['range']['from'])) && ($lip <= ip2ulong($dhcpifconf['range']['to']))) {
362
                                	$data['if'] = $dhcpif;
363
                                	break;
364
                        	}
365
			}
366
                }		
367
		echo "<tr>\n";
368
                echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
369
		echo "<td class=\"listr\">{$fspans}{$data['duid']}{$fspane}&nbsp;</td>\n";
370
                echo "<td class=\"listr\">{$fspans}"  . htmlentities($data['hostname']) . "{$fspane}&nbsp;</td>\n";
371
				if ($data['type'] != "static") {
372
					echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}&nbsp;</td>\n";
373
					echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}&nbsp;</td>\n";
374
				} else {
375
					echo "<td class=\"listr\">{$fspans} n/a {$fspane}&nbsp;</td>\n";
376
					echo "<td class=\"listr\">{$fspans} n/a {$fspane}&nbsp;</td>\n";
377
				}
378
                echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}&nbsp;</td>\n";
379
                echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}&nbsp;</td>\n";
380
		
381
		if ($data['type'] == "dynamic") {
382
			echo "<td valign=\"middle\"><a href=\"services_dhcpv6_edit.php?if={$data['if']}&duid={$data['duid']}&hostname={$data['hostname']}\">";
383
			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") ."\"></a></td>\n";
384
		} else {
385
                	echo "<td class=\"list\" valign=\"middle\">";
386
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus_mo.gif\" width=\"17\" height=\"17\" border=\"0\"></td>\n";
387
		}
388

    
389
		/* Only show the button for offline dynamic leases */
390
		if (($data['type'] == "dynamic") && ($data['online'] != "online")) {
391
			echo "<td class=\"list\" valign=\"middle\"><a href=\"status_dhcpv6_leases.php?deleteip={$data['ip']}&all=" . htmlspecialchars($_GET['all']) . "\">";
392
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"" . gettext("delete this DHCP lease") . "\"></a></td>\n";
393
		}
394
                echo "</tr>\n";
395
	}
396
}
397

    
398
?>
399
</table>
400
<p>
401
<form action="status_dhcpv6_leases.php" method="GET">
402
<input type="hidden" name="order" value="<?=htmlspecialchars($_GET['order']);?>">
403
<?php if ($_GET['all']): ?>
404
<input type="hidden" name="all" value="0">
405
<input type="submit" class="formbtn" value="<?=gettext("Show active and static leases only"); ?>">
406
<?php else: ?>
407
<input type="hidden" name="all" value="1">
408
<input type="submit" class="formbtn" value="<?=gettext("Show all configured leases"); ?>">
409
<?php endif; ?>
410
</form>
411
<?php if($leases == 0): ?>
412
<p><strong><?=gettext("No leases file found. Is the DHCP server active"); ?>?</strong></p>
413
<?php endif; ?>
414

    
415
<?php include("fend.inc"); ?>
416
</body>
417
</html>
(165-165/232)