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

    
81
// Put everything together again
82
while($i < $leases_count) {
83
	/* split the line by space */
84
	$data = explode(" ", $leases_content[$i]);
85
	/* walk the fields */
86
	$f = 0;
87
	$fcount = count($data);
88
	while($f < $fcount) {
89
		if ($data[$f] == "lease") {
90
			$leases[$i]['ip'] = $data[$f+1];
91
			$leases[$i]['type'] = "dynamic";
92
		}
93
		if ($data[$f] == "failover") {
94
			$pools[$i]['name'] = $data[$f+2];
95
			$pools[$i]['mystate'] = $data[$f+7];
96
			$pools[$i]['peerstate'] = $data[$f+14];
97
			$pools[$i]['mydate'] = $data[$f+10];
98
			$pools[$i]['mydate'] .= " " . $data[$f+11];
99
			$pools[$i]['peerdate'] = $data[$f+17];
100
			$pools[$i]['peerdate'] .= " " . $data[$f+18];
101
		}
102
		if ($data[$f] == "client-hostname") {
103
			if($data[$f] <> "") {
104
				$leases[$i]['hostname'] = preg_replace('/"/','',$data[$f+1]);
105
			} else {
106
				$hostname = gethostbyaddr($leases[$i]['ip']);
107
				if($hostname <> "") {
108
					$leases[$i]['hostname'] = $hostname;
109
				}
110
			}
111
		}	
112
		if ($data[$f] == "hardware") {
113
			if ($data[$f+1] == "ethernet") {
114
				$leases[$i]['mac'] = $data[$f+2];
115
				/* check if it's online */
116
				$online = exec("/usr/sbin/arp -an |/usr/bin/grep {$leases[$i]['mac']}| grep {$leases[$i]['ip']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
117
				if ($online == 1) {
118
					$leases[$i]['online'] = 'online';
119
				} else {
120
					$leases[$i]['online'] = 'offline';
121
				}
122
			}
123
		} else if ($data[$f] == "starts") {
124
			$leases[$i]['start'] = $data[$f+2];
125
			$leases[$i]['start'] .= " " . $data[$f+3];
126
		} else if ($data[$f] == "ends") {
127
			$leases[$i]['end'] = $data[$f+2];
128
			$leases[$i]['end'] .= " " . $data[$f+3];
129
		} else if (($data[$f] == "binding") && (!isset($leases[$i]['act']))){
130
			if ($data[$f+1] == "state") {
131
				switch($data[$f+2]) {
132
					case 'active':
133
						$leases[$i]['act'] = 'active';
134
						break;
135
					case 'free':
136
						$leases[$i]['act'] = 'expired';
137
						break;
138
					case 'backup':
139
						$leases[$i]['act'] = 'reserved';	
140
						$leases[$i]['online'] = 'offline';
141
						break;
142
				}
143
			}
144
		} elseif (($data[$f] == "}") && ($data[1] == 1)) {
145
			// End of group
146
			//updated leases are appended to the end of the lease file. if we aren't
147
			//showing everything just show the most current lease in the list
148
			if(!$_GET['all']) {
149
				$l = $leases[$i]['ip'];
150
				for($k = 0; $k < $i; $k++) {
151
					if($leases[$k]['ip'] == $l) {
152
						array_splice($leases, $k, 1);
153
						--$i;
154
						break;
155
						}
156
				}
157
			}
158
		}
159
		$f++;
160
	}
161
	$i++;
162
}
163

    
164
/* remove duplicate items by mac address */
165
if(count($leases) > 0) {
166
	$leases = remove_duplicate($leases,"mac");
167
}
168
if(count($pools) > 0) {
169
	$pools = remove_duplicate($pools,"name");
170
	asort($pools);
171
}
172

    
173
foreach($config['interfaces'] as $ifname => $ifarr) {
174
	if (is_array($config['dhcpd'][$ifname]['staticmap'])) {
175
		foreach($config['dhcpd'][$ifname]['staticmap'] as $static) {
176
			$slease = array();
177
			$slease['ip'] = $static['ipaddr'];
178
			$slease['type'] = "static";
179
			$slease['mac'] = $static['mac'];
180
			$slease['start'] = gmdate("M d Y H:i:s", time());
181
			$slease['end'] = gmdate("M d Y H:i:s", time());
182
			$slease['end'] = gmdate("M d Y H:i:s", strtotime('+5 minutes'));
183
			$slease['hostname'] = $static['hostname'];
184
			$slease['act'] = "static";
185
			$online = exec("/usr/sbin/arp -an |/usr/bin/grep {$slease['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
186
			if ($online == 1) {
187
				$slease['online'] = 'online';
188
			} else {
189
				$slease['online'] = 'offline';
190
			}
191
			$leases[] = $slease;
192
		}
193
	}
194
}
195

    
196
if ($_GET['order'])
197
	usort($leases, "leasecmp");
198

    
199
?>
200

    
201
<?php
202
/* only print pool status when we have one */
203
if(count($pools) > 0) {
204
?>
205
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
206
  <tr>
207
    <td class="listhdrr">Failover Group</a></td>
208
    <td class="listhdrr">My State</a></td>
209
    <td class="listhdrr">Since</a></td>
210
    <td class="listhdrr">Peer State</a></td>
211
    <td class="listhdrr">Since</a></td>
212
  </tr>
213
<?php
214
foreach ($pools as $data) {
215
	echo "<tr>\n";
216
	echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}&nbsp;</td>\n";
217
	echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}&nbsp;</td>\n";
218
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}&nbsp;</td>\n";
219
	echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}&nbsp;</td>\n";
220
	echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}&nbsp;</td>\n";
221
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
222
	echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n";
223
	echo "</tr>\n";
224
}
225

    
226
?>
227
</table>
228

    
229
<?php
230
/* only print pool status when we have one */
231
}
232
?>
233

    
234
<p>
235

    
236
<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
237
  <tr>
238
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=ip">IP address</a></td>
239
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=mac">MAC address</a></td>
240
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=hostname">Hostname</a></td>
241
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=start">Start</a></td>
242
    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=end">End</a></td>
243
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=online">Online</a></td>
244
    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=act">Lease Type</a></td>
245
	</tr>
246
<?php
247
foreach ($leases as $data) {
248
	if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) {
249
		if ($data['act'] != "active" && $data['act'] != "static") {
250
			$fspans = "<span class=\"gray\">";
251
			$fspane = "</span>";
252
		} else {
253
			$fspans = $fspane = "";
254
		}
255
                $lip = ip2long($data['ip']);
256
		if ($data['act'] == "static") {
257
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
258
				if(is_array($dhcpifconf['staticmap'])) {
259
					foreach ($dhcpifconf['staticmap'] as $staticent) {
260
						if ($data['ip'] == $staticent['ipaddr']) {
261
							$data['if'] = $dhcpif;
262
							break;
263
						}
264
					}
265
				}
266
				/* exit as soon as we have an interface */
267
				if ($data['if'] != "")
268
					break;
269
			}
270
		} else {
271
                	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
272
                        	if (($lip >= ip2long($dhcpifconf['range']['from'])) && ($lip <= ip2long($dhcpifconf['range']['to']))) {
273
                                	$data['if'] = $dhcpif;
274
                                	break;
275
                        	}
276
			}
277
                }		
278
		echo "<tr>\n";
279
                echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
280
                if ($data['online'] != "online") {
281
                        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";
282
                } else {
283
                	echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}&nbsp;</td>\n";
284
                }
285
                echo "<td class=\"listr\">{$fspans}{$data['hostname']}{$fspane}&nbsp;</td>\n";
286
                echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}&nbsp;</td>\n";
287
                echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}&nbsp;</td>\n";
288
                echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}&nbsp;</td>\n";
289
                echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}&nbsp;</td>\n";
290
		
291
		if ($data['type'] == "dynamic") {
292
                	echo "<td class=\"list\" valign=\"middle\"><a href=\"services_dhcp_edit.php?if={$data['if']}&mac={$data['mac']}&hostname={$data['hostname']}\">";
293
			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";
294
		} else {
295
                	echo "<td class=\"list\" valign=\"middle\">";
296
			echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_plus_mo.gif\" width=\"17\" height=\"17\" border=\"0\"></td>\n";
297
		}
298

    
299
                echo "<td valign=\"middle\"><a href=\"services_wol_edit.php?if={$data['if']}&mac={$data['mac']}&descr={$data['hostname']}\">";
300
		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";
301
                echo "</tr>\n";
302
	}
303
}
304

    
305
?>
306
</table>
307
<p>
308
<form action="diag_dhcp_leases.php" method="GET">
309
<input type="hidden" name="order" value="<?=$_GET['order'];?>">
310
<?php if ($_GET['all']): ?>
311
<input type="hidden" name="all" value="0">
312
<input type="submit" class="formbtn" value="Show active and static leases only">
313
<?php else: ?>
314
<input type="hidden" name="all" value="1">
315
<input type="submit" class="formbtn" value="Show all configured leases">
316
<?php endif; ?>
317
</form>
318
<?php if($leases == 0): ?>
319
<p><strong>No leases file found. Is the DHCP server active?</strong></p>
320
<?php endif; ?>
321

    
322
<meta http-equiv="refresh" content="120;url=<?php print $_SERVER['SCRIPT_NAME']; ?>">
323

    
324
<?php include("fend.inc"); ?>
325
</body>
326
</html>
(8-8/167)