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