Project

General

Profile

Download (9.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * diag_ndp.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2021 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2011 Seth Mos <seth.mos@dds.nl>
10
 * All rights reserved.
11
 *
12
 * originally based on m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15
 *
16
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27
 */
28

    
29
##|+PRIV
30
##|*IDENT=page-diagnostics-ndptable
31
##|*NAME=Diagnostics: NDP Table
32
##|*DESCR=Allow access to the 'Diagnostics: NDP Table' page.
33
##|*MATCH=diag_ndp.php*
34
##|-PRIV
35

    
36
@ini_set('zlib.output_compression', 0);
37
@ini_set('implicit_flush', 1);
38
define('NDP_BINARY_PATH', '/usr/sbin/ndp');
39
require_once("guiconfig.inc");
40

    
41
// Delete ndp entry.
42
if (isset($_POST['deleteentry'])) {
43
	$ip = $_POST['deleteentry'];
44
	if (is_ipaddrv6($ip)) {
45
		$commandReturnValue = mwexec(NDP_BINARY_PATH . " -d " . escapeshellarg($ip), true);
46
		$deleteSucceededFlag = ($commandReturnValue == 0);
47
	} else {
48
		$deleteSucceededFlag = false;
49
	}
50

    
51
	$deleteResultMessage = ($deleteSucceededFlag)
52
		? sprintf(gettext("The NDP entry for %s has been deleted."), $ip)
53
		: sprintf(gettext("%s is not a valid IPv6 address or could not be deleted."), $ip);
54
	$deleteResultMessageType = ($deleteSucceededFlag)
55
		? 'success'
56
		: 'alert-warning';
57
} elseif (isset($_POST['clearndptable'])) {
58
	$out = "";
59
	$ret = exec("/usr/sbin/ndp -c", $out, $ndpTableRetVal);
60
	if ($ndpTableRetVal == 0) { 
61
		$deleteResultMessage = gettext("NDP Table has been cleared.");
62
		$deleteResultMessageType = 'success';
63
	} else {
64
		$deleteResultMessage = gettext("Unable to clear NDP Table.");
65
		$deleteResultMessageType = 'alert-warning';
66
	}
67
}
68

    
69
exec(NDP_BINARY_PATH . " -na", $rawdata);
70

    
71
$i = 0;
72

    
73
/* if list */
74
$ifdescrs = get_configured_interface_with_descr();
75

    
76
foreach ($ifdescrs as $key =>$interface) {
77
	$hwif[$config['interfaces'][$key]['if']] = $interface;
78
}
79

    
80
/*
81
 * Key map for each element in $rawdata
82
 * 0 => Neighbor IP
83
 * 1 => Physical address (MAC)
84
 * 2 => Interface
85
 * 3 => Expiration
86
 * 4 => State
87
 * 5 => Flags
88
 */
89
$data = array();
90
array_shift($rawdata);
91
foreach ($rawdata as $line) {
92
	$elements = preg_split('/[ ]+/', $line);
93

    
94
	$ndpent = array();
95
	$ndpent['ipv6'] = trim($elements[0]);
96
	$ndpent['mac'] = trim($elements[1]);
97
	$ndpent['interface'] = trim($elements[2]);
98
	$ndpent['expiration'] = trim($elements[3]);
99
	$data[] = $ndpent;
100
}
101

    
102
/* FIXME: Not ipv6 compatible dns resolving. PHP needs fixing */
103
function _getHostName($mac, $ip) {
104
	if (is_ipaddr($ip)) {
105
		list($ip, $scope) = explode("%", $ip);
106
		if (gethostbyaddr($ip) <> "" and gethostbyaddr($ip) <> $ip) {
107
			return gethostbyaddr($ip);
108
		} else {
109
			return "";
110
		}
111
	}
112
}
113

    
114
// Resolve hostnames and replace Z_ with "".  The intention
115
// is to sort the list by hostnames, alpha and then the non
116
// resolvable addresses will appear last in the list.
117
foreach ($data as &$entry) {
118
	$dns = trim(_getHostName($entry['mac'], $entry['ipv6']));
119
	if (trim($dns)) {
120
		$entry['dnsresolve'] = "$dns";
121
	} else {
122
		$entry['dnsresolve'] = "Z_ ";
123
	}
124
}
125
unset($entry);
126

    
127
// Sort the data alpha first
128
$data = msort($data, "dnsresolve");
129

    
130
// Load MAC-Manufacturer table
131
$mac_man = load_mac_manufacturer_table();
132

    
133
$pgtitle = array(gettext("Diagnostics"), gettext("NDP Table"));
134
include("head.inc");
135

    
136
// Show message if defined.
137
if (isset($deleteResultMessage, $deleteResultMessageType)) {
138
	print_info_box(htmlentities($deleteResultMessage), $deleteResultMessageType);
139
}
140
?>
141

    
142
<div class="panel panel-default" id="search-panel">
143
	<div class="panel-heading">
144
		<h2 class="panel-title">
145
			<?=gettext('Search')?>
146
			<span class="widget-heading-icon pull-right">
147
				<a data-toggle="collapse" href="#search-panel_panel-body">
148
					<i class="fa fa-plus-circle"></i>
149
				</a>
150
			</span>
151
		</h2>
152
	</div>
153
	<div id="search-panel_panel-body" class="panel-body collapse in">
154
		<div class="form-group">
155
			<label class="col-sm-2 control-label">
156
				<?=gettext("Search term")?>
157
			</label>
158
			<div class="col-sm-5"><input class="form-control" name="searchstr" id="searchstr" type="text"/></div>
159
			<div class="col-sm-2">
160
				<select id="where" class="form-control">
161
					<option value="0"><?=gettext("IPv6 Address")?></option>
162
					<option value="1"><?=gettext("MAC Address")?></option>
163
					<option value="2"><?=gettext("Hostname")?></option>
164
					<option value="3"><?=gettext("Interface")?></option>
165
					<option value="4"><?=gettext("Expiration")?></option>
166
					<option value="5" selected><?=gettext("All")?></option>
167
				</select>
168
			</div>
169
			<div class="col-sm-3">
170
				<a id="btnsearch" title="<?=gettext("Search")?>" class="btn btn-primary btn-sm"><i class="fa fa-search icon-embed-btn"></i><?=gettext("Search")?></a>
171
				<a id="btnclear" title="<?=gettext("Clear")?>" class="btn btn-info btn-sm"><i class="fa fa-undo icon-embed-btn"></i><?=gettext("Clear")?></a>
172
			</div>
173
			<div class="col-sm-10 col-sm-offset-2">
174
				<span class="help-block"><?=gettext('Enter a search string or *nix regular expression to filter entries.')?></span>
175
			</div>
176
		</div>
177
	</div>
178
</div>
179

    
180
<div class="panel panel-default">
181
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('NDP Table')?></h2></div>
182
	<div class="panel-body">
183

    
184
<div class="table-responsive">
185
	<table class="table table-striped table-condensed table-hover sortable-theme-bootstrap" data-sortable>
186
		<thead>
187
			<tr>
188
				<th><?=gettext("IPv6 address")?></th>
189
				<th><?=gettext("MAC address")?></th>
190
				<th><?=gettext("Hostname")?></th>
191
				<th><?=gettext("Interface")?></th>
192
				<th><?=gettext("Expiration")?></th>
193
				<th data-sortable="false"><?=gettext("Actions")?></th>
194
			</tr>
195
	</thead>
196
	<tbody>
197
			<?php foreach ($data as $entry): ?>
198
				<tr>
199
					<td><?=$entry['ipv6']?></td>
200
					<td>
201
						<?php
202
						$mac=trim($entry['mac']);
203
						$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]);
204
						?>
205
						<?=$mac?>
206

    
207
						<?php if (isset($mac_man[$mac_hi])):?>
208
							(<?=$mac_man[$mac_hi]?>)
209
						<?php endif; ?>
210

    
211
					</td>
212
					<td>
213
						<?=htmlspecialchars(str_replace("Z_ ", "", $entry['dnsresolve']))?>
214
					</td>
215
					<td>
216
						<?php
217
						if (isset($hwif[$entry['interface']])) {
218
							echo $hwif[$entry['interface']];
219
						} else {
220
							echo $entry['interface'];
221
						}
222
						?>
223
					</td>
224
					<td>
225
						<?=$entry['expiration']?>
226
					</td>
227
					<td>
228
						<a class="fa fa-trash" title="<?=gettext('Delete NDP entry')?>"	href="diag_ndp.php?deleteentry=<?=$entry['ipv6']?>" usepost></a>
229
					</td>
230
				</tr>
231
			<?php endforeach; ?>
232
	</tbody>
233
	</table>
234
</div>
235

    
236
	</div>
237
</div>
238

    
239
<nav class="action-buttons">
240
	<button id="clearndp" class="btn btn-danger no-confirm">
241
		<i class="fa fa-trash icon-embed-btn"></i>
242
		<?=gettext("Clear NDP Table")?>
243
	</button>
244
</nav>
245

    
246
<script type="text/javascript">
247
//<![CDATA[
248
events.push(function() {
249
	// Make these controls plain buttons
250
	$("#btnsearch").prop('type', 'button');
251
	$("#btnclear").prop('type', 'button');
252

    
253
	// Search for a term in the entry name and/or dn
254
	$("#btnsearch").click(function() {
255
		var searchstr = $('#searchstr').val().toLowerCase();
256
		var table = $("table tbody");
257
		var where = $('#where').val();
258

    
259
		table.find('tr').each(function (i) {
260
			var $tds = $(this).find('td'),
261
				ipaddr   = $tds.eq(0).text().trim().toLowerCase();
262
				macaddr  = $tds.eq(1).text().trim().toLowerCase();
263
				hostname = $tds.eq(2).text().trim().toLowerCase();
264
				iface    = $tds.eq(3).text().trim().toLowerCase(),
265
				stat     = $tds.eq(4).text().trim().toLowerCase();
266

    
267
			regexp = new RegExp(searchstr);
268
			if (searchstr.length > 0) {
269
				if (!(regexp.test(ipaddr)   && ((where == 0) || (where == 5))) &&
270
				    !(regexp.test(macaddr)  && ((where == 1) || (where == 5))) &&
271
				    !(regexp.test(hostname) && ((where == 2) || (where == 5))) &&
272
				    !(regexp.test(iface)    && ((where == 3) || (where == 5))) &&
273
				    !(regexp.test(stat)     && ((where == 4) || (where == 5)))
274
				    ) {
275
					$(this).hide();
276
				} else {
277
					$(this).show();
278
				}
279
			} else {
280
				$(this).show();	// A blank search string shows all
281
			}
282
		});
283
	});
284

    
285
	// Clear the search term and unhide all rows (that were hidden during a previous search)
286
	$("#btnclear").click(function() {
287
		var table = $("table tbody");
288

    
289
		$('#searchstr').val("");
290

    
291
		table.find('tr').each(function (i) {
292
			$(this).show();
293
		});
294
	});
295

    
296
	// Hitting the enter key will do the same as clicking the search button
297
	$("#searchstr").on("keyup", function (event) {
298
		if (event.keyCode == 13) {
299
			$("#btnsearch").get(0).click();
300
		}
301
	});
302

    
303
	$('#clearndp').click(function() {
304
		if (confirm("Are you sure you wish to clear NDP table?")) {
305
			postSubmit({clearndptable: 'true'}, 'diag_ndp.php');
306
		}
307
	});
308

    
309
});
310
//]]>
311
</script>
312

    
313
<?php include("foot.inc");
(20-20/227)