File:
1.00.5a/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: ?>