diff --git a/src/lang/da_DK.lang.php b/src/lang/da_DK.lang.php index aa6e8f42..8390057b 100644 --- a/src/lang/da_DK.lang.php +++ b/src/lang/da_DK.lang.php @@ -115,6 +115,7 @@ $sm_lang = array( 'type' => 'Type', 'type_website' => 'Hjemmeside', 'type_service' => 'Tjeneste', + 'type_ping' => 'Ping', 'pattern' => 'Søge streng/mønster', 'pattern_description' => 'Hvis dette mønster ikke findes på hjemmesiden, vil serveren blive markeret offline. Regulære udtryk er tilladt.', 'last_check' => 'Sidst kontrolleret', diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index e8f1dff0..8ec22924 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -115,6 +115,7 @@ $sm_lang = array( 'type' => 'Type', 'type_website' => 'Website', 'type_service' => 'Service', + 'type_ping' => 'Ping', 'pattern' => 'Search string/pattern', 'pattern_description' => 'If this pattern is not found on the website, the server will be marked offline. Regular expressions are allowed.', 'last_check' => 'Last check', diff --git a/src/psm/Module/Server/Controller/ServerController.class.php b/src/psm/Module/Server/Controller/ServerController.class.php index 2b39f89f..6cf8848d 100755 --- a/src/psm/Module/Server/Controller/ServerController.class.php +++ b/src/psm/Module/Server/Controller/ServerController.class.php @@ -208,7 +208,7 @@ class ServerController extends AbstractServerController { 'label' => strip_tags($_POST['label']), 'ip' => strip_tags($_POST['ip']), 'port' => intval($_POST['port']), - 'type' => in_array($_POST['type'], array('website', 'service')) ? $_POST['type'] : 'website', + 'type' => in_array($_POST['type'], array('website', 'service', 'ping')) ? $_POST['type'] : 'website', 'pattern' => $_POST['pattern'], 'warning_threshold' => intval($_POST['warning_threshold']), 'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no', @@ -342,6 +342,7 @@ class ServerController extends AbstractServerController { 'label_type' => psm_get_lang('servers', 'type'), 'label_website' => psm_get_lang('servers', 'type_website'), 'label_service' => psm_get_lang('servers', 'type_service'), + 'label_ping' => psm_get_lang('servers', 'type_ping'), 'label_type' => psm_get_lang('servers', 'type'), 'label_pattern' => psm_get_lang('servers', 'pattern'), 'label_pattern_description' => psm_get_lang('servers', 'pattern_description'), diff --git a/src/psm/Util/Install/Installer.class.php b/src/psm/Util/Install/Installer.class.php index 2198d3bd..ca567c7d 100644 --- a/src/psm/Util/Install/Installer.class.php +++ b/src/psm/Util/Install/Installer.class.php @@ -200,7 +200,7 @@ class Installer { `ip` varchar(100) NOT NULL, `port` int(5) unsigned NOT NULL, `label` varchar(255) NOT NULL, - `type` enum('service','website') NOT NULL default 'service', + `type` enum('service','website','ping') NOT NULL default 'service', `pattern` varchar(255) NOT NULL, `status` enum('on','off') NOT NULL default 'on', `error` varchar(255) NULL, diff --git a/src/psm/Util/Updater/StatusUpdater.class.php b/src/psm/Util/Updater/StatusUpdater.class.php index dacd784a..8ad44bfb 100644 --- a/src/psm/Util/Updater/StatusUpdater.class.php +++ b/src/psm/Util/Updater/StatusUpdater.class.php @@ -95,6 +95,9 @@ class StatusUpdater { case 'website': $this->status_new = $this->updateWebsite($max_runs); break; + case 'ping': + $this->status_new = $this->updatePing($max_runs); + break; } // update server status @@ -217,6 +220,53 @@ class StatusUpdater { return $result; } + + /** + * Check the current server with a ping and hope to get a pong + * @param int $max_runs + * @param int $run + * @return boolean + */ + protected function updatePing($max_runs, $run = 1) { + $errno = 0; + $timeout = 1; + $package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost"; /* ICMP ping packet with a pre-calculated checksum */ + + // save response time + $starttime = microtime(true); + + /* Only run if is cron + * socket_create() need to run as root :( + * ugly hack cli hack i know + */ + //if(psm_is_cli()) { + + // IPv6 ready + if ($this->is_ipv6($this->server['ip'])) { + $socket = socket_create(AF_INET6, SOCK_RAW, 1); + } else { + $socket = socket_create(AF_INET, SOCK_RAW, 1); + } + + + socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0)); + socket_connect($socket, $this->server['ip'], null); + socket_send($socket, $package, strLen($package), 0); + + // if ping fails it returns false + $status = (socket_read($socket, 255)) ? false : true; + $this->rtime = (microtime(true) - $starttime); + + socket_close($socket); + + // check if server is available and rerun if asked. + if(!$status && $run < $max_runs) { + return $this->updatePing($max_runs, $run + 1); + } + + return $status; + //} + } /** * Get the error returned by the update function @@ -235,4 +285,23 @@ class StatusUpdater { public function getRtime() { return $this->rtime; } + + /** + * Test if ip is IPv6 + * @param string $ip + * @return boolean + */ + private function is_ipv6($ip) { + // If it contains anything other than hex characters, periods, colons or a / it's not IPV6 + if (!preg_match("/^([0-9a-f\.\/:]+)$/",strtolower($ip))) { return false; } + + // An IPV6 address needs at minimum two colons in it + if (substr_count($ip,":") < 2) { return false; } + + // If any of the "octets" are longer than 4 characters it's not valid + $part = preg_split("/[:\/]/",$ip); + foreach ($part as $i) { if (strlen($i) > 4) { return false; } } + + return true; + } } diff --git a/src/templates/server/server.tpl.html b/src/templates/server/server.tpl.html index e62a2b26..bf8c1149 100755 --- a/src/templates/server/server.tpl.html +++ b/src/templates/server/server.tpl.html @@ -98,6 +98,7 @@