File:
1.08.1a/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: function bin_str_dump($s,$count=0)
111: {
112: if ($count==0) $count=strlen($s);
113: for($a=0; $a<$count; $a++)
114: {
115: $c=$s[$a];
116: printf("%d: 0x%02x %d %c\n",$a,$c,$c,$c);
117: }
118: }
119:
120:
121:
122:
123: function icmpChecksum($data)
124: {
125: if (strlen($data)%2)
126: $data .= "\x00";
127:
128: $bit = unpack('n*', $data);
129: $sum = array_sum($bit);
130:
131: while ($sum >> 16)
132: $sum = ($sum >> 16) + ($sum & 0xffff);
133:
134: return pack('n*', ~$sum);
135: }
136:
137: function PingTest($host,$ctimeout=-1)
138: {
139: global $NATS;
140: $FreeNATS_Timer=new TFNTimer();
141: // Make Package
142: $type= "\x08";
143: $code= "\x00";
144: $checksum= "\x00\x00";
145: $identifier = "\x00\x00";
146: $seqNumber = "\x00\x00";
147: $data= "FreeNATS";
148: $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
149: $checksum = icmpChecksum($package); // Calculate the checksum
150: $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
151:
152: // Return s or ms(s*1000)
153: $returnsecs=true;
154: if (isset($NATS))
155: {
156: if ($NATS->Cfg->Get("test.icmp.returnms",0)==1) $returnsecs=false;
157: }
158:
159: // Timeout Values
160: if (isset($NATS)) $timeout=$NATS->Cfg->Get("test.icmp.timeout",10);
161: else $timeout=10;
162: if ($ctimeout>0) $timeout=$ctimeout; // use custom timeout if passed
163: if ($timeout<=0) $timeout=10; // catch-all for defaults bug
164:
165: // Create Socket
166: $socket = socket_create(AF_INET, SOCK_RAW, 1); // @
167: //or die(socket_strerror(socket_last_error()));
168: if (!$socket) return 0;
169:
170: // Set Non-Blocking
171: socket_set_nonblock($socket); // @
172:
173: // Connect Socket
174: $sconn=socket_connect($socket, $host, null); // @
175: if (!$sconn) return 0;
176:
177: // Package Size
178: $package_size = 8+strlen($data);
179:
180: // Send Data
181: socket_send($socket, $package, $package_size, 0); // @
182:
183: // Start Timer
184: $FreeNATS_Timer->Start();
185: $startTime = microtime(true); // need this for the looping section
186:
187:
188: // Read Data
189: $keepon=true;
190:
191: while( (!($echo_reply=socket_read($socket, 2))) && $keepon) // @socket_read
192: { // basically just kill time
193: // consider putting some sort of sleepy thing here to lower load but would f* with figures!
194:
195: if ( (microtime(true) - $startTime) > $timeout )
196: $keepon=false;
197: }
198:
199: if ($keepon) // didn't time out - read data
200: {
201: $elapsed=$FreeNATS_Timer->Stop();
202:
203: // Examing Received Data
204: // Type, Code, Checksum 2, id 2, seq 2, data X
205: $ret_type=$echo_reply[0];
206: $ret_code=$echo_reply[1];
207: //printf("%02x %02x ",$ret_type,$ret_code);
208: /*
209: $ret_checksum=substr($echo_reply,2,2);
210: $ret_id=substr($echo_reply,4,2);
211: $ret_seq=substr($echo_reply,6,2);
212: $ret_data=substr($echo_reply,8,strlen($echo_reply)-7);
213: */
214: /*
215: printf("\n%02x %02x %04x %x %04x %s ",$ret_type,$ret_code,$ret_checksum,$ret_id,$ret_seq,$ret_data);
216: printf("\n%02x %02x %04x %x %04x %s ",$type,$code,$checksum,$identifier,$seqNumber,$data);
217: echo "\n";
218: bin_str_dump($package,$package_size);
219: bin_str_dump($echo_reply);
220: */
221: if ($returnsecs) $elapsed=round($elapsed,4);
222: else $elapsed=round( ($elapsed*1000),4 );
223: socket_close($socket); // @
224: // $ret=round(microtime(true) - $startTime, 4); -- old method
225: if ($elapsed<=0) $elapsed="0.0001"; // safety catch-all
226:
227: if ($ret_type==0) // valid icmp echo_reply message
228: return $elapsed;
229: else // icmp error message
230: return -1;
231: /*
232: if ($ret==0) return "0.0001";
233: else
234: {
235: if ($ret<=0) return "0.0001";
236: else return $ret;
237: }
238: */
239: }
240:
241: // Socket timed out
242: socket_close($socket); // @
243: return 0;
244: }
245:
246: function WebTest($url,$timeout=-1)
247: {
248: global $NATS;
249: if ($timeout<=0) // use NATS or env
250: {
251: if (isset($NATS))
252: {
253: $nto=$NATS->Cfg->Get("test.http.timeout",-1);
254: if ($nto>0) $timeout=$nto; // use NATS timeout
255: }
256: }
257: if ($timeout>0) // use the set timeout
258: $oldtimeout=ini_set("default_socket_timeout",$timeout);
259:
260: if (function_exists("curl_getinfo")) // use CURL if present
261: {
262: $ch=curl_init();
263: curl_setopt($ch,CURLOPT_URL,$url);
264: curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
265: curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
266: curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
267: curl_setopt($ch,CURLOPT_HEADER,1);
268: if ($timeout>0) curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
269: if ($timeout>0) curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);
270: if (!$output=curl_exec($ch))
271: {
272: $ctr=-1; // failed
273: }
274: else $ctr=round(curl_getinfo($ch,CURLINFO_SIZE_DOWNLOAD)/1024,2);
275: curl_close($ch);
276:
277: if ($ctr==0) $ctr="0.0001";
278:
279: }
280: else
281: { // no CURL - use fopen()
282: $oldagent=ini_set("user_agent","MSIE 4\.0b2;"); // MSIE 4.0b2 is HTTP/1.0 only just like fopen http wrapper
283: $fp=@fopen($url,"r");
284: if ($fp<=0)
285: {
286: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout);
287: ini_set("user_agent",$oldagent);
288: return -1;
289: }
290: $ctr=0;
291: while ($body=@fgets($fp,1024)) $ctr+=sizeof($body);
292: @fclose($fp);
293: ini_set("user_agent",$oldagent);
294: }
295:
296:
297:
298: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout);
299: return $ctr;
300: }
301:
302: function DoTest($test,$param,$hostname="",$timeout=-1,$params=0,$nodeid="")
303: {
304: global $NATS;
305: if (!is_array($params))
306: {
307: $params=array();
308: for ($a=0; $a<10; $a++) $params[$a]="";
309: }
310:
311: switch ($test)
312: {
313: case "web": case "wsize":
314: // Don't bother with pre-resolution as size only
315: return WebTest($param,$timeout);
316: break;
317: /* -- modularised
318: case "tcp": // nb TCP does not support timeouts currently
319: $ip=ip_lookup($hostname);
320: if ($ip=="0") return 0;
321: $fp=@fsockopen($ip,$param);
322: if ($fp<=0) return 0;
323: @fclose($fp);
324: return 1;
325: break;
326: */
327: case "wtime":
328: $timer=new TFNTimer();
329: // Do a pre-lookup
330: $ip=url_lookup($param);
331: if ($ip=="0") return -1; // dns lookup failed
332: $timer->Start();
333: $r=WebTest($param,$timeout);
334: $elapsedTime=$timer->Stop();
335: $elapsedTime=round($elapsedTime,4);
336: if ($r<0) return -1; // open failed
337: if ($r==0) return -2; // no chars shown as returned
338: if ($elapsedTime<=0) return 0.0001;
339: return $elapsedTime;
340: break;
341:
342: case "host":
343: $timer=new TFNTimer();
344: if (preg_match("/[a-zA-Z]/",$param)>0) $is_ip=false;
345: else $is_ip=true;
346:
347: $timer->Start();
348: if ($is_ip) $result=gethostbyaddr($param);
349: else $result=gethostbyname($param);
350: $elapsedTime=$timer->Stop();
351:
352: if ($result==$param) // lookup failed
353: return -1;
354:
355: if ($result=="") // lookup failed
356: return -1;
357:
358: $elapsedTime=round($elapsedTime,4);
359: if ($elapsedTime<=0) return 0.0001;
360: return $elapsedTime;
361: break;
362:
363: case "testloop":
364: return $param;
365: break;
366:
367: case "testrand":
368: mt_srand(microtime()*1000000);
369: if ( ($param=="") || ($param==0) ) $param=100;
370: return mt_rand(0,$param);
371: break;
372:
373: case "ping":
374: return PingTest($param,$timeout);
375: break;
376:
377: default:
378: if (isset($NATS)) // try and see if a test is registered
379: {
380: if (isset($NATS->Tests->QuickList[$test])) // exists
381: {
382: $NATS->Tests->Tests[$test]->Create();
383: return $NATS->Tests->Tests[$test]->instance->DoTest($test,$param,$hostname,$timeout,$params);
384: }
385: }
386:
387: }
388: return -1; // did not run any test so untested
389: }
390:
391: function SimpleEval($test,$result)
392: {
393: global $NATS;
394: switch($test)
395: {
396: case "ping": // handles both types of simple evaluation (inbuilt ICMP and remote ping)
397: if ($result<=0) return 2;
398: return 0;
399: case "web": case "wsize":
400: if ($result<=0) return 2;
401: return 0;
402: /*
403: case "tcp":
404: if ($result==1) return 0;
405: return 2;
406: */
407: case "wtime":
408: if ($result<0) return 2;
409: return 0;
410: /*
411: case "mysql":
412: if ($result<=0) return 2;
413: return 0;
414:
415: case "mysqlrows":
416: if ($result<=0) return 2; // no rows returned or error
417: return 0;
418: */
419: case "host": case "dns":
420: if ($result<=0) return 2; // no records returned or error
421:
422: case "testloop":
423: return 0;
424: case "testrand":
425: return 0;
426:
427: default:
428: if (isset($NATS))
429: {
430: if (isset($NATS->Tests->QuickList[$test]))
431: {
432: $NATS->Tests->Tests[$test]->Create();
433: return $NATS->Tests->Tests[$test]->instance->Evaluate($result);
434: }
435: }
436: }
437: return -1; // untested if we don't know WTF the result was
438: }
439:
440: function aText($al)
441: {
442: return oText($al); // uses function in tests.inc.php with site config support
443: /* -- depreciated
444: switch($al)
445: {
446: case -1: return "Untested";
447: case 0: return "Passed";
448: case 1: return "Warning";
449: case 2: return "Failed";
450: default: return "Unknown";
451: }
452: */
453: }
454: ?>