Project

General

Profile

Download (9.02 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-2024 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_get_path("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
// Resolve hostnames and replace Z_ with "".  The intention
103
// is to sort the list by hostnames, alpha and then the non
104
// resolvable addresses will appear last in the list.
105
$dnsavailable = get_dnsavailable(AF_INET6);
106
foreach ($data as &$entry) {
107
	$dns="";
108
	if (!empty($entry['ipv6']) && $dnsavailable) {
109
		$dns = resolve_address($entry['ipv6']);
110
	}
111

    
112
	if (trim($dns)) {
113
		$entry['dnsresolve'] = "$dns";
114
	} else {
115
		$entry['dnsresolve'] = "Z_ ";
116
	}
117
}
118
unset($entry);
119

    
120
// Sort the data alpha first
121
$data = msort($data, "dnsresolve");
122

    
123
// Load MAC-Manufacturer table
124
$mac_man = load_mac_manufacturer_table();
125

    
126
$pgtitle = array(gettext("Diagnostics"), gettext("NDP Table"));
127
include("head.inc");
128

    
129
// Show message if defined.
130
if (isset($deleteResultMessage, $deleteResultMessageType)) {
131
	print_info_box(htmlentities($deleteResultMessage), $deleteResultMessageType);
132
}
133
?>
134

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

    
173
<div class="panel panel-default">
174
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('NDP Table')?></h2></div>
175
	<div class="panel-body">
176

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

    
200
						<?php if (isset($mac_man[$mac_hi])):?>
201
							(<?=$mac_man[$mac_hi]?>)
202
						<?php endif; ?>
203

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

    
229
	</div>
230
</div>
231

    
232
<nav class="action-buttons">
233
	<button id="clearndp" class="btn btn-danger no-confirm">
234
		<i class="fa-solid fa-trash-can icon-embed-btn"></i>
235
		<?=gettext("Clear NDP Table")?>
236
	</button>
237
</nav>
238

    
239
<script type="text/javascript">
240
//<![CDATA[
241
events.push(function() {
242
	// Make these controls plain buttons
243
	$("#btnsearch").prop('type', 'button');
244
	$("#btnclear").prop('type', 'button');
245

    
246
	// Search for a term in the entry name and/or dn
247
	$("#btnsearch").click(function() {
248
		var searchstr = $('#searchstr').val().toLowerCase();
249
		var table = $("table tbody");
250
		var where = $('#where').val();
251

    
252
		table.find('tr').each(function (i) {
253
			var $tds = $(this).find('td'),
254
				ipaddr   = $tds.eq(0).text().trim().toLowerCase();
255
				macaddr  = $tds.eq(1).text().trim().toLowerCase();
256
				hostname = $tds.eq(2).text().trim().toLowerCase();
257
				iface    = $tds.eq(3).text().trim().toLowerCase(),
258
				stat     = $tds.eq(4).text().trim().toLowerCase();
259

    
260
			regexp = new RegExp(searchstr);
261
			if (searchstr.length > 0) {
262
				if (!(regexp.test(ipaddr)   && ((where == 0) || (where == 5))) &&
263
				    !(regexp.test(macaddr)  && ((where == 1) || (where == 5))) &&
264
				    !(regexp.test(hostname) && ((where == 2) || (where == 5))) &&
265
				    !(regexp.test(iface)    && ((where == 3) || (where == 5))) &&
266
				    !(regexp.test(stat)     && ((where == 4) || (where == 5)))
267
				    ) {
268
					$(this).hide();
269
				} else {
270
					$(this).show();
271
				}
272
			} else {
273
				$(this).show();	// A blank search string shows all
274
			}
275
		});
276
	});
277

    
278
	// Clear the search term and unhide all rows (that were hidden during a previous search)
279
	$("#btnclear").click(function() {
280
		var table = $("table tbody");
281

    
282
		$('#searchstr').val("");
283

    
284
		$('#where option[value="5"]').prop('selected', true);
285

    
286
		table.find('tr').each(function (i) {
287
			$(this).show();
288
		});
289
	});
290

    
291
	// Hitting the enter key will do the same as clicking the search button
292
	$("#searchstr").on("keyup", function (event) {
293
		if (event.keyCode == 13) {
294
			$("#btnsearch").get(0).click();
295
		}
296
	});
297

    
298
	$('#clearndp').click(function() {
299
		if (confirm("<?=gettext('Are you sure you wish to clear NDP table?')?>")) {
300
			postSubmit({clearndptable: 'true'}, 'diag_ndp.php');
301
		}
302
	});
303

    
304
});
305
//]]>
306
</script>
307

    
308
<?php
309
include('foot.inc');
(22-22/232)