File: 1.01.4b/server/base/tests.inc.php (View as Code)

1: 2: /* ------------------------------------------------------------- 3: This file is part of FreeNATS 4: 5: FreeNATS is (C) Copyright 2008 PurplePixie Systems 6: 7: FreeNATS is free software: you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation, either version 3 of the License, or 10: (at your option) any later version. 11: 12: FreeNATS is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with FreeNATS. If not, see www.gnu.org/licenses 19: 20: For more information see www.purplepixie.org/freenats 21: -------------------------------------------------------------- */ 22: 23: if (!isset($BaseDir)) $BaseDir="../base/"; // 24: require_once($BaseDir."timer.inc.php"); // just in case standalone 25: 26: // FreeNATS_Local_Test Base Class - Local Tests (run from FreeNATS server) must extend from this 27: 28: class FreeNATS_Local_Test 29: { 30: function DoTest($testname,$param,$hostname="",$timeout=-1,$params=false) 31: { 32: return 0; 33: } 34: 35: function Evaluate($result) 36: { 37: return -1; 38: } 39: 40: function DisplayForm(&$row) 41: { 42: return false; 43: } 44: 45: function ProtectOutput(&$row) 46: { 47: return false; 48: } 49: } 50: 51: // ------------------------------------------------------------------------------------------------ 52: require($BaseDir."tests/tcp.inc.php"); 53: require($BaseDir."tests/udp.inc.php"); 54: require($BaseDir."tests/mysql.inc.php"); 55: require($BaseDir."tests/imap.inc.php"); 56: require($BaseDir."tests/smtp.inc.php"); 57: 58: require($BaseDir."tests/dns.inc.php"); 59: require($BaseDir."tests/nats-dns.inc.php"); // the wrapper module 60: 61: require($BaseDir."tests/smb.inc.php"); 62: 63: 64: function ip_lookup($hostname) // "safe" DNS lookup function to call with a hostname, URL or IP - returns 0 if unsuccessful 65: { 66: // Is it already an IP adress? 67: $out=str_replace(".","",$hostname); 68: if (is_numeric($out)) return $hostname; // yes it is 69: 70: // No it is not 71: $ip=@gethostbyname($hostname); 72: if ($ip==$hostname) return 0; // unmodified host - lookup failed 73: 74: return $ip; 75: } 76: 77: function next_run_x($interval) 78: { 79: if ($interval<1) return time(); 80: return time()+(($interval)*60)-30; 81: } 82: 83: function test_sleep() 84: { 85: global $NATS; 86: if (!isset($NATS)) return false; 87: $sleep=$NATS->Cfg->Get("test.interval",0); 88: if ($sleep<=0) return false; 89: $sleep=$sleep*1000000; // convert to usec 90: usleep($sleep); 91: return true; 92: } 93: 94: function url_lookup($url) 95: { 96: // Sod regular expressions here as we'd have to do it twice or with cleverness I lack 97: // Is it a URL? 98: $colon=strpos($url,":"); 99: if ($colon != 0) // exists so it a URL 100: { 101: $out=preg_match("@^(?:http[s]*://)?([^/|\?|:]+)@i",$url,$matches); 102: $hostname=$matches[1]; 103: } 104: else $hostname=$url; // try direct 105: 106: return ip_lookup($hostname); 107: } 108: 109: 110: 111: 112: 113: 114: 115: function icmpChecksum($data) 116: { 117: if (strlen($data)%2) 118: $data .= "\x00"; 119: 120: $bit = unpack('n*', $data); 121: $sum = array_sum($bit); 122: 123: while ($sum >> 16) 124: $sum = ($sum >> 16) + ($sum & 0xffff); 125: 126: return pack('n*', ~$sum); 127: } 128: 129: function PingTest($host,$ctimeout=-1) 130: { 131: global $NATS; 132: $FreeNATS_Timer=new TFNTimer(); 133: // Make Package 134: $type= "\x08"; 135: $code= "\x00"; 136: $checksum= "\x00\x00"; 137: $identifier = "\x00\x00"; 138: $seqNumber = "\x00\x00"; 139: $data= "FreeNATS"; 140: $package = $type.$code.$checksum.$identifier.$seqNumber.$data; 141: $checksum = icmpChecksum($package); // Calculate the checksum 142: $package = $type.$code.$checksum.$identifier.$seqNumber.$data; 143: 144: // Return s or ms(s*1000) 145: $returnsecs=true; 146: if (isset($NATS)) 147: { 148: if ($NATS->Cfg->Get("test.icmp.returnms",0)==1) $returnsecs=false; 149: } 150: 151: // Timeout Values 152: if (isset($NATS)) $timeout=$NATS->Cfg->Get("test.icmp.timeout",10); 153: else $timeout=10; 154: if ($ctimeout>0) $timeout=$ctimeout; // use custom timeout if passed 155: if ($timeout<=0) $timeout=10; // catch-all for defaults bug 156: 157: // Create Socket 158: $socket = @socket_create(AF_INET, SOCK_RAW, 1); 159: //or die(socket_strerror(socket_last_error())); 160: if (!$socket) return 0; 161: 162: // Set Non-Blocking 163: @socket_set_nonblock($socket); 164: 165: // Connect Socket 166: $sconn=@socket_connect($socket, $host, null); 167: if (!$sconn) return 0; 168: 169: // Send Data 170: @socket_send($socket, $package, strLen($package), 0); 171: 172: // Start Timer 173: $FreeNATS_Timer->Start(); 174: $startTime = microtime(true); // need this for the looping section 175: 176: 177: // Read Data 178: $keepon=true; 179: 180: while( (!(@socket_read($socket, 255))) && $keepon) 181: { // basically just kill time 182: // consider putting some sort of sleepy thing here to lower load but would f* with figures! 183: 184: if ( (microtime(true) - $startTime) > $timeout ) 185: $keepon=false; 186: } 187: 188: if ($keepon) // didn't time out - read data 189: { 190: $elapsed=$FreeNATS_Timer->Stop(); 191: if ($returnsecs) $elapsed=round($elapsed,4); 192: else $elapsed=round( ($elapsed*1000),4 ); 193: @socket_close($socket); 194: // $ret=round(microtime(true) - $startTime, 4); -- old method 195: if ($elapsed<=0) $elapsed="0.0001"; // safety catch-all 196: return $elapsed; 197: /* 198: if ($ret==0) return "0.0001"; 199: else 200: { 201: if ($ret<=0) return "0.0001"; 202: else return $ret; 203: } 204: */ 205: } 206: 207: // Socket timed out 208: @socket_close($socket); 209: return 0; 210: } 211: 212: function WebTest($url,$timeout=-1) 213: { 214: global $NATS; 215: if ($timeout<=0) // use NATS or env 216: { 217: if (isset($NATS)) 218: { 219: $nto=$NATS->Cfg->Get("test.http.timeout",-1); 220: if ($nto>0) $timeout=$nto; // use NATS timeout 221: } 222: } 223: if ($timeout>0) // use the set timeout 224: $oldtimeout=ini_set("default_socket_timeout",$timeout); 225: 226: if (function_exists("curl_getinfo")) // use CURL if present 227: { 228: $ch=curl_init(); 229: curl_setopt($ch,CURLOPT_URL,$url); 230: curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 231: curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0); 232: curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0); 233: curl_setopt($ch,CURLOPT_HEADER,1); 234: if ($timeout>0) curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout); 235: if ($timeout>0) curl_setopt($ch,CURLOPT_TIMEOUT,$timeout); 236: if (!$output=curl_exec($ch)) 237: { 238: $ctr=-1; // failed 239: } 240: else $ctr=round(curl_getinfo($ch,CURLINFO_SIZE_DOWNLOAD)/1024,2); 241: curl_close($ch); 242: 243: if ($ctr==0) $ctr="0.0001"; 244: 245: } 246: else 247: { // no CURL - use fopen() 248: $fp=@fopen($url,"r"); 249: if ($fp<=0) 250: { 251: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout); 252: return -1; 253: } 254: $ctr=0; 255: while ($body=@fgets($fp,1024)) $ctr+=sizeof($body); 256: @fclose($fp); 257: } 258: 259: 260: 261: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout); 262: return $ctr; 263: } 264: 265: function DoTest($test,$param,$hostname="",$timeout=-1,$params=0,$nodeid="") 266: { 267: global $NATS; 268: if (!is_array($params)) 269: { 270: $params=array(); 271: for ($a=0; $a<10; $a++) $params[$a]=""; 272: } 273: 274: switch ($test) 275: { 276: case "web": case "wsize": 277: // Don't bother with pre-resolution as size only 278: return WebTest($param,$timeout); 279: break; 280: /* -- modularised 281: case "tcp": // nb TCP does not support timeouts currently 282: $ip=ip_lookup($hostname); 283: if ($ip=="0") return 0; 284: $fp=@fsockopen($ip,$param); 285: if ($fp<=0) return 0; 286: @fclose($fp); 287: return 1; 288: break; 289: */ 290: case "wtime": 291: $timer=new TFNTimer(); 292: // Do a pre-lookup 293: $ip=url_lookup($param); 294: if ($ip=="0") return -1; // dns lookup failed 295: $timer->Start(); 296: $r=WebTest($param,$timeout); 297: $elapsedTime=$timer->Stop(); 298: $elapsedTime=round($elapsedTime,4); 299: if ($r<0) return -1; // open failed 300: if ($r==0) return -2; // no chars shown as returned 301: if ($elapsedTime<=0) return 0.0001; 302: return $elapsedTime; 303: break; 304: 305: case "host": 306: $timer=new TFNTimer(); 307: if (preg_match("/[a-zA-Z]/",$param)>0) $is_ip=false; 308: else $is_ip=true; 309: 310: $timer->Start(); 311: if ($is_ip) $result=gethostbyaddr($param); 312: else $result=gethostbyname($param); 313: $elapsedTime=$timer->Stop(); 314: 315: if ($result==$param) // lookup failed 316: return -1; 317: 318: if ($result=="") // lookup failed 319: return -1; 320: 321: $elapsedTime=round($elapsedTime,4); 322: if ($elapsedTime<=0) return 0.0001; 323: return $elapsedTime; 324: break; 325: 326: case "testloop": 327: return $param; 328: break; 329: 330: case "testrand": 331: mt_srand(microtime()*1000000); 332: if ( ($param=="") || ($param==0) ) $param=100; 333: return mt_rand(0,$param); 334: break; 335: 336: case "ping": 337: return PingTest($param,$timeout); 338: break; 339: 340: default: 341: if (isset($NATS)) // try and see if a test is registered 342: { 343: if (isset($NATS->Tests->QuickList[$test])) // exists 344: { 345: $NATS->Tests->Tests[$test]->Create(); 346: return $NATS->Tests->Tests[$test]->instance->DoTest($test,$param,$hostname,$timeout,$params); 347: } 348: } 349: 350: } 351: return -1; // did not run any test so untested 352: } 353: 354: function SimpleEval($test,$result) 355: { 356: global $NATS; 357: switch($test) 358: { 359: case "ping": // handles both types of simple evaluation (inbuilt ICMP and remote ping) 360: if ($result<=0) return 2; 361: return 0; 362: case "web": case "wsize": 363: if ($result<=0) return 2; 364: return 0; 365: /* 366: case "tcp": 367: if ($result==1) return 0; 368: return 2; 369: */ 370: case "wtime": 371: if ($result<0) return 2; 372: return 0; 373: /* 374: case "mysql": 375: if ($result<=0) return 2; 376: return 0; 377: 378: case "mysqlrows": 379: if ($result<=0) return 2; // no rows returned or error 380: return 0; 381: */ 382: case "host": case "dns": 383: if ($result<=0) return 2; // no records returned or error 384: 385: case "testloop": 386: return 0; 387: case "testrand": 388: return 0; 389: 390: default: 391: if (isset($NATS)) 392: { 393: if (isset($NATS->Tests->QuickList[$test])) 394: { 395: $NATS->Tests->Tests[$test]->Create(); 396: return $NATS->Tests->Tests[$test]->instance->Evaluate($result); 397: } 398: } 399: } 400: return -1; // untested if we don't know WTF the result was 401: } 402: 403: function aText($al) 404: { 405: return oText($al); // uses function in tests.inc.php with site config support 406: /* -- depreciated 407: switch($al) 408: { 409: case -1: return "Untested"; 410: case 0: return "Passed"; 411: case 1: return "Warning"; 412: case 2: return "Failed"; 413: default: return "Unknown"; 414: } 415: */ 416: } 417: ?>