File: 1.00.1a/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: 53: require($BaseDir."tests/mysql.inc.php"); 54: require($BaseDir."tests/imap.inc.php"); 55: require($BaseDir."tests/smtp.inc.php"); 56: require($BaseDir."tests/dns.inc.php"); 57: 58: function ip_lookup($hostname) // "safe" DNS lookup function to call with a hostname, URL or IP - returns 0 if unsuccessful 59: { 60: // Is it already an IP adress? 61: $out=str_replace(".","",$hostname); 62: if (is_numeric($out)) return $hostname; // yes it is 63: 64: // No it is not 65: $ip=@gethostbyname($hostname); 66: if ($ip==$hostname) return 0; // unmodified host - lookup failed 67: 68: return $ip; 69: } 70: 71: function next_run_x($interval) 72: { 73: if ($interval<1) return time(); 74: return time()+(($interval)*60)-30; 75: } 76: 77: function test_sleep() 78: { 79: global $NATS; 80: if (!isset($NATS)) return false; 81: $sleep=$NATS->Cfg->Get("test.interval",0); 82: if ($sleep<=0) return false; 83: $sleep=$sleep*1000000; // convert to usec 84: usleep($sleep); 85: return true; 86: } 87: 88: function url_lookup($url) 89: { 90: // Sod regular expressions here as we'd have to do it twice or with cleverness I lack 91: // Is it a URL? 92: $colon=strpos($url,":"); 93: if ($colon != 0) // exists so it a URL 94: { 95: $out=preg_match("@^(?:http[s]*://)?([^/|\?|:]+)@i",$url,$matches); 96: $hostname=$matches[1]; 97: } 98: else $hostname=$url; // try direct 99: 100: return ip_lookup($hostname); 101: } 102: 103: 104: 105: 106: 107: 108: 109: function icmpChecksum($data) 110: { 111: if (strlen($data)%2) 112: $data .= "\x00"; 113: 114: $bit = unpack('n*', $data); 115: $sum = array_sum($bit); 116: 117: while ($sum >> 16) 118: $sum = ($sum >> 16) + ($sum & 0xffff); 119: 120: return pack('n*', ~$sum); 121: } 122: 123: function PingTest($host,$ctimeout=-1) 124: { 125: global $NATS; 126: $FreeNATS_Timer=new TFNTimer(); 127: // Make Package 128: $type= "\x08"; 129: $code= "\x00"; 130: $checksum= "\x00\x00"; 131: $identifier = "\x00\x00"; 132: $seqNumber = "\x00\x00"; 133: $data= "FreeNATS"; 134: $package = $type.$code.$checksum.$identifier.$seqNumber.$data; 135: $checksum = icmpChecksum($package); // Calculate the checksum 136: $package = $type.$code.$checksum.$identifier.$seqNumber.$data; 137: 138: // Return s or ms(s*1000) 139: $returnsecs=true; 140: if (isset($NATS)) 141: { 142: if ($NATS->Cfg->Get("test.icmp.returnms",0)==1) $returnsecs=false; 143: } 144: 145: // Timeout Values 146: if (isset($NATS)) $timeout=$NATS->Cfg->Get("test.icmp.timeout",10); 147: else $timeout=10; 148: if ($ctimeout>0) $timeout=$ctimeout; // use custom timeout if passed 149: if ($timeout<=0) $timeout=10; // catch-all for defaults bug 150: 151: // Create Socket 152: $socket = @socket_create(AF_INET, SOCK_RAW, 1); 153: //or die(socket_strerror(socket_last_error())); 154: if (!$socket) return 0; 155: 156: // Set Non-Blocking 157: @socket_set_nonblock($socket); 158: 159: // Connect Socket 160: $sconn=@socket_connect($socket, $host, null); 161: if (!$sconn) return 0; 162: 163: // Send Data 164: @socket_send($socket, $package, strLen($package), 0); 165: 166: // Start Timer 167: $FreeNATS_Timer->Start(); 168: $startTime = microtime(true); // need this for the looping section 169: 170: 171: // Read Data 172: $keepon=true; 173: 174: while( (!(@socket_read($socket, 255))) && $keepon) 175: { // basically just kill time 176: // consider putting some sort of sleepy thing here to lower load but would f* with figures! 177: 178: if ( (microtime(true) - $startTime) > $timeout ) 179: $keepon=false; 180: } 181: 182: if ($keepon) // didn't time out - read data 183: { 184: $elapsed=$FreeNATS_Timer->Stop(); 185: if ($returnsecs) $elapsed=round($elapsed,4); 186: else $elapsed=round( ($elapsed*1000),4 ); 187: @socket_close($socket); 188: // $ret=round(microtime(true) - $startTime, 4); -- old method 189: if ($elapsed<=0) $elapsed="0.0001"; // safety catch-all 190: return $elapsed; 191: /* 192: if ($ret==0) return "0.0001"; 193: else 194: { 195: if ($ret<=0) return "0.0001"; 196: else return $ret; 197: } 198: */ 199: } 200: 201: // Socket timed out 202: @socket_close($socket); 203: return 0; 204: } 205: 206: function WebTest($url,$timeout=-1) 207: { 208: global $NATS; 209: if ($timeout<=0) // use NATS or env 210: { 211: if (isset($NATS)) 212: { 213: $nto=$NATS->Cfg->Get("test.http.timeout",-1); 214: if ($nto>0) $timeout=$nto; // use NATS timeout 215: } 216: } 217: if ($timeout>0) // use the set timeout 218: $oldtimeout=ini_set("default_socket_timeout",$timeout); 219: 220: if (function_exists("curl_getinfo")) // use CURL if present 221: { 222: $ch=curl_init(); 223: curl_setopt($ch,CURLOPT_URL,$url); 224: curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 225: curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0); 226: curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0); 227: curl_setopt($ch,CURLOPT_HEADER,1); 228: if ($timeout>0) curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout); 229: if ($timeout>0) curl_setopt($ch,CURLOPT_TIMEOUT,$timeout); 230: if (!$output=curl_exec($ch)) 231: { 232: $ctr=-1; // failed 233: } 234: else $ctr=round(curl_getinfo($ch,CURLINFO_SIZE_DOWNLOAD)/1024,2); 235: curl_close($ch); 236: 237: if ($ctr==0) $ctr="0.0001"; 238: 239: } 240: else 241: { // no CURL - use fopen() 242: $fp=@fopen($url,"r"); 243: if ($fp<=0) 244: { 245: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout); 246: return -1; 247: } 248: $ctr=0; 249: while ($body=@fgets($fp,1024)) $ctr+=sizeof($body); 250: @fclose($fp); 251: } 252: 253: 254: 255: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout); 256: return $ctr; 257: } 258: 259: function DoTest($test,$param,$hostname="",$timeout=-1,$params=0,$nodeid="") 260: { 261: global $NATS; 262: if (!is_array($params)) 263: { 264: $params=array(); 265: for ($a=0; $a<10; $a++) $params[$a]=""; 266: } 267: 268: switch ($test) 269: { 270: case "web": case "wsize": 271: // Don't bother with pre-resolution as size only 272: return WebTest($param,$timeout); 273: break; 274: case "tcp": // nb TCP does not support timeouts currently 275: $ip=ip_lookup($hostname); 276: if ($ip=="0") return 0; 277: $fp=@fsockopen($ip,$param); 278: if ($fp<=0) return 0; 279: @fclose($fp); 280: return 1; 281: break; 282: case "wtime": 283: $timer=new TFNTimer(); 284: // Do a pre-lookup 285: $ip=url_lookup($param); 286: if ($ip=="0") return -1; // dns lookup failed 287: $timer->Start(); 288: $r=WebTest($param,$timeout); 289: $elapsedTime=$timer->Stop(); 290: $elapsedTime=round($elapsedTime,4); 291: if ($r<0) return -1; // open failed 292: if ($r==0) return -2; // no chars shown as returned 293: if ($elapsedTime<=0) return 0.0001; 294: return $elapsedTime; 295: break; 296: 297: case "host": 298: $timer=new TFNTimer(); 299: if (preg_match("/[a-zA-Z]/",$param)>0) $is_ip=false; 300: else $is_ip=true; 301: 302: $timer->Start(); 303: if ($is_ip) $result=gethostbyaddr($param); 304: else $result=gethostbyname($param); 305: $elapsedTime=$timer->Stop(); 306: 307: if ($result==$param) // lookup failed 308: return -1; 309: 310: if ($result=="") // lookup failed 311: return -1; 312: 313: $elapsedTime=round($elapsedTime,4); 314: if ($elapsedTime<=0) return 0.0001; 315: return $elapsedTime; 316: break; 317: 318: case "dns": 319: $timer=new TFNTimer(); 320: if ($param=="") $dnsserver=$hostname; 321: else $dnsserver=$param; 322: if ($dnsserver=="") return -3; 323: if ($timeout<=0) $timeout=60; 324: if ($params[4]==1) $udp=false; // use TCP 325: else $udp=true; 326: if (($params[3]=="")||($params[3]==0)) $port=53; 327: else $port=$params[3]; 328: 329: $dns_query=new DNSQuery($dnsserver,$port,$timeout,$udp,false); // run with debug off 330: $type=$params[2]; 331: $query=$params[1]; 332: 333: $timer->Start(); 334: $answer=$dns_query->Query($query,$type); 335: $elapsedTime=$timer->Stop(); 336: 337: if ( ($answer===false) || ($dns_query->error) ) return -2; // query error 338: if ($answer->count<=0) return -1; // no records returned 339: 340: // otherwise we've got some results ok 341: $elapsedTime=round($elapsedTime,4); 342: if ($elapsedTime<=0) return 0.0001; 343: return $elapsedTime; 344: break; 345: 346: case "testloop": 347: return $param; 348: break; 349: 350: case "testrand": 351: mt_srand(microtime()*1000000); 352: if ( ($param=="") || ($param==0) ) $param=100; 353: return mt_rand(0,$param); 354: break; 355: 356: case "ping": 357: return PingTest($param,$timeout); 358: break; 359: /* // now handled as a module 360: case "smtp": 361: $ip=ip_lookup($param); 362: if ($ip=="0") return -1; 363: return smtp_test_time($ip,$params[1],$timeout); 364: break; 365: */ 366: case "imap": 367: if ($params[5]==1) $ssl=true; 368: else $ssl=false; 369: 370: $ip=ip_lookup($param); 371: if ($ip=="0") return -1; 372: 373: return imap_test_time($ip,$params[1],$params[2],$timeout,$params[3],$params[4],$ssl); 374: break; 375: 376: case "mysql": 377: $ip=ip_lookup($param); 378: if ($ip=="0") return -1; // cache only as 127.0.0.1 is not the same connection as localhost for MySQL auth! 379: 380: return mysql_test_time($param,$params[1],$params[2],$params[3],$timeout,$params[4]); 381: break; 382: 383: case "mysqlrows": 384: $ip=ip_lookup($param); 385: if ($ip=="0") return -1; // cache only - see above 386: return mysql_test_rows($param,$params[1],$params[2],$params[3],$timeout,$params[4]); 387: break; 388: 389: default: 390: if (isset($NATS)) // try and see if a test is registered 391: { 392: if (isset($NATS->Tests->QuickList[$test])) // exists 393: { 394: $NATS->Tests->Tests[$test]->Create(); 395: return $NATS->Tests->Tests[$test]->instance->DoTest($test,$param,$hostname,$timeout,$params); 396: } 397: } 398: 399: } 400: return -1; // did not run any test so untested 401: } 402: 403: function SimpleEval($test,$result) 404: { 405: global $NATS; 406: switch($test) 407: { 408: case "ping": // handles both types of simple evaluation (inbuilt ICMP and remote ping) 409: if ($result<=0) return 2; 410: return 0; 411: case "web": case "wsize": 412: if ($result<=0) return 2; 413: return 0; 414: case "tcp": 415: if ($result==1) return 0; 416: return 2; 417: case "wtime": 418: if ($result<0) return 2; 419: return 0; 420: 421: case "imap": 422: if ($result<=0) return 2; 423: return 0; 424: /* 425: case "smtp": 426: if ($result<=0) return 2; 427: return 0; 428: */ 429: case "mysql": 430: if ($result<=0) return 2; 431: return 0; 432: 433: case "mysqlrows": 434: if ($result<=0) return 2; // no rows returned or error 435: return 0; 436: 437: case "host": case "dns": 438: if ($result<=0) return 2; // no records returned or error 439: 440: case "testloop": 441: return 0; 442: case "testrand": 443: return 0; 444: 445: default: 446: if (isset($NATS)) 447: { 448: if (isset($NATS->Tests->QuickList[$test])) 449: { 450: $NATS->Tests->Tests[$test]->Create(); 451: return $NATS->Tests->Tests[$test]->instance->Evaluate($result); 452: } 453: } 454: } 455: return -1; // untested if we don't know WTF the result was 456: } 457: 458: function aText($al) 459: { 460: return oText($al); // uses function in tests.inc.php with site config support 461: /* -- depreciated 462: switch($al) 463: { 464: case -1: return "Untested"; 465: case 0: return "Passed"; 466: case 1: return "Warning"; 467: case 2: return "Failed"; 468: default: return "Unknown"; 469: } 470: */ 471: } 472: ?>