Project

General

Profile

Download (9.31 KB) Statistics
| Branch: | Tag: | Revision:
1 93e1b16c Scott Ullrich
<?php
2
/*
3
	diag_arp.php
4 c7281770 Chris Buechler
	part of the pfSense project	(https://www.pfsense.org)
5 13d193c2 Scott Ullrich
	Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com>
6 6317d31d Phil Davis
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
7 93e1b16c Scott Ullrich
8 20b9b335 Scott Ullrich
	originally part of m0n0wall (http://m0n0.ch/wall)
9 93e1b16c Scott Ullrich
	Copyright (C) 2005 Paul Taylor (paultaylor@winndixie.com) and 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 13d193c2 Scott Ullrich
/*
35
	pfSense_BUILDER_BINARIES:	/bin/cat		/usr/sbin/arp
36
	pfSense_MODULE:	arp
37
*/
38
39 6b07c15a Matthew Grooms
##|+PRIV
40
##|*IDENT=page-diagnostics-arptable
41
##|*NAME=Diagnostics: ARP Table page
42
##|*DESCR=Allow access to the 'Diagnostics: ARP Table' page.
43
##|*MATCH=diag_arp.php*
44
##|-PRIV
45
46 868ba36d Scott Ullrich
@ini_set('zlib.output_compression', 0);
47
@ini_set('implicit_flush', 1);
48 6b07c15a Matthew Grooms
49 93e1b16c Scott Ullrich
require("guiconfig.inc");
50 6090e85b Bill Marquette
51 fc259334 Seth Mos
function leasecmp($a, $b) {
52
	return strcmp($a[$_GET['order']], $b[$_GET['order']]);
53
}
54 93e1b16c Scott Ullrich
55 fc259334 Seth Mos
function adjust_gmt($dt) {
56
	$ts = strtotime($dt . " GMT");
57
	return strftime("%Y/%m/%d %H:%M:%S", $ts);
58
}
59 93e1b16c Scott Ullrich
60 fc259334 Seth Mos
function remove_duplicate($array, $field) {
61 20b9b335 Scott Ullrich
	foreach ($array as $sub)
62
		$cmp[] = $sub[$field];
63 fc259334 Seth Mos
	$unique = array_unique($cmp);
64
	foreach ($unique as $k => $rien)
65
		$new[] = $array[$k];
66
	return $new;
67
}
68 93e1b16c Scott Ullrich
69 20b9b335 Scott Ullrich
// Define path to AWK
70 fc259334 Seth Mos
$awk = "/usr/bin/awk";
71 20b9b335 Scott Ullrich
72
// Read in leases file
73
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
74
75 fc259334 Seth Mos
/* this pattern sticks comments into a single array item */
76
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
77 20b9b335 Scott Ullrich
78 fc259334 Seth Mos
/* We then split the leases file by } */
79
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
80 93e1b16c Scott Ullrich
81 fc259334 Seth Mos
/* stuff the leases file in a proper format into a array by line */
82
exec("cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
83
$leases_count = count($leases_content);
84
85
$pools = array();
86
$leases = array();
87
$i = 0;
88
$l = 0;
89
$p = 0;
90
// Put everything together again
91
while($i < $leases_count) {
92 b45630bf jim-p
	/* split the line by space */
93
	$data = explode(" ", $leases_content[$i]);
94
	/* walk the fields */
95
	$f = 0;
96
	$fcount = count($data);
97
	/* with less then 20 fields there is nothing useful */
98
	if($fcount < 20) {
99
		$i++;
100
		continue;
101
	}
102
	while($f < $fcount) {
103
		switch($data[$f]) {
104
			case "failover":
105
				$pools[$p]['name'] = $data[$f+2];
106
				$pools[$p]['mystate'] = $data[$f+7];
107
				$pools[$p]['peerstate'] = $data[$f+14];
108
				$pools[$p]['mydate'] = $data[$f+10];
109
				$pools[$p]['mydate'] .= " " . $data[$f+11];
110
				$pools[$p]['peerdate'] = $data[$f+17];
111
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
112
				$p++;
113
				$i++;
114
				continue 3;
115
			case "lease":
116
				$leases[$l]['ip'] = $data[$f+1];
117
				$leases[$l]['type'] = "dynamic";
118
				$f = $f+2;
119
				break;
120
			case "starts":
121
				$leases[$l]['start'] = $data[$f+2];
122
				$leases[$l]['start'] .= " " . $data[$f+3];
123
				$f = $f+3;
124
				break;
125
			case "ends":
126
				$leases[$l]['end'] = $data[$f+2];
127
				$leases[$l]['end'] .= " " . $data[$f+3];
128
				$f = $f+3;
129
				break;
130
			case "tstp":
131
				$f = $f+3;
132
				break;
133
			case "tsfp":
134
				$f = $f+3;
135
				break;
136
			case "atsfp":
137
				$f = $f+3;
138
				break;
139
			case "cltt":
140
				$f = $f+3;
141
				break;
142
			case "binding":
143
				switch($data[$f+2]) {
144
					case "active":
145
						$leases[$l]['act'] = "active";
146
						break;
147
					case "free":
148
						$leases[$l]['act'] = "expired";
149
						$leases[$l]['online'] = "offline";
150
						break;
151
					case "backup":
152
						$leases[$l]['act'] = "reserved";
153
						$leases[$l]['online'] = "offline";
154
						break;
155
				}
156
				$f = $f+1;
157
				break;
158
			case "next":
159
				/* skip the next binding statement */
160
				$f = $f+3;
161
				break;
162 f1273b82 jim-p
			case "rewind":
163
				/* skip the rewind binding statement */
164
				$f = $f+3;
165
				break;
166 b45630bf jim-p
			case "hardware":
167
				$leases[$l]['mac'] = $data[$f+2];
168
				/* check if it's online and the lease is active */
169
				if($leases[$l]['act'] == "active") {
170
					$online = exec("/usr/sbin/arp -an |/usr/bin/awk '/{$leases[$l]['ip']}/ {print}'|wc -l");
171
					if ($online == 1) {
172
						$leases[$l]['online'] = 'online';
173
					} else {
174
						$leases[$l]['online'] = 'offline';
175
					}
176
				}
177
				$f = $f+2;
178
				break;
179
			case "client-hostname":
180
				if($data[$f+1] <> "") {
181
					$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
182
				} else {
183
					$hostname = gethostbyaddr($leases[$l]['ip']);
184
					if($hostname <> "") {
185
						$leases[$l]['hostname'] = $hostname;
186
					}
187
				}
188
				$f = $f+1;
189
				break;
190
			case "uid":
191
				$f = $f+1;
192
				break;
193
		}
194
		$f++;
195
	}
196
	$l++;
197
	$i++;
198 fc259334 Seth Mos
}
199
200
/* remove duplicate items by mac address */
201
if(count($leases) > 0) {
202 b45630bf jim-p
	$leases = remove_duplicate($leases,"ip");
203 fc259334 Seth Mos
}
204
205
if(count($pools) > 0) {
206 b45630bf jim-p
	$pools = remove_duplicate($pools,"name");
207
	asort($pools);
208 fc259334 Seth Mos
}
209
210
// Put this in an easy to use form
211
$dhcpmac = array();
212
$dhcpip = array();
213 f8ec8de4 Renato Botelho
214 fc259334 Seth Mos
foreach ($leases as $value) {
215 f8ec8de4 Renato Botelho
	$dhcpmac[$value['mac']] = $value['hostname'];
216
	$dhcpip[$value['ip']] = $value['hostname'];
217 93e1b16c Scott Ullrich
}
218
219
exec("/usr/sbin/arp -an",$rawdata);
220
221 f8ec8de4 Renato Botelho
$i = 0;
222 cbe3ea96 Ermal Luçi
223
/* if list */
224
$ifdescrs = get_configured_interface_with_descr();
225 93e1b16c Scott Ullrich
226 e7237dd0 jim-p
foreach ($ifdescrs as $key => $interface) {
227
	$thisif = convert_friendly_interface_to_real_interface_name($key);
228
	if (!empty($thisif))
229
		$hwif[$thisif] = $interface;
230 93e1b16c Scott Ullrich
}
231
232
$data = array();
233
foreach ($rawdata as $line) {
234
	$elements = explode(' ',$line);
235 f8ec8de4 Renato Botelho
236 93e1b16c Scott Ullrich
	if ($elements[3] != "(incomplete)") {
237
		$arpent = array();
238
		$arpent['ip'] = trim(str_replace(array('(',')'),'',$elements[1]));
239
		$arpent['mac'] = trim($elements[3]);
240
		$arpent['interface'] = trim($elements[5]);
241
		$data[] = $arpent;
242
	}
243
}
244
245 b45630bf jim-p
function _getHostName($mac,$ip) {
246 93e1b16c Scott Ullrich
	global $dhcpmac, $dhcpip;
247 f8ec8de4 Renato Botelho
248 93e1b16c Scott Ullrich
	if ($dhcpmac[$mac])
249
		return $dhcpmac[$mac];
250
	else if ($dhcpip[$ip])
251
		return $dhcpip[$ip];
252 dd4bded7 Evgeny Yurchenko
	else{
253 d31ca336 Renato Botelho
		exec("host -W 1 " . escapeshellarg($ip), $output);
254 4f5967b9 Phil Davis
		if (preg_match('/.*pointer ([A-Za-z_0-9.-]+)\..*/',$output[0],$matches)) {
255 dd4bded7 Evgeny Yurchenko
			if ($matches[1] <> $ip)
256
				return $matches[1]; 
257
		}
258
	}
259
	return "";
260 93e1b16c Scott Ullrich
}
261
262 f8ec8de4 Renato Botelho
$pgtitle = array(gettext("Diagnostics"),gettext("ARP Table"));
263 fc259334 Seth Mos
include("head.inc");
264 20b9b335 Scott Ullrich
265 93e1b16c Scott Ullrich
?>
266 20b9b335 Scott Ullrich
267 6db7ee23 xbipin
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
268 f8ec8de4 Renato Botelho
269 20b9b335 Scott Ullrich
<?php include("fbegin.inc"); ?>
270 4a993c8f Scott Ullrich
271
<div id="loading">
272 293ceb87 Colin Fleming
	<img src="/themes/<?=$g['theme'];?>/images/misc/loader.gif" alt="loader" /><?= gettext("Loading, please wait..."); ?>
273
	<p>&nbsp;</p>
274 4a993c8f Scott Ullrich
</div>
275
276
<?php
277
278 868ba36d Scott Ullrich
// Flush buffers out to client so that they see Loading, please wait....
279
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
280
ob_implicit_flush(1);
281
282 20b9b335 Scott Ullrich
// Resolve hostnames and replace Z_ with "".  The intention
283
// is to sort the list by hostnames, alpha and then the non
284
// resolvable addresses will appear last in the list.
285 dd4bded7 Evgeny Yurchenko
$dnsavailable=1;
286
$dns = trim(_getHostName("", "8.8.8.8")); 
287
if ($dns == ""){
288
	$dns = trim(_getHostName("", "8.8.4.4")); 
289
	if ($dns == "") $dnsavailable =0;
290
}
291
292 4a993c8f Scott Ullrich
foreach ($data as &$entry) {
293 dd4bded7 Evgeny Yurchenko
	if ($dnsavailable){
294
		$dns = trim(_getHostName($entry['mac'], $entry['ip']));
295
	}else
296
		$dns="";
297 4a993c8f Scott Ullrich
	if(trim($dns))
298
		$entry['dnsresolve'] = "$dns";
299 f8ec8de4 Renato Botelho
	else
300 4a993c8f Scott Ullrich
		$entry['dnsresolve'] = "Z_ ";
301
}
302 20b9b335 Scott Ullrich
303
// Sort the data alpha first
304 4a993c8f Scott Ullrich
$data = msort($data, "dnsresolve");
305
306 57f2840e Evgeny
// Load MAC-Manufacturer table
307
$mac_man = load_mac_manufacturer_table();
308 4a993c8f Scott Ullrich
?>
309 293ceb87 Colin Fleming
<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="diag arp">
310 20b9b335 Scott Ullrich
	<tr>
311
		<td>
312 293ceb87 Colin Fleming
			<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0" summary="tabcont">
313 20b9b335 Scott Ullrich
				<tr>
314 f8ec8de4 Renato Botelho
					<td class="listhdrr"><?= gettext("IP address"); ?></td>
315
					<td class="listhdrr"><?= gettext("MAC address"); ?></td>
316
					<td class="listhdrr"><?= gettext("Hostname"); ?></td>
317
					<td class="listhdr"><?= gettext("Interface"); ?></td>
318 20b9b335 Scott Ullrich
					<td class="list"></td>
319
				</tr>
320
				<?php foreach ($data as $entry): ?>
321
					<tr>
322
						<td class="listlr"><?=$entry['ip'];?></td>
323 57f2840e Evgeny
						<td class="listr">
324
						<?php
325 34121b0c smos
						$mac=trim($entry['mac']);
326 57f2840e Evgeny
						$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]);
327 701989fb jim-p
						print $mac;
328 8cd558b6 ayvis
						if(isset($mac_man[$mac_hi])){ print "<br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>"; }
329 57f2840e Evgeny
						?>
330 34121b0c smos
						</td>
331 20b9b335 Scott Ullrich
						<td class="listr">
332
							<?php
333 34121b0c smos
							echo trim(str_replace("Z_ ", "", $entry['dnsresolve']));
334 20b9b335 Scott Ullrich
							?>
335
						</td>
336
						<td class="listr"><?=$hwif[$entry['interface']];?></td>
337
					</tr>
338
				<?php endforeach; ?>
339
			</table>
340
		</td>
341
	</tr>
342 64620f90 jim-p
	<tr>
343 8cd558b6 ayvis
		<td><br /><?= gettext("NOTE: Local IPv6 peers use") ?> <a href="diag_ndp.php"><?= gettext("NDP") ?></a> <?= gettext("instead of ARP") ?>.</td>
344 64620f90 jim-p
	</tr>
345 93e1b16c Scott Ullrich
</table>
346
347
<?php include("fend.inc"); ?>
348 4a993c8f Scott Ullrich
349
<script type="text/javascript">
350 293ceb87 Colin Fleming
//<![CDATA[
351 ebfc87d6 Vinicius Coque
	jQuery('#loading').html('');
352 293ceb87 Colin Fleming
//]]>
353 4a993c8f Scott Ullrich
</script>
354 293ceb87 Colin Fleming
</body>
355
</html>