Project

General

Profile

« Previous | Next » 

Revision c1640267

Added by Seth Mos over 14 years ago

Add the initial broken dhcp v6 leases page. I have no file to code it. Will wait for later.

View differences:

usr/local/www/status_dhcpv6_leases.php
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
/* this pattern sticks comments into a single array item */
114
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
115
/* We then split the leases file by } */
116
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
117

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

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

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

  
243
/* remove duplicate items by mac address */
244
if(count($leases) > 0) {
245
	$leases = remove_duplicate($leases,"ip");
246
}
247

  
248
if(count($pools) > 0) {
249
	$pools = remove_duplicate($pools,"name");
250
	asort($pools);
251
}
252

  
253
foreach($config['interfaces'] as $ifname => $ifarr) {
254
	if (is_array($config['dhcpdv6'][$ifname]) && 
255
		is_array($config['dhcpdv6'][$ifname]['staticmap'])) {
256
		foreach($config['dhcpdv6'][$ifname]['staticmap'] as $static) {
257
			$slease = array();
258
			$slease['ipv6'] = $static['ipaddr'];
259
			$slease['type'] = "static";
260
			$slease['mac'] = $static['mac'];
261
			$slease['start'] = "";
262
			$slease['end'] = "";
263
			$slease['hostname'] = htmlentities($static['hostname']);
264
			$slease['act'] = "static";
265
			$online = exec("/usr/sbin/arp -an |/usr/bin/grep {$slease['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
266
			if ($online == 1) {
267
				$slease['online'] = 'online';
268
			} else {
269
				$slease['online'] = 'offline';
270
			}
271
			$leases[] = $slease;
272
		}
273
	}
274
}
275

  
276
if ($_GET['order'])
277
	usort($leases, "leasecmp");
278

  
279
/* only print pool status when we have one */
280
if(count($pools) > 0) {
281
?>
282
<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
283
  <tr>
284
    <td class="listhdrr"><?=gettext("Failover Group"); ?></a></td>
285
    <td class="listhdrr"><?=gettext("My State"); ?></a></td>
286
    <td class="listhdrr"><?=gettext("Since"); ?></a></td>
287
    <td class="listhdrr"><?=gettext("Peer State"); ?></a></td>
288
    <td class="listhdrr"><?=gettext("Since"); ?></a></td>
289
  </tr>
290
<?php
291
foreach ($pools as $data) {
292
	echo "<tr>\n";
293
	echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}&nbsp;</td>\n";
294
	echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}&nbsp;</td>\n";
295
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}&nbsp;</td>\n";
296
	echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}&nbsp;</td>\n";
297
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}&nbsp;</td>\n";
298
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
299
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
300
	echo "</tr>\n";
301
}
302

  
303
?>
304
</table>
305

  
306
<?php
307
/* only print pool status when we have one */
308
}
309
?>
310

  
311
<p>
312

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

  
381
                echo "<td valign=\"middle\"><a href=\"services_wol_edit.php?if={$data['if']}&mac={$data['mac']}&descr={$data['hostname']}\">";
382
		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") ."\"></a></td>\n";
383

  
384
		/* Only show the button for offline dynamic leases */
385
		if (($data['type'] == "dynamic") && ($data['online'] != "online")) {
386
			echo "<td class=\"list\" valign=\"middle\"><a href=\"status_dhcp_leases.php?deleteip={$data['ip']}&all=" . htmlspecialchars($_GET['all']) . "\">";
387
			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";
388
		}
389
                echo "</tr>\n";
390
	}
391
}
392

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

  
410
<?php include("fend.inc"); ?>
411
</body>
412
</html>

Also available in: Unified diff