Project

General

Profile

Download (11.6 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 = "Diagnostics: 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
<p class="pgtitle"><?=$pgtitle?></p>
45
<?php
46

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

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

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

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

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

    
77
$pools = array();
78
$leases = array();
79
$i = 0;
80
$l = 0;
81
$p = 0;
82

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

    
189
/* remove duplicate items by mac address */
190
if(count($leases) > 0) {
191
	$leases = remove_duplicate($leases,"ip");
192
}
193

    
194
if(count($pools) > 0) {
195
	$pools = remove_duplicate($pools,"name");
196
	asort($pools);
197
}
198

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

    
222
if ($_GET['order'])
223
	usort($leases, "leasecmp");
224

    
225
?>
226

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

    
252
?>
253
</table>
254

    
255
<?php
256
/* only print pool status when we have one */
257
}
258
?>
259

    
260
<p>
261

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

    
325
                echo "<td valign=\"middle\"><a href=\"services_wol_edit.php?if={$data['if']}&mac={$data['mac']}&descr={$data['hostname']}\">";
326
		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";
327
                echo "</tr>\n";
328
	}
329
}
330

    
331
?>
332
</table>
333
<p>
334
<form action="diag_dhcp_leases.php" method="GET">
335
<input type="hidden" name="order" value="<?=$_GET['order'];?>">
336
<?php if ($_GET['all']): ?>
337
<input type="hidden" name="all" value="0">
338
<input type="submit" class="formbtn" value="Show active and static leases only">
339
<?php else: ?>
340
<input type="hidden" name="all" value="1">
341
<input type="submit" class="formbtn" value="Show all configured leases">
342
<?php endif; ?>
343
</form>
344
<?php if($leases == 0): ?>
345
<p><strong>No leases file found. Is the DHCP server active?</strong></p>
346
<?php endif; ?>
347

    
348
<?php include("fend.inc"); ?>
349
</body>
350
</html>
(8-8/173)