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