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