File: 0.04.14b/server/base/tests.inc.php (View as HTML)

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