Project

General

Profile

Download (12.4 KB) Statistics
| Branch: | Tag: | Revision:
1 e078c882 jim-p
<?php
2
/*
3 c5d81585 Renato Botelho
 * status_ntpd.php
4 191cb31d 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 a68f7a3d Luiz Otavio O Souza
 * Copyright (c) 2014-2024 Rubicon Communications, LLC (Netgate)
9 c5d81585 Renato Botelho
 * Copyright (c) 2013 Dagorlad
10
 * All rights reserved.
11 191cb31d Stephen Beaver
 *
12 c5d81585 Renato Botelho
 * originally based on m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15 191cb31d Stephen Beaver
 *
16 b12ea3fb Renato Botelho
 * 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 191cb31d Stephen Beaver
 *
20 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
21 191cb31d Stephen Beaver
 *
22 b12ea3fb Renato Botelho
 * 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 5d36f3c4 Stephen Beaver
 */
28 e078c882 jim-p
29
##|+PRIV
30
##|*IDENT=page-status-ntp
31 5230f468 jim-p
##|*NAME=Status: NTP
32 e078c882 jim-p
##|*DESCR=Allow access to the 'Status: NTP' page.
33
##|*MATCH=status_ntpd.php*
34
##|-PRIV
35
36 a5906662 Reid Linnemann
require_once('config.inc');
37 d0ca7530 Reid Linnemann
require_once('config.lib.inc');
38
require_once('guiconfig.inc');
39
40
$allow_query = !config_path_enabled('ntpd','noquery');
41
foreach (config_get_path('ntpd/restrictions/row') as $v) {
42
	if (ip_in_subnet('127.0.0.1', "{$v['acl_network']}/{$v['mask']}") || 
43
		ip_in_subnet('::1', "{$v['acl_network']}/{$v['mask']}")) {
44
		$allow_query = !isset($v['noquery']);
45 d73918f2 Nano Caiordo
	}
46
}
47
48 d0ca7530 Reid Linnemann
if ($allow_query && (config_get_path('ntpd/enable') != 'disabled')) {
49
	if (config_path_enabled('system','ipv6allow')) {
50 e4a496ae Phil Davis
		$inet_version = "";
51 42b0c921 Phil Davis
	} else {
52 e4a496ae Phil Davis
		$inet_version = " -4";
53 42b0c921 Phil Davis
	}
54 5c8843d5 jim-p
55 d09e19ad jim-p
	exec('/usr/local/sbin/ntpq -pnw ' . $inet_version . ' | /usr/bin/tail +3 | /usr/bin/awk -v RS= \'{gsub(/\n[[:space:]][[:space:]]+/," ")}1\'', $ntpq_output);
56 25890c50 jim-p
57 c56d07dc nagyrobi
	$ntpq_servers = array();
58
	foreach ($ntpq_output as $line) {
59
		$server = array();
60 fbb652ed jim-p
		$status_char = substr($line, 0, 1);
61
		$line = substr($line, 1);
62
		$peerinfo = preg_split("/[\s\t]+/", $line);
63
64
		$server['server'] = $peerinfo[0];
65
		$server['refid'] = $peerinfo[1];
66
		$server['stratum'] = $peerinfo[2];
67
		$server['type'] = $peerinfo[3];
68
		$server['when'] = $peerinfo[4];
69
		$server['poll'] = $peerinfo[5];
70
		$server['reach'] = $peerinfo[6];
71
		$server['delay'] = $peerinfo[7];
72
		$server['offset'] = $peerinfo[8];
73
		$server['jitter'] = $peerinfo[9];
74 c56d07dc nagyrobi
75 fbb652ed jim-p
		switch ($status_char) {
76 c56d07dc nagyrobi
			case " ":
77 fbb652ed jim-p
				if ($server['refid'] == ".POOL.") {
78
					$server['status'] = gettext("Pool Placeholder");
79
				} else {
80
					$server['status'] = gettext("Unreach/Pending");
81
				}
82 c56d07dc nagyrobi
				break;
83
			case "*":
84 3bd74348 bruno
				$server['status'] = gettext("Active Peer");
85 c56d07dc nagyrobi
				break;
86
			case "+":
87 3bd74348 bruno
				$server['status'] = gettext("Candidate");
88 c56d07dc nagyrobi
				break;
89
			case "o":
90 3bd74348 bruno
				$server['status'] = gettext("PPS Peer");
91 c56d07dc nagyrobi
				break;
92
			case "#":
93 3bd74348 bruno
				$server['status'] = gettext("Selected");
94 c56d07dc nagyrobi
				break;
95
			case ".":
96 3bd74348 bruno
				$server['status'] = gettext("Excess Peer");
97 c56d07dc nagyrobi
				break;
98
			case "x":
99 3bd74348 bruno
				$server['status'] = gettext("False Ticker");
100 c56d07dc nagyrobi
				break;
101
			case "-":
102 3bd74348 bruno
				$server['status'] = gettext("Outlier");
103 c56d07dc nagyrobi
				break;
104
		}
105
106
		$ntpq_servers[] = $server;
107
	}
108
109 62a407da Phil Davis
	exec("/usr/local/sbin/ntpq -c clockvar $inet_version", $ntpq_clockvar_output);
110 c56d07dc nagyrobi
	foreach ($ntpq_clockvar_output as $line) {
111
		if (substr($line, 0, 9) == "timecode=") {
112
			$tmp = explode('"', $line);
113
			$tmp = $tmp[1];
114
			if (substr($tmp, 0, 6) == '$GPRMC') {
115
				$gps_vars = explode(",", $tmp);
116 6c07db48 Phil Davis
				$gps_ok = ($gps_vars[2] == "A");
117 c56d07dc nagyrobi
				$gps_lat_deg = substr($gps_vars[3], 0, 2);
118 d627983d jskyboo
				$gps_lat_min = substr($gps_vars[3], 2);
119 c56d07dc nagyrobi
				$gps_lon_deg = substr($gps_vars[5], 0, 3);
120 d627983d jskyboo
				$gps_lon_min = substr($gps_vars[5], 3);
121 0e847960 jim-p
				$gps_lat = (float) $gps_lat_deg + (float) $gps_lat_min / 60.0;
122 c56d07dc nagyrobi
				$gps_lat = $gps_lat * (($gps_vars[4] == "N") ? 1 : -1);
123 0e847960 jim-p
				$gps_lon = (float) $gps_lon_deg + (float) $gps_lon_min / 60.0;
124 c56d07dc nagyrobi
				$gps_lon = $gps_lon * (($gps_vars[6] == "E") ? 1 : -1);
125 d627983d jskyboo
				$gps_lat_dir = $gps_vars[4];
126
				$gps_lon_dir = $gps_vars[6];
127 42b0c921 Phil Davis
			} elseif (substr($tmp, 0, 6) == '$GPGGA') {
128 c56d07dc nagyrobi
				$gps_vars = explode(",", $tmp);
129 6c07db48 Phil Davis
				$gps_ok = $gps_vars[6];
130 c56d07dc nagyrobi
				$gps_lat_deg = substr($gps_vars[2], 0, 2);
131 d627983d jskyboo
				$gps_lat_min = substr($gps_vars[2], 2);
132 c56d07dc nagyrobi
				$gps_lon_deg = substr($gps_vars[4], 0, 3);
133 d627983d jskyboo
				$gps_lon_min = substr($gps_vars[4], 3);
134 0e847960 jim-p
				$gps_lat = (float) $gps_lat_deg + (float) $gps_lat_min / 60.0;
135 c56d07dc nagyrobi
				$gps_lat = $gps_lat * (($gps_vars[3] == "N") ? 1 : -1);
136 0e847960 jim-p
				$gps_lon = (float) $gps_lon_deg + (float) $gps_lon_min / 60.0;
137 c56d07dc nagyrobi
				$gps_lon = $gps_lon * (($gps_vars[5] == "E") ? 1 : -1);
138
				$gps_alt = $gps_vars[9];
139
				$gps_alt_unit = $gps_vars[10];
140 fdb04797 jskyboo
				$gps_sat = (int)$gps_vars[7];
141 d627983d jskyboo
				$gps_lat_dir = $gps_vars[3];
142
				$gps_lon_dir = $gps_vars[5];
143 42b0c921 Phil Davis
			} elseif (substr($tmp, 0, 6) == '$GPGLL') {
144 fdb04797 jskyboo
				$gps_vars = preg_split('/[,\*]+/', $tmp);
145 6c07db48 Phil Davis
				$gps_ok = ($gps_vars[6] == "A");
146 c56d07dc nagyrobi
				$gps_lat_deg = substr($gps_vars[1], 0, 2);
147 d627983d jskyboo
				$gps_lat_min = substr($gps_vars[1], 2);
148 c56d07dc nagyrobi
				$gps_lon_deg = substr($gps_vars[3], 0, 3);
149 d627983d jskyboo
				$gps_lon_min = substr($gps_vars[3], 3);
150 0e847960 jim-p
				$gps_lat = (float) $gps_lat_deg + (float) $gps_lat_min / 60.0;
151 c56d07dc nagyrobi
				$gps_lat = $gps_lat * (($gps_vars[2] == "N") ? 1 : -1);
152 0e847960 jim-p
				$gps_lon = (float) $gps_lon_deg + (float) $gps_lon_min / 60.0;
153 c56d07dc nagyrobi
				$gps_lon = $gps_lon * (($gps_vars[4] == "E") ? 1 : -1);
154 d627983d jskyboo
				$gps_lat_dir = $gps_vars[2];
155
				$gps_lon_dir = $gps_vars[4];
156 6924a2bf jskyboo
			} elseif (substr($tmp, 0, 6) == '$PGRMF') {
157
				$gps_vars = preg_split('/[,\*]+/', $tmp);
158
				$gps_ok = $gps_vars[11];
159
				$gps_lat_deg = substr($gps_vars[6], 0, 2);
160
				$gps_lat_min = substr($gps_vars[6], 2);
161
				$gps_lon_deg = substr($gps_vars[8], 0, 3);
162
				$gps_lon_min = substr($gps_vars[8], 3);
163 0e847960 jim-p
				$gps_lat = (float) $gps_lat_deg + (float) $gps_lat_min / 60.0;
164 6924a2bf jskyboo
				$gps_lat = $gps_lat * (($gps_vars[7] == "N") ? 1 : -1);
165 0e847960 jim-p
				$gps_lon = (float) $gps_lon_deg + (float) $gps_lon_min / 60.0;
166 6924a2bf jskyboo
				$gps_lon = $gps_lon * (($gps_vars[9] == "E") ? 1 : -1);
167
				$gps_lat_dir = $gps_vars[7];
168
				$gps_lon_dir = $gps_vars[9];
169 c56d07dc nagyrobi
			}
170
		}
171 25890c50 jim-p
	}
172 e078c882 jim-p
}
173
174 0e847960 jim-p
global $showgps;
175
$showgps = 0;
176
177
global $gps_goo_lnk;
178
$gps_goo_lnk = 1;
179
180
// GPS satellite information (if available)
181
if (($gps_ok) && ($gps_lat) && ($gps_lon)) {
182
	$gps_goo_lnk = 2;
183
	$showgps = 1;
184
}
185
186
if (isset($gps_ok) && config_path_enabled('ntpd/gps','extstatus')) {
187 d0ca7530 Reid Linnemann
	$lookfor['GPGSV'] = config_path_enabled('ntpd/gps/nmeaset','gpgsv');
188
	$lookfor['GPGGA'] = !isset($gps_sat) && config_path_enabled('ntpd/gps/nmeaset','gpgga');
189 d627983d jskyboo
	$gpsport = fopen('/dev/gps0', 'r+');
190
	while ($gpsport && ($lookfor['GPGSV'] || $lookfor['GPGGA'])) {
191 c56d07dc nagyrobi
		$buffer = fgets($gpsport);
192 d627983d jskyboo
		if ($lookfor['GPGSV'] && substr($buffer, 0, 6) == '$GPGSV') {
193 6c07db48 Phil Davis
			$gpgsv = explode(',', $buffer);
194 d627983d jskyboo
			$gps_satview = (int)$gpgsv[3];
195 d0ca7530 Reid Linnemann
			$lookfor['GPGSV'] = false;
196 d627983d jskyboo
		} elseif ($lookfor['GPGGA'] && substr($buffer, 0, 6) == '$GPGGA') {
197
			$gpgga = explode(',', $buffer);
198
			$gps_sat = (int)$gpgga[7];
199
			$gps_alt = $gpgga[9];
200
			$gps_alt_unit = $gpgga[10];
201 d0ca7530 Reid Linnemann
			$lookfor['GPGGA'] = false;
202 5c8843d5 jim-p
		}
203
	}
204
}
205
206 0cdf72ef Stephen Beaver
// Responding to an AJAX call, we return the GPS data or the status data depending on $_REQUEST['dogps']
207
if ($_REQUEST['ajax']) {
208
209
	if ($_REQUEST['dogps'] == "yes") {
210
		print_gps();
211
	} else {
212
		print_status();
213
	}
214
215
	exit;
216
}
217
218
function print_status() {
219 d0ca7530 Reid Linnemann
	global $ntpq_servers, $allow_query;
220 0cdf72ef Stephen Beaver
221 d0ca7530 Reid Linnemann
	if (config_get_path('ntpd/enable') == 'disabled'):
222 b5d5da0c Viktor Gurov
		print("<tr>\n");
223
		print('<td class="warning" colspan="11">');
224
		printf(gettext('NTP Server is disabled'));
225
		print("</td>\n");
226
		print("</tr>\n");
227
	elseif (!$allow_query):
228 0cdf72ef Stephen Beaver
		print("<tr>\n");
229
		print('<td class="warning" colspan="11">');
230 702fa4d0 Phil Davis
		printf(gettext('Statistics unavailable because ntpq and ntpdc queries are disabled in the %1$sNTP service settings%2$s'), '<a href="services_ntpd.php">', '</a>');
231 0cdf72ef Stephen Beaver
		print("</td>\n");
232
		print("</tr>\n");
233
	elseif (count($ntpq_servers) == 0):
234
		print("<tr>\n");
235
		print('<td class="warning" colspan="11">');
236 702fa4d0 Phil Davis
		printf(gettext('No peers found, %1$sis the ntp service running?%2$s'), '<a href="status_services.php">', '</a>');
237 0cdf72ef Stephen Beaver
		print("</td>\n");
238
		print("</tr>\n");
239
	else:
240
241
		$i = 0;
242
		foreach ($ntpq_servers as $server):
243
			print("<tr>\n");
244
			print("<td>" . $server['status'] . "</td>\n");
245
			print("<td>" . $server['server'] . "</td>\n");
246
			print("<td>" . $server['refid'] . "</td>\n");
247
			print("<td>" . $server['stratum'] . "</td>\n");
248
			print("<td>" . $server['type'] . "</td>\n");
249
			print("<td>" . $server['when'] . "</td>\n");
250
			print("<td>" . $server['poll'] . "</td>\n");
251
			print("<td>" . $server['reach'] . "</td>\n");
252
			print("<td>" . $server['delay'] . "</td>\n");
253
			print("<td>" . $server['offset'] . "</td>\n");
254
			print("<td>" . $server['jitter'] . "</td>\n");
255
			print("</tr>\n");
256
			$i++;
257
		endforeach;
258
	endif;
259
}
260
261
function print_gps() {
262 d627983d jskyboo
	global 	$gps_lat, $gps_lon, $gps_lat_deg, $gps_lon_deg, $gps_lat_min, $gps_lon_min, $gps_lat_dir, $gps_lon_dir,
263 0cdf72ef Stephen Beaver
			$gps_alt, $gps_alt_unit, $gps_sat, $gps_satview, $gps_goo_lnk;
264
265
	print("<tr>\n");
266
	print("<td>\n");
267 ef268b48 Stephen Beaver
	printf("%.5f", $gps_lat);
268 0cdf72ef Stephen Beaver
	print(" (");
269 ef268b48 Stephen Beaver
	printf("%d%s", $gps_lat_deg, "&deg;");
270 d627983d jskyboo
	printf("%.5f", $gps_lat_min);
271
	print($gps_lat_dir);
272 0cdf72ef Stephen Beaver
	print(")");
273
	print("</td>\n");
274
	print("<td>\n");
275 ef268b48 Stephen Beaver
	printf("%.5f", $gps_lon);
276 0cdf72ef Stephen Beaver
	print(" (");
277 ef268b48 Stephen Beaver
	printf("%d%s", $gps_lon_deg, "&deg;");
278 d627983d jskyboo
	printf("%.5f", $gps_lon_min);
279
	print($gps_lon_dir);
280 0cdf72ef Stephen Beaver
	print(")");
281
	print("</td>\n");
282
283
	if (isset($gps_alt)) {
284 ef268b48 Stephen Beaver
		print("<td>\n");
285
		print($gps_alt . ' ' . $gps_alt_unit);
286
		print("</td>\n");
287 0cdf72ef Stephen Beaver
	}
288
289
	if (isset($gps_sat) || isset($gps_satview)) {
290 fdb04797 jskyboo
		print('<td>');
291 0cdf72ef Stephen Beaver
292
		if (isset($gps_satview)) {
293
			print(gettext('in view ') . intval($gps_satview));
294
		}
295
296
		if (isset($gps_sat) && isset($gps_satview)) {
297
			print(', ');
298
		}
299
		if (isset($gps_sat)) {
300
			print(gettext('in use ') . $gps_sat);
301
		}
302
303
		print("</td>\n");
304
	}
305
306
	print("</tr>\n");
307
	print("<tr>\n");
308 47df65c3 Viktor G
	print('<td colspan="' . $gps_goo_lnk . '"><a target="_gmaps" href="https://maps.google.com/?q=' . $gps_lat . ',' . $gps_lon . '">' . gettext("Google Maps Link") . '</a></td>');
309 0cdf72ef Stephen Beaver
	print("</tr>\n");
310
}
311
312 6c07db48 Phil Davis
$pgtitle = array(gettext("Status"), gettext("NTP"));
313 b32dd0a6 jim-p
$shortcut_section = "ntp";
314 8dff26ce sbeaver
315 e078c882 jim-p
include("head.inc");
316
?>
317 8dff26ce sbeaver
318
<div class="panel panel-default">
319 3bd74348 bruno
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Network Time Protocol Status");?></h2></div>
320 8dff26ce sbeaver
	<div class="panel-body">
321 10fe1eb5 Stephen Beaver
		<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
322 8dff26ce sbeaver
			<thead>
323
				<tr>
324 0cdf72ef Stephen Beaver
					<th><?=gettext("Status")?></th>
325
					<th><?=gettext("Server")?></th>
326
					<th><?=gettext("Ref ID")?></th>
327
					<th><?=gettext("Stratum")?></th>
328
					<th><?=gettext("Type")?></th>
329
					<th><?=gettext("When")?></th>
330 46ab767e Viktor Gurov
					<th><?=gettext("Poll (s)")?></th>
331 0cdf72ef Stephen Beaver
					<th><?=gettext("Reach")?></th>
332 46ab767e Viktor Gurov
					<th><?=gettext("Delay (ms)")?></th>
333
					<th><?=gettext("Offset (ms)")?></th>
334
					<th><?=gettext("Jitter (ms)")?></th>
335 8dff26ce sbeaver
				</tr>
336
			</thead>
337 0cdf72ef Stephen Beaver
			<tbody id="ntpbody">
338
				<?=print_status()?>
339 8dff26ce sbeaver
			</tbody>
340
		</table>
341
	</div>
342
</div>
343
344
345
<?php
346
347
// GPS satellite information (if available)
348
if (($gps_ok) && ($gps_lat) && ($gps_lon)):
349 c33f2391 Phil Davis
	$gps_goo_lnk = 2;
350 0cdf72ef Stephen Beaver
	$showgps = 1;
351 c33f2391 Phil Davis
?>
352 8dff26ce sbeaver
353 c33f2391 Phil Davis
<div class="panel panel-default">
354 3d7a8696 k-paulius
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("GPS Information");?></h2></div>
355 c33f2391 Phil Davis
	<div class="panel-body">
356
		<table class="table table-striped table-hover table-condensed">
357
			<thead>
358 8dff26ce sbeaver
				<tr>
359 0cdf72ef Stephen Beaver
					<th><?=gettext("Clock Latitude")?></th>
360
					<th><?=gettext("Clock Longitude")?></th>
361 c33f2391 Phil Davis
<?php
362
	if (isset($gps_alt)) {
363
?>
364 0cdf72ef Stephen Beaver
					<th><?=gettext("Clock Altitude")?></th>
365 c33f2391 Phil Davis
<?php
366
		$gps_goo_lnk++;
367
	}
368 8dff26ce sbeaver
369 c33f2391 Phil Davis
	if (isset($gps_sat) || isset($gps_satview)) {
370
?>
371 0cdf72ef Stephen Beaver
					<th><?=gettext("Satellites")?></th>
372 c33f2391 Phil Davis
<?php
373
		$gps_goo_lnk++;
374
	}
375
?>
376
				</tr>
377
			</thead>
378 8dff26ce sbeaver
379 0cdf72ef Stephen Beaver
			<tbody id="gpsbody">
380
				<?=print_gps()?>
381
			</tbody>
382
		</table>
383
	</div>
384
</div>
385 8dff26ce sbeaver
386 c33f2391 Phil Davis
<?php
387 0cdf72ef Stephen Beaver
endif;
388 c33f2391 Phil Davis
?>
389 8dff26ce sbeaver
390 0cdf72ef Stephen Beaver
<script type="text/javascript">
391
//<![CDATA[
392
events.push(function() {
393
	ajax_lock = false;		// Mutex so we don't make a call until the previous call is finished
394
	do_gps = "no";
395 8dff26ce sbeaver
396 0cdf72ef Stephen Beaver
	// Fetch the tbody contents from the server
397
	function update_tables() {
398
399
		if (ajax_lock) {
400
			return;
401 c33f2391 Phil Davis
		}
402 0cdf72ef Stephen Beaver
403
		ajax_lock = true;
404
405
		ajaxRequest = $.ajax(
406
			{
407
				url: "/status_ntpd.php",
408
				type: "post",
409
				data: {
410
					ajax: 	"ajax",
411
					dogps:  do_gps
412
				}
413
			}
414
		);
415
416
		// Deal with the results of the above ajax call
417
		ajaxRequest.done(function (response, textStatus, jqXHR) {
418
			if (do_gps == "yes") {
419
				$('#gpsbody').html(response);
420
			} else {
421
				$('#ntpbody').html(response);
422
			}
423
424
			ajax_lock = false;
425
426 adaa4d03 Stephen Beaver
			// Alternate updating the status table and the gps table (if enabled)
427 0cdf72ef Stephen Beaver
			if ((do_gps == "yes") || ("<?=$showgps?>" != 1)) {
428
				do_gps = "no";
429
			} else {
430 adaa4d03 Stephen Beaver
				do_gps = "yes";
431 0cdf72ef Stephen Beaver
			}
432
433
			// and do it again
434
			setTimeout(update_tables, 5000);
435
		});
436
437
438 c33f2391 Phil Davis
	}
439 8dff26ce sbeaver
440 0cdf72ef Stephen Beaver
	// Populate the tbody on page load
441
	update_tables();
442
});
443
//]]>
444
</script>
445 8dff26ce sbeaver
446 0cdf72ef Stephen Beaver
<?php
447 c33f2391 Phil Davis
include("foot.inc");
448
?>