Project

General

Profile

Download (9.7 KB) Statistics
| Branch: | Tag: | Revision:
1 93e1b16c Scott Ullrich
<?php
2
/*
3 c5d81585 Renato Botelho
 * diag_arp.php
4 9da2cf1c Stephen Beaver
 *
5 c5d81585 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 0284d79e jim-p
 * Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate)
9 c5d81585 Renato Botelho
 * All rights reserved.
10 fd9ebcd5 Stephen Beaver
 *
11 c5d81585 Renato Botelho
 * originally based on m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14 fd9ebcd5 Stephen Beaver
 *
15 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18 fd9ebcd5 Stephen Beaver
 *
19 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
20 fd9ebcd5 Stephen Beaver
 *
21 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26 fd9ebcd5 Stephen Beaver
 */
27 93e1b16c Scott Ullrich
28 6b07c15a Matthew Grooms
##|+PRIV
29
##|*IDENT=page-diagnostics-arptable
30 5230f468 jim-p
##|*NAME=Diagnostics: ARP Table
31 6b07c15a Matthew Grooms
##|*DESCR=Allow access to the 'Diagnostics: ARP Table' page.
32
##|*MATCH=diag_arp.php*
33
##|-PRIV
34
35 868ba36d Scott Ullrich
@ini_set('zlib.output_compression', 0);
36
@ini_set('implicit_flush', 1);
37 6b07c15a Matthew Grooms
38 c81ef6e2 Phil Davis
require_once("guiconfig.inc");
39 6090e85b Bill Marquette
40 6ea0d41e stilez
// delete arp entry
41 7f4268b6 Steve Beaver
if (isset($_POST['deleteentry'])) {
42
	$ip = $_POST['deleteentry'];
43 6ea0d41e stilez
	if (is_ipaddrv4($ip)) {
44 7f4268b6 Steve Beaver
		$ret = mwexec("arp -d " . $_POST['deleteentry'], true);
45 6ea0d41e stilez
	} else {
46
		$ret = 1;
47
	}
48
	if ($ret) {
49
		$savemsg = sprintf(gettext("%s is not a valid IPv4 address or could not be deleted."), $ip);
50
		$savemsgtype = 'alert-warning';
51
	} else {
52
		$savemsg = sprintf(gettext("The ARP cache entry for %s has been deleted."), $ip);
53
		$savemsgtype = 'success';
54
	}
55
}
56
57 55342b60 Renato Botelho
$leases = system_get_dhcpleases();
58 fc259334 Seth Mos
59
// Put this in an easy to use form
60
$dhcpmac = array();
61
$dhcpip = array();
62 f8ec8de4 Renato Botelho
63 55342b60 Renato Botelho
foreach ($leases['lease'] as $value) {
64 f8ec8de4 Renato Botelho
	$dhcpmac[$value['mac']] = $value['hostname'];
65
	$dhcpip[$value['ip']] = $value['hostname'];
66 93e1b16c Scott Ullrich
}
67
68 6624a6be Renato Botelho
$arp_table = system_get_arp_table();
69 93e1b16c Scott Ullrich
70 f8ec8de4 Renato Botelho
$i = 0;
71 cbe3ea96 Ermal Luçi
72
/* if list */
73
$ifdescrs = get_configured_interface_with_descr();
74 93e1b16c Scott Ullrich
75 e7237dd0 jim-p
foreach ($ifdescrs as $key => $interface) {
76
	$thisif = convert_friendly_interface_to_real_interface_name($key);
77 5f601060 Phil Davis
	if (!empty($thisif)) {
78 e7237dd0 jim-p
		$hwif[$thisif] = $interface;
79 5f601060 Phil Davis
	}
80 93e1b16c Scott Ullrich
}
81
82 699737d9 Phil Davis
function _getHostName($mac, $ip) {
83 93e1b16c Scott Ullrich
	global $dhcpmac, $dhcpip;
84 f8ec8de4 Renato Botelho
85 5f601060 Phil Davis
	if ($dhcpmac[$mac]) {
86 93e1b16c Scott Ullrich
		return $dhcpmac[$mac];
87 5f601060 Phil Davis
	} else if ($dhcpip[$ip]) {
88 93e1b16c Scott Ullrich
		return $dhcpip[$ip];
89 5f601060 Phil Davis
	} else {
90 d31ca336 Renato Botelho
		exec("host -W 1 " . escapeshellarg($ip), $output);
91 699737d9 Phil Davis
		if (preg_match('/.*pointer ([A-Za-z_0-9.-]+)\..*/', $output[0], $matches)) {
92 5f601060 Phil Davis
			if ($matches[1] <> $ip) {
93 7d5b007c Sjon Hortensius
				return $matches[1];
94 5f601060 Phil Davis
			}
95 dd4bded7 Evgeny Yurchenko
		}
96
	}
97
	return "";
98 93e1b16c Scott Ullrich
}
99
100 699737d9 Phil Davis
$pgtitle = array(gettext("Diagnostics"), gettext("ARP Table"));
101 fc259334 Seth Mos
include("head.inc");
102 20b9b335 Scott Ullrich
103 6ea0d41e stilez
// Handle save msg if defined
104
if ($savemsg) {
105
	print_info_box(htmlentities($savemsg), $savemsgtype);
106
}
107 93e1b16c Scott Ullrich
?>
108 20b9b335 Scott Ullrich
109 a4af095c Renato Botelho
<!-- On modern hardware the table will load so fast you may never see this! -->
110 4a993c8f Scott Ullrich
<div id="loading">
111 a4af095c Renato Botelho
	<?= gettext(" Loading, please wait...")?>
112 4a993c8f Scott Ullrich
</div>
113
114
<?php
115
116 868ba36d Scott Ullrich
// Flush buffers out to client so that they see Loading, please wait....
117 5f601060 Phil Davis
for ($i = 0; $i < ob_get_level(); $i++) {
118
	ob_end_flush();
119
}
120 608947a8 Stephen Beaver
121 868ba36d Scott Ullrich
ob_implicit_flush(1);
122
123 20b9b335 Scott Ullrich
// Resolve hostnames and replace Z_ with "".  The intention
124
// is to sort the list by hostnames, alpha and then the non
125
// resolvable addresses will appear last in the list.
126 dd4bded7 Evgeny Yurchenko
$dnsavailable=1;
127 7d5b007c Sjon Hortensius
$dns = trim(_getHostName("", "8.8.8.8"));
128 5f601060 Phil Davis
if ($dns == "") {
129 7d5b007c Sjon Hortensius
	$dns = trim(_getHostName("", "8.8.4.4"));
130 5f601060 Phil Davis
	if ($dns == "") {
131
		$dnsavailable = 0;
132
	}
133 dd4bded7 Evgeny Yurchenko
}
134
135 6624a6be Renato Botelho
foreach ($arp_table as &$entry) {
136
	if ($dnsavailable && !empty($entry['mac-address'])) {
137
		$dns = trim(_getHostName($entry['mac-address'],
138
		    $entry['ip-address']));
139 5f601060 Phil Davis
	} else {
140 dd4bded7 Evgeny Yurchenko
		$dns="";
141 5f601060 Phil Davis
	}
142
	if (trim($dns)) {
143 4a993c8f Scott Ullrich
		$entry['dnsresolve'] = "$dns";
144 5f601060 Phil Davis
	} else {
145 4a993c8f Scott Ullrich
		$entry['dnsresolve'] = "Z_ ";
146 5f601060 Phil Davis
	}
147 4a993c8f Scott Ullrich
}
148 8ed2d200 NewEraCracker
unset($entry);
149 20b9b335 Scott Ullrich
150
// Sort the data alpha first
151 6624a6be Renato Botelho
$arp_table = msort($arp_table, "dnsresolve");
152 4a993c8f Scott Ullrich
153 57f2840e Evgeny
// Load MAC-Manufacturer table
154
$mac_man = load_mac_manufacturer_table();
155 4a993c8f Scott Ullrich
?>
156 9297ad65 jim-p
<div class="panel panel-default" id="search-panel">
157
	<div class="panel-heading">
158
		<h2 class="panel-title">
159
			<?=gettext('Search')?>
160
			<span class="widget-heading-icon pull-right">
161
				<a data-toggle="collapse" href="#search-panel_panel-body">
162
					<i class="fa fa-plus-circle"></i>
163
				</a>
164
			</span>
165
		</h2>
166
	</div>
167
	<div id="search-panel_panel-body" class="panel-body collapse in">
168
		<div class="form-group">
169
			<label class="col-sm-2 control-label">
170
				<?=gettext("Search term")?>
171
			</label>
172
			<div class="col-sm-5"><input class="form-control" name="searchstr" id="searchstr" type="text"/></div>
173
			<div class="col-sm-2">
174
				<select id="where" class="form-control">
175
					<option value="0"><?=gettext("Interface")?></option>
176
					<option value="1"><?=gettext("IP Address")?></option>
177
					<option value="2"><?=gettext("MAC Address")?></option>
178
					<option value="3"><?=gettext("Hostname")?></option>
179
					<option value="4"><?=gettext("Status")?></option>
180
					<option value="5"><?=gettext("Link Type")?></option>
181
					<option value="6" selected><?=gettext("All")?></option>
182
				</select>
183
			</div>
184
			<div class="col-sm-3">
185
				<a id="btnsearch" title="<?=gettext("Search")?>" class="btn btn-primary btn-sm"><i class="fa fa-search icon-embed-btn"></i><?=gettext("Search")?></a>
186
				<a id="btnclear" title="<?=gettext("Clear")?>" class="btn btn-info btn-sm"><i class="fa fa-undo icon-embed-btn"></i><?=gettext("Clear")?></a>
187
			</div>
188
			<div class="col-sm-10 col-sm-offset-2">
189
				<span class="help-block"><?=gettext('Enter a search string or *nix regular expression to filter entries.')?></span>
190
			</div>
191
		</div>
192
	</div>
193
</div>
194
195 ac950976 Colin Fleming
<div class="panel panel-default">
196
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('ARP Table')?></h2></div>
197
	<div class="panel-body">
198
199 89f64f0f Sander van Leeuwen
<div class="table-responsive">
200 608947a8 Stephen Beaver
	<table class="sortable-theme-bootstrap table table-striped table-hover" data-sortable>
201 89f64f0f Sander van Leeuwen
		<thead>
202
			<tr>
203
				<th><?= gettext("Interface")?></th>
204
				<th><?= gettext("IP address")?></th>
205
				<th><?= gettext("MAC address")?></th>
206
				<th><?= gettext("Hostname")?></th>
207 9e3cb876 jim-p
				<th><?= gettext("Status")?></th>
208
				<th><?= gettext("Link Type")?></th>
209 6ea0d41e stilez
				<th data-sortable="false"><?=gettext("Actions")?></th>
210 89f64f0f Sander van Leeuwen
			</tr>
211
		</thead>
212
		<tbody>
213 947141fd Phil Davis
214 82afb104 Stephen Beaver
<?php
215 6624a6be Renato Botelho
		foreach ($arp_table as $entry): ?>
216 89f64f0f Sander van Leeuwen
			<tr>
217
				<td><?=$hwif[$entry['interface']]?></td>
218 6624a6be Renato Botelho
				<td><?=$entry['ip-address']?></td>
219
<?php
220
				if (empty($entry['mac-address'])) {
221
					$mac = '(' . gettext("Incomplete") .')';
222
					print "<td>{$mac}</td>";
223
				} else {
224
					$mac = trim($entry['mac-address']);
225
					print "<td>{$mac}";
226
					$mac_hi = strtoupper($mac[0] . $mac[1] .
227
					    $mac[3] . $mac[4] . $mac[6] .
228
					    $mac[7]);
229 89f64f0f Sander van Leeuwen
230 cba48c64 Colin Fleming
					if (isset($mac_man[$mac_hi])) {
231 4a26ba22 jim-p
						print ' <small>('.
232 6624a6be Renato Botelho
						    $mac_man[$mac_hi] .
233
						    ')</small>';
234 cba48c64 Colin Fleming
					}
235 6624a6be Renato Botelho
				}
236
237
				$status = '';
238
				if (!empty($entry['expires'])) {
239
					$status = sprintf(gettext(
240
					    "Expires in %d seconds"),
241
					    $entry['expires']);
242
				} else if (!empty($entry['permanent'])) {
243
					$status = gettext("Permanent");
244
				}
245
?>
246 89f64f0f Sander van Leeuwen
				</td>
247
				<td><?=trim(str_replace("Z_ ", "", $entry['dnsresolve']))?></td>
248 6624a6be Renato Botelho
				<td><?=ucfirst($status)?></td>
249
				<td><?=$entry['type']?></td>
250 6ea0d41e stilez
				<td>
251 6624a6be Renato Botelho
					<a class="fa fa-trash" title="<?=gettext('Delete arp cache entry')?>"	href="diag_arp.php?deleteentry=<?=$entry['ip-address']?>" usepost></a>
252 6ea0d41e stilez
				</td>
253 89f64f0f Sander van Leeuwen
			</tr>
254 6624a6be Renato Botelho
<?php
255
		endforeach
256
?>
257 89f64f0f Sander van Leeuwen
		</tbody>
258
	</table>
259
</div>
260
261 ac950976 Colin Fleming
	</div>
262
</div>
263
264 cba48c64 Colin Fleming
<script type="text/javascript">
265 293ceb87 Colin Fleming
//<![CDATA[
266 a4af095c Renato Botelho
// Clear the "loading" div once the page has loaded"
267 947141fd Phil Davis
events.push(function() {
268 a4af095c Renato Botelho
	$('#loading').empty();
269 9297ad65 jim-p
270
	// Make these controls plain buttons
271
	$("#btnsearch").prop('type', 'button');
272
	$("#btnclear").prop('type', 'button');
273
274
	// Search for a term in the entry name and/or dn
275
	$("#btnsearch").click(function() {
276
		var searchstr = $('#searchstr').val().toLowerCase();
277
		var table = $("table tbody");
278
		var where = $('#where').val();
279
280
		table.find('tr').each(function (i) {
281
			var $tds = $(this).find('td'),
282
				iface    = $tds.eq(0).text().trim().toLowerCase(),
283
				ipaddr   = $tds.eq(1).text().trim().toLowerCase();
284
				macaddr  = $tds.eq(2).text().trim().toLowerCase();
285
				hostname = $tds.eq(3).text().trim().toLowerCase();
286
				stat     = $tds.eq(4).text().trim().toLowerCase();
287
				linktype = $tds.eq(5).text().trim().toLowerCase();
288
289
			regexp = new RegExp(searchstr);
290
			if (searchstr.length > 0) {
291
				if (!(regexp.test(iface)    && ((where == 0) || (where == 6))) &&
292
				    !(regexp.test(ipaddr)   && ((where == 1) || (where == 6))) &&
293
				    !(regexp.test(macaddr)  && ((where == 2) || (where == 6))) &&
294
				    !(regexp.test(hostname) && ((where == 3) || (where == 6))) &&
295
				    !(regexp.test(stat)     && ((where == 4) || (where == 6))) &&
296
				    !(regexp.test(linktype) && ((where == 5) || (where == 6)))
297
				    ) {
298
					$(this).hide();
299
				} else {
300
					$(this).show();
301
				}
302
			} else {
303
				$(this).show();	// A blank search string shows all
304
			}
305
		});
306
	});
307
308
	// Clear the search term and unhide all rows (that were hidden during a previous search)
309
	$("#btnclear").click(function() {
310
		var table = $("table tbody");
311
312
		$('#searchstr').val("");
313
314
		table.find('tr').each(function (i) {
315
			$(this).show();
316
		});
317
	});
318
319
	// Hitting the enter key will do the same as clicking the search button
320
	$("#searchstr").on("keyup", function (event) {
321
		if (event.keyCode == 13) {
322
			$("#btnsearch").get(0).click();
323
		}
324
	});
325
326 a4af095c Renato Botelho
});
327 0da0d43e Phil Davis
//]]>
328 4a993c8f Scott Ullrich
</script>
329 a4af095c Renato Botelho
330 c40962e9 Phil Davis
<div class="infoblock blockopen">
331 0da0d43e Phil Davis
<?php
332 5db70796 Phil Davis
print_info_box(sprintf(gettext('Local IPv6 peers use %1$sNDP%2$s instead of ARP.'), '<a href="diag_ndp.php">', '</a>') . '<br />' .
333
   '<br />' . gettext('Permanent ARP entries are shown for local interfaces or static ARP entries.') .
334
   '<br />' . gettext('Normal dynamic ARP entries show a countdown timer until they will expire and then be re-checked.') .
335
   '<br />' . gettext('Incomplete ARP entries indicate that the target host has not yet replied to an ARP request.'), 'info', false);
336 c40962e9 Phil Davis
?>
337
</div>
338 93e1b16c Scott Ullrich
339 c40962e9 Phil Davis
<?php
340
include("foot.inc");
341
?>