Project

General

Profile

Download (11 KB) Statistics
| Branch: | Tag: | Revision:
1 93e1b16c Scott Ullrich
<?php
2
/*
3 aaec5634 Renato Botelho
 * diag_arp.php
4 9da2cf1c Stephen Beaver
 *
5 aaec5634 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 2a2396a6 Renato Botelho
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7 aaec5634 Renato Botelho
 * All rights reserved.
8 fd9ebcd5 Stephen Beaver
 *
9 aaec5634 Renato Botelho
 * originally based on m0n0wall (http://m0n0.ch/wall)
10
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
 * All rights reserved.
12 fd9ebcd5 Stephen Beaver
 *
13 aaec5634 Renato Botelho
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15 fd9ebcd5 Stephen Beaver
 *
16 aaec5634 Renato Botelho
 * 1. Redistributions of source code must retain the above copyright notice,
17
 *    this list of conditions and the following disclaimer.
18 fd9ebcd5 Stephen Beaver
 *
19 aaec5634 Renato Botelho
 * 2. Redistributions in binary form must reproduce the above copyright
20
 *    notice, this list of conditions and the following disclaimer in
21
 *    the documentation and/or other materials provided with the
22
 *    distribution.
23 fd9ebcd5 Stephen Beaver
 *
24 aaec5634 Renato Botelho
 * 3. All advertising materials mentioning features or use of this software
25
 *    must display the following acknowledgment:
26
 *    "This product includes software developed by the pfSense Project
27
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
28 fd9ebcd5 Stephen Beaver
 *
29 aaec5634 Renato Botelho
 * 4. The names "pfSense" and "pfSense Project" must not be used to
30
 *    endorse or promote products derived from this software without
31
 *    prior written permission. For written permission, please contact
32
 *    coreteam@pfsense.org.
33 fd9ebcd5 Stephen Beaver
 *
34 aaec5634 Renato Botelho
 * 5. Products derived from this software may not be called "pfSense"
35
 *    nor may "pfSense" appear in their names without prior written
36
 *    permission of the Electric Sheep Fencing, LLC.
37 fd9ebcd5 Stephen Beaver
 *
38 aaec5634 Renato Botelho
 * 6. Redistributions of any form whatsoever must retain the following
39
 *    acknowledgment:
40 0da0d43e Phil Davis
 *
41 aaec5634 Renato Botelho
 * "This product includes software developed by the pfSense Project
42
 * for use in the pfSense software distribution (http://www.pfsense.org/).
43 fd9ebcd5 Stephen Beaver
 *
44 aaec5634 Renato Botelho
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
45
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
48
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
 * OF THE POSSIBILITY OF SUCH DAMAGE.
56 fd9ebcd5 Stephen Beaver
 */
57 93e1b16c Scott Ullrich
58 6b07c15a Matthew Grooms
##|+PRIV
59
##|*IDENT=page-diagnostics-arptable
60 5230f468 jim-p
##|*NAME=Diagnostics: ARP Table
61 6b07c15a Matthew Grooms
##|*DESCR=Allow access to the 'Diagnostics: ARP Table' page.
62
##|*MATCH=diag_arp.php*
63
##|-PRIV
64
65 868ba36d Scott Ullrich
@ini_set('zlib.output_compression', 0);
66
@ini_set('implicit_flush', 1);
67 6b07c15a Matthew Grooms
68 aceaf18c Phil Davis
require_once("guiconfig.inc");
69 6090e85b Bill Marquette
70 17e3a05a stilez
// delete arp entry
71
if (isset($_GET['deleteentry'])) {
72
	$ip = $_GET['deleteentry'];
73
	if (is_ipaddrv4($ip)) {
74
		$ret = mwexec("arp -d " . $_GET['deleteentry'], true);
75
	} else {
76
		$ret = 1;
77
	}
78
	if ($ret) {
79
		$savemsg = sprintf(gettext("%s is not a valid IPv4 address or could not be deleted."), $ip);
80
		$savemsgtype = 'alert-warning';
81
	} else {
82
		$savemsg = sprintf(gettext("The ARP cache entry for %s has been deleted."), $ip);
83
		$savemsgtype = 'success';
84
	}
85
}
86
87 fc259334 Seth Mos
function leasecmp($a, $b) {
88
	return strcmp($a[$_GET['order']], $b[$_GET['order']]);
89
}
90 93e1b16c Scott Ullrich
91 fc259334 Seth Mos
function adjust_gmt($dt) {
92
	$ts = strtotime($dt . " GMT");
93
	return strftime("%Y/%m/%d %H:%M:%S", $ts);
94
}
95 93e1b16c Scott Ullrich
96 fc259334 Seth Mos
function remove_duplicate($array, $field) {
97 5f601060 Phil Davis
	foreach ($array as $sub) {
98 20b9b335 Scott Ullrich
		$cmp[] = $sub[$field];
99 5f601060 Phil Davis
	}
100 fc259334 Seth Mos
	$unique = array_unique($cmp);
101 5f601060 Phil Davis
	foreach ($unique as $k => $rien) {
102 fc259334 Seth Mos
		$new[] = $array[$k];
103 5f601060 Phil Davis
	}
104 fc259334 Seth Mos
	return $new;
105
}
106 93e1b16c Scott Ullrich
107 20b9b335 Scott Ullrich
// Define path to AWK
108 fc259334 Seth Mos
$awk = "/usr/bin/awk";
109 20b9b335 Scott Ullrich
110
// Read in leases file
111
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
112
113 fc259334 Seth Mos
/* this pattern sticks comments into a single array item */
114
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
115 20b9b335 Scott Ullrich
116 fc259334 Seth Mos
/* We then split the leases file by } */
117
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
118 93e1b16c Scott Ullrich
119 5f601060 Phil Davis
/* stuff the leases file in a proper format into an array by line */
120 fc259334 Seth Mos
exec("cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
121
$leases_count = count($leases_content);
122
123
$pools = array();
124
$leases = array();
125
$i = 0;
126
$l = 0;
127
$p = 0;
128
// Put everything together again
129 5f601060 Phil Davis
while ($i < $leases_count) {
130 b45630bf jim-p
	/* split the line by space */
131
	$data = explode(" ", $leases_content[$i]);
132
	/* walk the fields */
133
	$f = 0;
134
	$fcount = count($data);
135
	/* with less then 20 fields there is nothing useful */
136 5f601060 Phil Davis
	if ($fcount < 20) {
137 b45630bf jim-p
		$i++;
138
		continue;
139
	}
140 5f601060 Phil Davis
	while ($f < $fcount) {
141
		switch ($data[$f]) {
142 b45630bf jim-p
			case "failover":
143
				$pools[$p]['name'] = $data[$f+2];
144
				$pools[$p]['mystate'] = $data[$f+7];
145
				$pools[$p]['peerstate'] = $data[$f+14];
146
				$pools[$p]['mydate'] = $data[$f+10];
147
				$pools[$p]['mydate'] .= " " . $data[$f+11];
148
				$pools[$p]['peerdate'] = $data[$f+17];
149
				$pools[$p]['peerdate'] .= " " . $data[$f+18];
150
				$p++;
151
				$i++;
152
				continue 3;
153
			case "lease":
154
				$leases[$l]['ip'] = $data[$f+1];
155
				$leases[$l]['type'] = "dynamic";
156
				$f = $f+2;
157
				break;
158
			case "starts":
159
				$leases[$l]['start'] = $data[$f+2];
160
				$leases[$l]['start'] .= " " . $data[$f+3];
161
				$f = $f+3;
162
				break;
163
			case "ends":
164
				$leases[$l]['end'] = $data[$f+2];
165
				$leases[$l]['end'] .= " " . $data[$f+3];
166
				$f = $f+3;
167
				break;
168
			case "tstp":
169
				$f = $f+3;
170
				break;
171
			case "tsfp":
172
				$f = $f+3;
173
				break;
174
			case "atsfp":
175
				$f = $f+3;
176
				break;
177
			case "cltt":
178
				$f = $f+3;
179
				break;
180
			case "binding":
181 699737d9 Phil Davis
				switch ($data[$f+2]) {
182 b45630bf jim-p
					case "active":
183
						$leases[$l]['act'] = "active";
184
						break;
185
					case "free":
186
						$leases[$l]['act'] = "expired";
187
						$leases[$l]['online'] = "offline";
188
						break;
189
					case "backup":
190
						$leases[$l]['act'] = "reserved";
191
						$leases[$l]['online'] = "offline";
192
						break;
193
				}
194
				$f = $f+1;
195
				break;
196
			case "next":
197
				/* skip the next binding statement */
198
				$f = $f+3;
199
				break;
200 f1273b82 jim-p
			case "rewind":
201
				/* skip the rewind binding statement */
202
				$f = $f+3;
203
				break;
204 b45630bf jim-p
			case "hardware":
205
				$leases[$l]['mac'] = $data[$f+2];
206
				/* check if it's online and the lease is active */
207 5f601060 Phil Davis
				if ($leases[$l]['act'] == "active") {
208 b45630bf jim-p
					$online = exec("/usr/sbin/arp -an |/usr/bin/awk '/{$leases[$l]['ip']}/ {print}'|wc -l");
209
					if ($online == 1) {
210
						$leases[$l]['online'] = 'online';
211
					} else {
212
						$leases[$l]['online'] = 'offline';
213
					}
214
				}
215
				$f = $f+2;
216
				break;
217
			case "client-hostname":
218 5f601060 Phil Davis
				if ($data[$f+1] <> "") {
219 699737d9 Phil Davis
					$leases[$l]['hostname'] = preg_replace('/"/', '', $data[$f+1]);
220 b45630bf jim-p
				} else {
221
					$hostname = gethostbyaddr($leases[$l]['ip']);
222 5f601060 Phil Davis
					if ($hostname <> "") {
223 b45630bf jim-p
						$leases[$l]['hostname'] = $hostname;
224
					}
225
				}
226
				$f = $f+1;
227
				break;
228
			case "uid":
229
				$f = $f+1;
230
				break;
231
		}
232
		$f++;
233
	}
234
	$l++;
235
	$i++;
236 fc259334 Seth Mos
}
237
238
/* remove duplicate items by mac address */
239 5f601060 Phil Davis
if (count($leases) > 0) {
240 699737d9 Phil Davis
	$leases = remove_duplicate($leases, "ip");
241 fc259334 Seth Mos
}
242
243 5f601060 Phil Davis
if (count($pools) > 0) {
244 699737d9 Phil Davis
	$pools = remove_duplicate($pools, "name");
245 b45630bf jim-p
	asort($pools);
246 fc259334 Seth Mos
}
247
248
// Put this in an easy to use form
249
$dhcpmac = array();
250
$dhcpip = array();
251 f8ec8de4 Renato Botelho
252 fc259334 Seth Mos
foreach ($leases as $value) {
253 f8ec8de4 Renato Botelho
	$dhcpmac[$value['mac']] = $value['hostname'];
254
	$dhcpip[$value['ip']] = $value['hostname'];
255 93e1b16c Scott Ullrich
}
256
257 699737d9 Phil Davis
exec("/usr/sbin/arp -an", $rawdata);
258 93e1b16c Scott Ullrich
259 f8ec8de4 Renato Botelho
$i = 0;
260 cbe3ea96 Ermal Luçi
261
/* if list */
262
$ifdescrs = get_configured_interface_with_descr();
263 93e1b16c Scott Ullrich
264 e7237dd0 jim-p
foreach ($ifdescrs as $key => $interface) {
265
	$thisif = convert_friendly_interface_to_real_interface_name($key);
266 5f601060 Phil Davis
	if (!empty($thisif)) {
267 e7237dd0 jim-p
		$hwif[$thisif] = $interface;
268 5f601060 Phil Davis
	}
269 93e1b16c Scott Ullrich
}
270
271
$data = array();
272
foreach ($rawdata as $line) {
273 699737d9 Phil Davis
	$elements = explode(' ', $line);
274 f8ec8de4 Renato Botelho
275 93e1b16c Scott Ullrich
	if ($elements[3] != "(incomplete)") {
276
		$arpent = array();
277 699737d9 Phil Davis
		$arpent['ip'] = trim(str_replace(array('(', ')'), '', $elements[1]));
278 93e1b16c Scott Ullrich
		$arpent['mac'] = trim($elements[3]);
279
		$arpent['interface'] = trim($elements[5]);
280
		$data[] = $arpent;
281
	}
282
}
283
284 699737d9 Phil Davis
function _getHostName($mac, $ip) {
285 93e1b16c Scott Ullrich
	global $dhcpmac, $dhcpip;
286 f8ec8de4 Renato Botelho
287 5f601060 Phil Davis
	if ($dhcpmac[$mac]) {
288 93e1b16c Scott Ullrich
		return $dhcpmac[$mac];
289 5f601060 Phil Davis
	} else if ($dhcpip[$ip]) {
290 93e1b16c Scott Ullrich
		return $dhcpip[$ip];
291 5f601060 Phil Davis
	} else {
292 d31ca336 Renato Botelho
		exec("host -W 1 " . escapeshellarg($ip), $output);
293 699737d9 Phil Davis
		if (preg_match('/.*pointer ([A-Za-z_0-9.-]+)\..*/', $output[0], $matches)) {
294 5f601060 Phil Davis
			if ($matches[1] <> $ip) {
295 7d5b007c Sjon Hortensius
				return $matches[1];
296 5f601060 Phil Davis
			}
297 dd4bded7 Evgeny Yurchenko
		}
298
	}
299
	return "";
300 93e1b16c Scott Ullrich
}
301
302 699737d9 Phil Davis
$pgtitle = array(gettext("Diagnostics"), gettext("ARP Table"));
303 fc259334 Seth Mos
include("head.inc");
304 20b9b335 Scott Ullrich
305 17e3a05a stilez
// Handle save msg if defined
306
if ($savemsg) {
307
	print_info_box(htmlentities($savemsg), $savemsgtype);
308
}
309 93e1b16c Scott Ullrich
?>
310 20b9b335 Scott Ullrich
311 a4af095c Renato Botelho
<!-- On modern hardware the table will load so fast you may never see this! -->
312 4a993c8f Scott Ullrich
<div id="loading">
313 a4af095c Renato Botelho
	<?= gettext(" Loading, please wait...")?>
314 4a993c8f Scott Ullrich
</div>
315
316
<?php
317
318 868ba36d Scott Ullrich
// Flush buffers out to client so that they see Loading, please wait....
319 5f601060 Phil Davis
for ($i = 0; $i < ob_get_level(); $i++) {
320
	ob_end_flush();
321
}
322 608947a8 Stephen Beaver
323 868ba36d Scott Ullrich
ob_implicit_flush(1);
324
325 20b9b335 Scott Ullrich
// Resolve hostnames and replace Z_ with "".  The intention
326
// is to sort the list by hostnames, alpha and then the non
327
// resolvable addresses will appear last in the list.
328 dd4bded7 Evgeny Yurchenko
$dnsavailable=1;
329 7d5b007c Sjon Hortensius
$dns = trim(_getHostName("", "8.8.8.8"));
330 5f601060 Phil Davis
if ($dns == "") {
331 7d5b007c Sjon Hortensius
	$dns = trim(_getHostName("", "8.8.4.4"));
332 5f601060 Phil Davis
	if ($dns == "") {
333
		$dnsavailable = 0;
334
	}
335 dd4bded7 Evgeny Yurchenko
}
336
337 4a993c8f Scott Ullrich
foreach ($data as &$entry) {
338 5f601060 Phil Davis
	if ($dnsavailable) {
339 dd4bded7 Evgeny Yurchenko
		$dns = trim(_getHostName($entry['mac'], $entry['ip']));
340 5f601060 Phil Davis
	} else {
341 dd4bded7 Evgeny Yurchenko
		$dns="";
342 5f601060 Phil Davis
	}
343
	if (trim($dns)) {
344 4a993c8f Scott Ullrich
		$entry['dnsresolve'] = "$dns";
345 5f601060 Phil Davis
	} else {
346 4a993c8f Scott Ullrich
		$entry['dnsresolve'] = "Z_ ";
347 5f601060 Phil Davis
	}
348 4a993c8f Scott Ullrich
}
349 8ed2d200 NewEraCracker
unset($entry);
350 20b9b335 Scott Ullrich
351
// Sort the data alpha first
352 4a993c8f Scott Ullrich
$data = msort($data, "dnsresolve");
353
354 57f2840e Evgeny
// Load MAC-Manufacturer table
355
$mac_man = load_mac_manufacturer_table();
356 4a993c8f Scott Ullrich
?>
357 ac950976 Colin Fleming
<div class="panel panel-default">
358
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('ARP Table')?></h2></div>
359
	<div class="panel-body">
360
361 89f64f0f Sander van Leeuwen
<div class="table-responsive">
362 608947a8 Stephen Beaver
	<table class="sortable-theme-bootstrap table table-striped table-hover" data-sortable>
363 89f64f0f Sander van Leeuwen
		<thead>
364
			<tr>
365
				<th><?= gettext("Interface")?></th>
366
				<th><?= gettext("IP address")?></th>
367
				<th><?= gettext("MAC address")?></th>
368
				<th><?= gettext("Hostname")?></th>
369 17e3a05a stilez
				<th data-sortable="false"><?=gettext("Actions")?></th>
370 89f64f0f Sander van Leeuwen
			</tr>
371
		</thead>
372
		<tbody>
373 947141fd Phil Davis
374 82afb104 Stephen Beaver
<?php
375
		foreach ($data as $entry): ?>
376 89f64f0f Sander van Leeuwen
			<tr>
377
				<td><?=$hwif[$entry['interface']]?></td>
378
				<td><?=$entry['ip']?></td>
379
				<td>
380
					<?=trim($entry['mac'])?>
381
				<?php
382
					$mac = trim($entry['mac']);
383
					$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]);
384
385 cba48c64 Colin Fleming
					if (isset($mac_man[$mac_hi])) {
386 89f64f0f Sander van Leeuwen
						print '<small>('. $mac_man[$mac_hi] .')</small>';
387 cba48c64 Colin Fleming
					}
388 89f64f0f Sander van Leeuwen
	?>
389
				</td>
390
				<td><?=trim(str_replace("Z_ ", "", $entry['dnsresolve']))?></td>
391 17e3a05a stilez
				<td>
392
					<a class="fa fa-trash" title="<?=gettext('Delete arp cache entry')?>"	href="diag_arp.php?deleteentry=<?=$entry['ip']?>"></a>
393
				</td>
394 89f64f0f Sander van Leeuwen
			</tr>
395
		<?php endforeach?>
396
		</tbody>
397
	</table>
398
</div>
399
400 ac950976 Colin Fleming
	</div>
401
</div>
402
403 cba48c64 Colin Fleming
<script type="text/javascript">
404 293ceb87 Colin Fleming
//<![CDATA[
405 a4af095c Renato Botelho
// Clear the "loading" div once the page has loaded"
406 947141fd Phil Davis
events.push(function() {
407 a4af095c Renato Botelho
	$('#loading').empty();
408
});
409 0da0d43e Phil Davis
//]]>
410 4a993c8f Scott Ullrich
</script>
411 a4af095c Renato Botelho
412 c40962e9 Phil Davis
<div class="infoblock blockopen">
413 0da0d43e Phil Davis
<?php
414 c6d73876 NOYB
print_info_box(gettext("Local IPv6 peers use ") . '<a href="diag_ndp.php">' . gettext("NDP") . '</a>' . gettext(" instead of ARP."), 'info', false);
415 c40962e9 Phil Davis
?>
416
</div>
417 93e1b16c Scott Ullrich
418 c40962e9 Phil Davis
<?php
419
include("foot.inc");
420
?>