Project

General

Profile

Download (11.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	diag_dhcp_leases.php
5
	Copyright (C) 2004 Scott Ullrich
6
	All rights reserved.
7

    
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
	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
require("guiconfig.inc");
35

    
36
$pgtitle = array("Status","DHCP leases");
37
include("head.inc");
38

    
39
?>
40

    
41
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
42
<script src="/javascript/sorttable.js"></script>
43
<?php include("fbegin.inc"); ?>
44
<?php
45

    
46
function leasecmp($a, $b) {
47
        return strcmp($a[$_GET['order']], $b[$_GET['order']]);
48
}
49

    
50
function adjust_gmt($dt) {
51
        $ts = strtotime($dt . " GMT");
52
        return strftime("%Y/%m/%d %H:%M:%S", $ts);
53
}
54

    
55
function remove_duplicate($array, $field)
56
{
57
  foreach ($array as $sub)
58
   $cmp[] = $sub[$field];
59
  $unique = array_unique($cmp);
60
  foreach ($unique as $k => $rien)
61
   $new[] = $array[$k];
62
  return $new;
63
}
64

    
65
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
66
$awk = "/usr/bin/awk";
67
/* this pattern sticks comments into a single array item */
68
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
69
/* We then split the leases file by } */
70
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
71

    
72
/* stuff the leases file in a proper format into a array by line */
73
exec("cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
74
$leases_count = count($leases_content);
75

    
76
exec("/usr/sbin/arp -an", $rawdata);
77
$arpdata = array();
78
foreach ($rawdata as $line) {
79
	$elements = explode(' ',$line);
80
	if ($elements[3] != "(incomplete)") {
81
		$arpent = array();
82
		$arpent['ip'] = trim(str_replace(array('(',')'),'',$elements[1]));
83
		// $arpent['mac'] = trim($elements[3]);
84
		// $arpent['interface'] = trim($elements[5]);
85
	$arpdata[] = $arpent['ip'];
86
	}
87
}
88

    
89
$pools = array();
90
$leases = array();
91
$i = 0;
92
$l = 0;
93
$p = 0;
94

    
95
// Put everything together again
96
while($i < $leases_count) {
97
	/* split the line by space */
98
	$data = explode(" ", $leases_content[$i]);
99
	/* walk the fields */
100
	$f = 0;
101
	$fcount = count($data);
102
	/* with less then 20 fields there is nothing useful */
103
	if($fcount < 20) {
104
		$i++;
105
		continue;
106
	}
107
	while($f < $fcount) {
108
		switch($data[$f]) {
109
			case "failover":
110
				$pools[$p]['name'] = $data[$f+2];
111
				$pools[$p]['mystate'] = $data[$f+7];
112
				$pools[$p]['peerstate'] = $data[$f+14];
113
				$pools[$p]['mydate'] = $data[$f+10];
114
				$pools[$p]['mydate'] .= " " . $data[$f+11];
115
				$pools[$p]['peerdate'] = $data[$f+17];
116
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
117
				$p++;
118
				$i++;
119
				continue 3;
120
			case "lease":
121
				$leases[$l]['ip'] = $data[$f+1];
122
				$leases[$l]['type'] = "dynamic";
123
				$f = $f+2;
124
				break;
125
			case "starts":
126
				$leases[$l]['start'] = $data[$f+2];
127
				$leases[$l]['start'] .= " " . $data[$f+3];
128
				$f = $f+3;
129
				break;
130
			case "ends":
131
				$leases[$l]['end'] = $data[$f+2];
132
				$leases[$l]['end'] .= " " . $data[$f+3];
133
				$f = $f+3;
134
				break;
135
			case "tstp":
136
				$f = $f+3;
137
				break;
138
			case "tsfp":
139
				$f = $f+3;
140
				break;
141
			case "atsfp":
142
				$f = $f+3;
143
				break;
144
			case "cltt":
145
				$f = $f+3;
146
				break;
147
			case "binding":
148
				switch($data[$f+2]) {
149
					case "active":
150
						$leases[$l]['act'] = "active";
151
						break;
152
					case "free":
153
						$leases[$l]['act'] = "expired";
154
						$leases[$l]['online'] = "offline";
155
						break;
156
					case "backup":
157
						$leases[$l]['act'] = "reserved";
158
						$leases[$l]['online'] = "offline";
159
						break;
160
				}
161
				$f = $f+1;
162
				break;
163
			case "next":
164
				/* skip the next binding statement */
165
				$f = $f+3;
166
				break;
167
			case "hardware":
168
				$leases[$l]['mac'] = $data[$f+2];
169
				/* check if it's online and the lease is active */
170
				if (in_array($leases[$l]['ip'], $arpdata)) {
171
					$leases[$l]['online'] = 'online';
172
				} else {
173
					$leases[$l]['online'] = 'offline';
174
				}
175
				$f = $f+2;
176
				break;
177
			case "client-hostname":
178
				if($data[$f+1] <> "") {
179
					$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
180
				} else {
181
					$hostname = gethostbyaddr($leases[$l]['ip']);
182
					if($hostname <> "") {
183
						$leases[$l]['hostname'] = $hostname;
184
					}
185
				}
186
				$f = $f+1;
187
				break;
188
			case "uid":
189
				$f = $f+1;
190
				break;
191
		}
192
		$f++;
193
	}
194
	$l++;
195
	$i++;
196
}
197

    
198
/* remove duplicate items by mac address */
199
if(count($leases) > 0) {
200
	$leases = remove_duplicate($leases,"ip");
201
}
202

    
203
if(count($pools) > 0) {
204
	$pools = remove_duplicate($pools,"name");
205
	asort($pools);
206
}
207

    
208
foreach($config['interfaces'] as $ifname => $ifarr) {
209
	if (is_array($config['dhcpd'][$ifname]['staticmap'])) {
210
		foreach($config['dhcpd'][$ifname]['staticmap'] as $static) {
211
			$slease = array();
212
			$slease['ip'] = $static['ipaddr'];
213
			$slease['type'] = "static";
214
			$slease['mac'] = $static['mac'];
215
			$slease['start'] = gmdate("M d Y H:i:s", time());
216
			$slease['end'] = gmdate("M d Y H:i:s", time());
217
			$slease['end'] = gmdate("M d Y H:i:s", strtotime('+5 minutes'));
218
			$slease['hostname'] = htmlentities($static['hostname']);
219
			$slease['act'] = "static";
220
			$online = exec("/usr/sbin/arp -an |/usr/bin/grep {$slease['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
221
			if ($online == 1) {
222
				$slease['online'] = 'online';
223
			} else {
224
				$slease['online'] = 'offline';
225
			}
226
			$leases[] = $slease;
227
		}
228
	}
229
}
230

    
231
if ($_GET['order'])
232
	usort($leases, "leasecmp");
233

    
234
?>
235

    
236
<?php
237
/* only print pool status when we have one */
238
if(count($pools) > 0) {
239
?>
240
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
241
  <tr>
242
    <td class="listhdrr">Failover Group</a></td>
243
    <td class="listhdrr">My State</a></td>
244
    <td class="listhdrr">Since</a></td>
245
    <td class="listhdrr">Peer State</a></td>
246
    <td class="listhdrr">Since</a></td>
247
  </tr>
248
<?php
249
foreach ($pools as $data) {
250
	echo "<tr>\n";
251
	echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}&nbsp;</td>\n";
252
	echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}&nbsp;</td>\n";
253
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}&nbsp;</td>\n";
254
	echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}&nbsp;</td>\n";
255
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}&nbsp;</td>\n";
256
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
257
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
258
	echo "</tr>\n";
259
}
260

    
261
?>
262
</table>
263

    
264
<?php
265
/* only print pool status when we have one */
266
}
267
?>
268

    
269
<p>
270

    
271
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
272
  <tr>
273
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=ip">IP address</a></td>
274
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=mac">MAC address</a></td>
275
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=hostname">Hostname</a></td>
276
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=start">Start</a></td>
277
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=end">End</a></td>
278
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=online">Online</a></td>
279
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=act">Lease Type</a></td>
280
	</tr>
281
<?php
282
foreach ($leases as $data) {
283
	if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) {
284
		if ($data['act'] != "active" && $data['act'] != "static") {
285
			$fspans = "<span class=\"gray\">";
286
			$fspane = "</span>";
287
		} else {
288
			$fspans = $fspane = "";
289
		}
290
                $lip = ip2long($data['ip']);
291
		if ($data['act'] == "static") {
292
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
293
				if(is_array($dhcpifconf['staticmap'])) {
294
					foreach ($dhcpifconf['staticmap'] as $staticent) {
295
						if ($data['ip'] == $staticent['ipaddr']) {
296
							$data['if'] = $dhcpif;
297
							break;
298
						}
299
					}
300
				}
301
				/* exit as soon as we have an interface */
302
				if ($data['if'] != "")
303
					break;
304
			}
305
		} else {
306
                	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {	
307
                        	if (($lip >= ip2long($dhcpifconf['range']['from'])) && ($lip <= ip2long($dhcpifconf['range']['to']))) {
308
                                	$data['if'] = $dhcpif;
309
                                	break;
310
                        	}
311
			}
312
                }		
313
		echo "<tr>\n";
314
                echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
315
                if ($data['online'] != "online") {
316
                        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";
317
                } else {
318
                	echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}&nbsp;</td>\n";
319
                }
320
                echo "<td class=\"listr\">{$fspans}"  . htmlentities($data['hostname']) . "{$fspane}&nbsp;</td>\n";
321
                echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}&nbsp;</td>\n";
322
                echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}&nbsp;</td>\n";
323
                echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}&nbsp;</td>\n";
324
                echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}&nbsp;</td>\n";
325
		
326
		if ($data['type'] == "dynamic") {
327
                	echo "<td class=\"list\" valign=\"middle\"><a href=\"services_dhcp_edit.php?if={$data['if']}&mac={$data['mac']}&hostname={$data['hostname']}\">";
328
			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";
329
		} else {
330
                	echo "<td class=\"list\" valign=\"middle\">";
331
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus_mo.gif\" width=\"17\" height=\"17\" border=\"0\"></td>\n";
332
		}
333

    
334
                echo "<td valign=\"middle\"><a href=\"services_wol_edit.php?if={$data['if']}&mac={$data['mac']}&descr={$data['hostname']}\">";
335
		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";
336
                echo "</tr>\n";
337
	}
338
}
339

    
340
?>
341
</table>
342
<p>
343
<form action="diag_dhcp_leases.php" method="GET">
344
<input type="hidden" name="order" value="<?=$_GET['order'];?>">
345
<?php if ($_GET['all']): ?>
346
<input type="hidden" name="all" value="0">
347
<input type="submit" class="formbtn" value="Show active and static leases only">
348
<?php else: ?>
349
<input type="hidden" name="all" value="1">
350
<input type="submit" class="formbtn" value="Show all configured leases">
351
<?php endif; ?>
352
</form>
353
<?php if($leases == 0): ?>
354
<p><strong>No leases file found. Is the DHCP server active?</strong></p>
355
<?php endif; ?>
356

    
357
<?php include("fend.inc"); ?>
358
</body>
359
</html>
(8-8/189)