Project

General

Profile

Download (10.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	diag_arp.php
4
	part of the pfSense project	(http://www.pfsense.org)
5
	Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com>
6

    
7
	originally part of m0n0wall (http://m0n0.ch/wall)
8
	Copyright (C) 2005 Paul Taylor (paultaylor@winndixie.com) and Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10

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

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

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

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

    
33
/*
34
	pfSense_BUILDER_BINARIES:	/bin/cat		/usr/sbin/arp
35
	pfSense_MODULE:	arp
36
*/
37

    
38
##|+PRIV
39
##|*IDENT=page-diagnostics-arptable
40
##|*NAME=Diagnostics: ARP Table page
41
##|*DESCR=Allow access to the 'Diagnostics: ARP Table' page.
42
##|*MATCH=diag_arp.php*
43
##|-PRIV
44

    
45
@ini_set('zlib.output_compression', 0);
46
@ini_set('implicit_flush', 1);
47

    
48
require("guiconfig.inc");
49

    
50
function leasecmp($a, $b) {
51
	return strcmp($a[$_GET['order']], $b[$_GET['order']]);
52
}
53

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

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

    
68
// Define path to AWK
69
$awk = "/usr/bin/awk";
70

    
71
// Read in leases file
72
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
73

    
74
/* this pattern sticks comments into a single array item */
75
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
76

    
77
/* We then split the leases file by } */
78
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
79

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

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

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

    
200
if(count($pools) > 0) {
201
        $pools = remove_duplicate($pools,"name");
202
        asort($pools);
203
}
204

    
205
// Put this in an easy to use form
206
$dhcpmac = array();
207
$dhcpip = array();
208

    
209
foreach ($leases as $value) {
210
	$dhcpmac[$value['mac']] = $value['hostname'];
211
	$dhcpip[$value['ip']] = $value['hostname'];
212
}
213

    
214
exec("/usr/sbin/arp -an",$rawdata);
215

    
216
$i = 0;
217

    
218
/* if list */
219
$ifdescrs = get_configured_interface_with_descr();
220

    
221
foreach ($ifdescrs as $key =>$interface) {
222
	$hwif[$config['interfaces'][$key]['if']] = $interface;
223
}
224

    
225
$data = array();
226
foreach ($rawdata as $line) {
227
	$elements = explode(' ',$line);
228

    
229
	if ($elements[3] != "(incomplete)") {
230
		$arpent = array();
231
		$arpent['ip'] = trim(str_replace(array('(',')'),'',$elements[1]));
232
		$arpent['mac'] = trim($elements[3]);
233
		$arpent['interface'] = trim($elements[5]);
234
		$data[] = $arpent;
235
	}
236
}
237

    
238
function _getHostName($mac,$ip)
239
{
240
	global $dhcpmac, $dhcpip;
241

    
242
	if ($dhcpmac[$mac])
243
		return $dhcpmac[$mac];
244
	else if ($dhcpip[$ip])
245
		return $dhcpip[$ip];
246
	else if(gethostbyaddr($ip) <> "" and gethostbyaddr($ip) <> $ip)
247
		return gethostbyaddr($ip);
248
	else
249
		return "";
250
}
251

    
252
$pgtitle = array(gettext("Diagnostics"),gettext("ARP Table"));
253
include("head.inc");
254

    
255
?>
256

    
257
<body link="#000000" vlink="#000000" alink="#000000">
258

    
259
<?php include("fbegin.inc"); ?>
260

    
261
<div id="loading">
262
	<img src="/themes/<?=$g['theme'];?>/images/misc/loader.gif"><?= gettext("Loading, please wait..."); ?>
263
	<p/>&nbsp;
264
</div>
265

    
266
<?php
267

    
268
// Flush buffers out to client so that they see Loading, please wait....
269
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
270
ob_implicit_flush(1);
271

    
272
// Resolve hostnames and replace Z_ with "".  The intention
273
// is to sort the list by hostnames, alpha and then the non
274
// resolvable addresses will appear last in the list.
275
foreach ($data as &$entry) {
276
	$dns = trim(_getHostName($entry['mac'], $entry['ip']));
277
	if(trim($dns))
278
		$entry['dnsresolve'] = "$dns";
279
	else
280
		$entry['dnsresolve'] = "Z_ ";
281
}
282

    
283
// Sort the data alpha first
284
$data = msort($data, "dnsresolve");
285

    
286
?>
287
<table width="100%" border="0" cellpadding="0" cellspacing="0">
288
	<tr>
289
		<td>
290
			<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
291
				<tr>
292
					<td class="listhdrr"><?= gettext("IP address"); ?></td>
293
					<td class="listhdrr"><?= gettext("MAC address"); ?></td>
294
					<td class="listhdrr"><?= gettext("Hostname"); ?></td>
295
					<td class="listhdr"><?= gettext("Interface"); ?></td>
296
					<td class="list"></td>
297
				</tr>
298
				<?php foreach ($data as $entry): ?>
299
					<tr>
300
						<td class="listlr"><?=$entry['ip'];?></td>
301
						<td class="listr"><?=$entry['mac'];?></td>
302
						<td class="listr">
303
							<?php
304
							echo str_replace("Z_ ", "", $entry['dnsresolve']);
305
							?>
306
						</td>
307
						<td class="listr"><?=$hwif[$entry['interface']];?></td>
308
					</tr>
309
				<?php endforeach; ?>
310
			</table>
311
		</td>
312
	</tr>
313
</table>
314

    
315
<?php include("fend.inc"); ?>
316

    
317
<script type="text/javascript">
318
	$('loading').innerHTML = '';
319
</script>
(5-5/225)