diff --git a/LookingGlass.php b/LookingGlass.php index 1c0ae45..56bb319 100644 --- a/LookingGlass.php +++ b/LookingGlass.php @@ -1,4 +1,5 @@ -update($str); - echo '---' . PHP_EOL . $parser->__toString() . PHP_EOL . str_pad('', 4096) . PHP_EOL; + echo '---'.PHP_EOL.$parser->__toString().PHP_EOL.str_pad('', 4096).PHP_EOL; // flush output buffering @ob_flush(); flush(); continue; - } - // correct output for traceroute + } // correct output for traceroute elseif ($type === 'traceroute') { if ($match < 10 && preg_match('/^[0-9] /', $str, $string)) { - $str = preg_replace('/^[0-9] /', ' ' . $string[0], $str); + $str = preg_replace('/^[0-9] /', ' '.$string[0], $str); $match++; } // check for consecutive failed hops @@ -304,9 +358,9 @@ class LookingGlass $fail++; if ($lastFail !== 'start' && ($traceCount - 1) === $lastFail - && $fail >= $failCount + && $fail >= $failCount ) { - echo str_pad($str . '
-- Traceroute timed out --
', 4096, ' ', STR_PAD_RIGHT); + echo str_pad($str.'
-- Traceroute timed out --
', 4096, ' ', STR_PAD_RIGHT); break; } $lastFail = $traceCount; @@ -315,7 +369,7 @@ class LookingGlass } // pad string for live output - echo str_pad($str . '
', 4096, ' ', STR_PAD_RIGHT); + echo str_pad($str.'
', 4096, ' ', STR_PAD_RIGHT); // flush output buffering @ob_flush(); @@ -345,7 +399,7 @@ class LookingGlass // kill remaining processes foreach ($pids as $pid) { if (is_numeric($pid)) { - posix_kill((int) $pid, 9); + posix_kill((int)$pid, 9); } } } @@ -353,6 +407,66 @@ class LookingGlass } return true; } + + public static function getLatency(): float + { + $getLatency = self::getLatencyFromSs(self::detectIpAddress()); + if (isset($getLatency[0])) { + return (float)round($getLatency[0]['latency'], 2); + } else { + return 0.00; + } + } + + /** + * This uses the command 'ss' in order to find out latency. + * A clever way coded by @ayyylias, so please keep credits and do not just steal. + * + * @param string $ip The command to execute. + * @return array Returns an array with results. + */ + private static function getLatencyFromSs(string $ip): array + { + $lines = shell_exec('/usr/sbin/ss -Hti state established'); + $ss = []; + $i = 0; + $j = 0; + foreach (explode(PHP_EOL, $lines) as $line) { + if ($i > 1) { + $i = 0; + $j++; + } + if ($line !== '') { + @$ss[$j] .= $line; + $i++; + } + } + $output = []; + foreach ($ss as $socket) { + $socket = preg_replace('!\s+!', ' ', $socket); + $explodedsocket = explode(' ', $socket); + preg_match('/\d+\.\d+\.\d+\.\d+/', $explodedsocket[2], $temp); + if (!isset($temp[0])) { + continue; + } // when thsi cantt be filled just continue + $sock['local'] = $temp[0]; + preg_match('/\d+\.\d+\.\d+\.\d+/', $explodedsocket[3], $temp); + $sock['remote'] = $temp[0]; + preg_match('/segs_out:(\d+)/', $socket, $temp); + $sock['segs_out'] = $temp[1]; + preg_match('/segs_in:(\d+)/', $socket, $temp); + $sock['segs_in'] = $temp[1]; + preg_match_all('/rtt:(\d+\.\d+)\/(\d+\.\d+)/', $socket, $temp); + $sock['latency'] = $temp[1][0]; + $sock['jitter'] = $temp[2][0]; + preg_match_all('/retrans:\d+\/(\d+)/', $socket, $temp); + $sock['retransmissions'] = (isset($temp[1][0]) ? $temp[1][0] : 0); + if ($sock['remote'] == $ip) { + $output[] = $sock; + } + } + return $output; + } } class Hop @@ -423,10 +537,10 @@ class Parser $hop->recieved = count($hop->timings); if (count($hop->timings)) { - $hop->last = $hop->timings[count($hop->timings) - 1]; - $hop->best = $hop->timings[0]; + $hop->last = $hop->timings[count($hop->timings) - 1]; + $hop->best = $hop->timings[0]; $hop->worst = $hop->timings[0]; - $hop->avg = array_sum($hop->timings) / count($hop->timings); + $hop->avg = array_sum($hop->timings) / count($hop->timings); } if (count($hop->timings) > 1) { @@ -434,7 +548,6 @@ class Parser } foreach ($hop->timings as $time) { - if ($hop->best > $time) { $hop->best = $time; } @@ -483,10 +596,10 @@ class Parser return; } - $rawHop = new RawHop(); + $rawHop = new RawHop(); $rawHop->dataType = $things[0]; - $rawHop->idx = (int)$things[1]; - $rawHop->value = $things[2]; + $rawHop->idx = (int)$things[1]; + $rawHop->value = $things[2]; if ($this->hopCount < $rawHop->idx + 1) { $this->hopCount = $rawHop->idx + 1; @@ -496,12 +609,12 @@ class Parser $this->hopsCollection[$rawHop->idx] = new Hop(); } - $hop = $this->hopsCollection[$rawHop->idx]; + $hop = $this->hopsCollection[$rawHop->idx]; $hop->idx = $rawHop->idx; switch ($rawHop->dataType) { case 'h': - $hop->ips[] = $rawHop->value; - $hop->hosts[] = gethostbyaddr($rawHop->value) ? : null; + $hop->ips[] = $rawHop->value; + $hop->hosts[] = gethostbyaddr($rawHop->value) ?: null; break; case 'd': //Not entirely sure if multiple IPs. Better use -n in mtr and resolve later in summarize. @@ -523,13 +636,13 @@ class Parser private function filterLastDupeHop() { // filter dupe last hop - $finalIdx = 0; + $finalIdx = 0; $previousIp = ''; foreach ($this->hopsCollection as $key => $hop) { if (count($hop->ips) && $hop->ips[0] !== $previousIp) { $previousIp = $hop->ips[0]; - $finalIdx = $key + 1; + $finalIdx = $key + 1; } } diff --git a/config.dist.php b/config.dist.php index aaa9fd6..0215e72 100644 --- a/config.dist.php +++ b/config.dist.php @@ -9,6 +9,9 @@ const LG_LOGO = '

Company Looking Glass

'; // Define the URL where the logo points to; const LG_LOGO_URL = 'https://github.com/hybula/lookingglass/'; +// Enable the latency check feature; +const LG_CHECK_LATENCY = false; + // Define a custom CSS file which can be used to style the LG, set false to disable, else point to the CSS file; const LG_CSS_OVERRIDES = false; // Define content, this could be JS, CSS or meta tags; diff --git a/index.php b/index.php index eec0265..16bfb4c 100644 --- a/index.php +++ b/index.php @@ -77,6 +77,10 @@ if (LG_BLOCK_CUSTOM) { $templateData['custom_html'] = ob_get_clean(); } +if (LG_CHECK_LATENCY) { + $templateData['latency'] = LookingGlass::getLatency(); +} + $templateData['csrfToken'] = $_SESSION[LookingGlass::SESSION_CSRF] = bin2hex(random_bytes(12)); ?> @@ -162,6 +166,7 @@ $templateData['csrfToken'] = $_SESSION[LookingGlass::SESSION_CSRF] = bin2hex(ran
+