Magellan Linux

Contents of /alx-src/branches/alx-web-070/include/ppping.inc.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8531 - (show annotations) (download)
Mon Feb 8 10:37:04 2016 UTC (8 years, 2 months ago) by niro
File size: 9495 byte(s)
-fixed file permissions via propset
1 <?php
2 /* -------------------------------------------------------------
3 This file is part of PurplePixie Ping (PPPing)
4
5 PPPing is (C) Copyright 2010 PurplePixie Systems
6
7 PPPing 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 PPPing 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 PPPing. If not, see www.gnu.org/licenses
19
20 For more information see www.purplepixie.org/phpping
21 -------------------------------------------------------------- */
22
23 /**
24 * PPPing PHP Ping Utility
25 * @package PPPing PHP Ping Utility
26 * @author David Cutting
27 * @version 0.01
28 **/
29
30 /**
31 * Main PPPing Class
32 * @package PPPing PHP Ping Utility
33 **/
34 class PPPing
35 {
36 /**
37 * Time-to-Live for IP Packet (DO NOT USE)
38 *
39 * -1 Uses system default (usually 64). Please note that this is currently
40 * not functional.
41 **/
42 var $ttl=-1;
43
44 /**
45 * Hostname to ping (resolvable host or IP address)
46 **/
47 var $hostname="";
48
49 /**
50 * Identifier - will fill with random content (16 bits)
51 **/
52 var $identity=0;
53
54 /**
55 * Sequence number in decimal (16 bits)
56 **/
57 var $sequence=0;
58
59 /**
60 * Timeout in seconds - maximum wait for a response before timeout
61 **/
62 var $timeout=10;
63
64 /**
65 * Timer start seconds
66 **/
67 var $timer_start_sec=0;
68
69 /**
70 * Timer start mseconds
71 **/
72 var $timer_start_msec=0;
73
74 /**
75 * Data package for the ping
76 **/
77 var $data_package = "PPPing";
78
79 /**
80 * Debug - prints output to the screen
81 **/
82 var $debug=false;
83
84 /**
85 * Holds information on last result
86 **/
87 var $Last = array();
88
89 /**
90 * Clears last data
91 **/
92 function clearLast()
93 {
94 $this->last = array(
95 "set" => false,
96 "result" => 0,
97 "ttl" => 0,
98 "hops" => 0,
99 "source" => "",
100 "destination" => "" );
101 }
102 /**
103 * Get a padded hex identifier
104 **/
105 function getIdentity()
106 {
107 if ( (is_numeric($this->identity)) && ($this->identity>=0) && ($this->identity<65535) )
108 $id=$this->identity;
109 else $id=0;
110
111 $id=dechex($id);
112 $id=str_pad($id,4,"0",STR_PAD_LEFT);
113 $id=pack("H*",$id);
114
115 return $id;
116 }
117
118 /**
119 * Get a padded hex sequence
120 **/
121 function getSequence()
122 {
123 if ( (is_numeric($this->sequence)) && ($this->sequence>=0) && ($this->sequence<65535) )
124 $seq=$this->sequence;
125 else $seq=0;
126 $seq=dechex($seq);
127 $seq=str_pad($seq,4,"0",STR_PAD_LEFT);
128 $seq=pack("H*",$seq);
129
130 return $seq;
131 }
132
133 /**
134 * Returns a hex string of the binary data for debug purposes
135 **/
136 function getHex($data)
137 {
138 $parts=unpack("H*",$data);
139 return $parts[1];
140 }
141
142 /**
143 * Randomise identity and/or sequence within 16 bit parameters
144 **/
145 function Randomise($identity=true,$sequence=false)
146 {
147 mt_srand(microtime()*1000000);
148 if ($identity) $this->identity=mt_rand(0,65534);
149 if ($sequence) $this->sequence=mt_rand(0,65534);
150 }
151
152 /**
153 * Start timer (reset values)
154 **/
155 function startTimer()
156 {
157 $now=microtime();
158 $timearray=explode(" ",$now);
159 $this->timer_start_sec=$timearray[1];
160 $this->timer_start_msec=$timearray[0];
161 }
162
163 /**
164 * Stop timer (return result)
165 **/
166 function stopTimer()
167 {
168 $now=microtime();
169 $timearray=explode(" ",$now);
170
171 $finish_secs=$timearray[1];
172 $finish_msecs=$timearray[0];
173
174 $elapsed_seconds = $finish_secs - $this->timer_start_sec;
175 $elapsed_time = $elapsed_seconds + $finish_msecs - $this->timer_start_msec;
176
177 $elapsed_ms = $elapsed_time * 1000;
178
179 $elapsed_ms = round($elapsed_ms,3);
180
181 return $elapsed_ms;
182 }
183
184
185 /**
186 * Constructor - randomises ID
187 **/
188 function PPPing()
189 {
190 $this->Randomise();
191 }
192
193 /**
194 * Returns a dotted quad from hex format IPv4 address
195 **/
196 function ipAddress($hexip)
197 {
198 $quad="";
199 for($a=0; $a<=6; $a+=2)
200 {
201 $portion=substr($hexip,$a,2);
202 $decimal=hexdec($portion);
203 if ($quad!="") $quad.=".";
204 $quad.=$decimal;
205 }
206 return $quad;
207 }
208
209 /**
210 * Generate an ICMP checksum
211 **/
212 function Checksum($data)
213 {
214 if (strlen($data)%2)
215 $data .= "\x00";
216
217 $bit = unpack('n*', $data);
218 $sum = array_sum($bit);
219
220 while ($sum >> 16)
221 $sum = ($sum >> 16) + ($sum & 0xffff);
222
223 return pack('n*', ~$sum);
224 }
225
226 /**
227 * Do a ping of the set hostname
228 *
229 * @return float
230 * Returns a negative number of failure which can be turned into text with
231 * the strError method. A positive number is a response in milliseconds (ms)
232 **/
233 function Ping()
234 {
235 $this->clearLast();
236 $type = "\x08"; // icmp echo
237 $code = "\x00";
238 $checksum = "\x00\x00"; // initial
239 $identifier = $this->getIdentity();
240 $dec_identity = $this->identity;
241 //$identifier = "\x00\x00";
242 //$seqNumber = "\x00\x00";
243 $seqNumber = $this->getSequence();
244 $dec_sequence = $this->sequence;
245 $data = $this->data_package;
246 $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
247 $checksum = $this->Checksum($package); // proper checksum
248 $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
249
250 $ip_protocol_code = getprotobyname("ip");
251 $ip_ttl_code = 7;
252
253 // Lookup hostname
254 $ips=str_replace(".","",$this->hostname);
255 if (!is_numeric($ips))
256 {
257 $host=gethostbyname($this->hostname);
258 if ($host==$this->hostname) return -5;
259 }
260 else $host=$this->hostname;
261
262 // Create Socket
263 $socket = socket_create(AF_INET, SOCK_RAW, 1); // @
264 //or die(socket_strerror(socket_last_error()));
265 if (!$socket) return -3;
266
267 // Set Non-Blocking
268 socket_set_nonblock($socket); // @
269
270 $socket_ttl = socket_get_option($socket,$ip_protocol_code,$ip_ttl_code);
271
272 //for ($a=0; $a<64; $a++)
273 // echo $a." - ".@socket_get_option($socket,$ip_protocol_code,$a)."\n";
274
275 if ($this->ttl>0)
276 {
277 socket_set_option($socket,$ip_protocol_code,$ip_ttl_code,128);
278 $socket_ttl = socket_get_option($socket,$ip_protocol_code,$ip_ttl_code);
279 //socket_set_option($socket,Socket::IPPROTO_IP,Socket::IP_TTL,128);
280 //$socket_ttl = socket_get_option($socket,Socket::IPPROTO_IP,Socket::IP_TTL);
281
282 }
283 else $socket_ttl = 64; // standard TTL
284
285
286 // Connect Socket
287 $sconn=socket_connect($socket, $host, null); // @
288 if (!$sconn) return 0;
289
290 // Package Size
291 //$package_size = 8+strlen($data);
292 $package_size = strlen($package);
293
294 // Send Data
295 socket_send($socket, $package, $package_size, 0); // @
296
297 // Start Timer
298 $this->startTimer();
299 $startTime = microtime(true); // need this for the looping section
300
301
302 // Read Data
303 $keepon=true;
304
305 while( (false===($echo_reply=socket_read($socket, 255))) && $keepon) // @socket_read
306 {
307
308 if ( (microtime(true) - $startTime) > $this->timeout )
309 $keepon=false;
310
311 }
312
313
314 if ($keepon) // didn't time out - read data
315 {
316 $elapsed=$this->stopTimer();
317
318 socket_close($socket); // @
319
320 if ( $echo_reply === false ) return -4;
321 else if (strlen($echo_reply)<2) return -2;
322
323 $rx_parts = unpack("C*",$echo_reply);
324 $tx_parts = unpack("C*",$package);
325 $ipheader="";
326 $ipheader_hex="";
327
328 if ($rx_parts[1] == 0x45) // IP Header Information
329 {
330 $ipheader=substr($echo_reply,0,20);
331 $ipheader_hex = $this->getHex($ipheader);
332 $echo_reply=substr($echo_reply,20);
333 $rx_parts = unpack("C*",$echo_reply);
334 }
335
336 if ($this->debug)
337 {
338 echo "\n";
339 echo " TyCoChksIdenSequData\n";
340 echo "TX: ".$this->getHex($package)."\n";
341 echo "RX: ".$this->getHex($echo_reply)."\n";
342 if ($ipheader!="") echo "HR: ".$ipheader_hex."\n";
343 }
344
345 $echo_reply_hex = $this->getHex($echo_reply);
346 $reply_type = $rx_parts[1];
347 $reply_code = $rx_parts[2];
348 $reply_identity = hexdec(substr($echo_reply_hex,8,4));
349 $reply_sequence = hexdec(substr($echo_reply_hex,12,4));
350
351 $match=true;
352 if ($ipheader!="")
353 {
354 $source=substr($ipheader_hex,24,8);
355 $dest=substr($ipheader_hex,32,8);
356 $ttl=hexdec(substr($ipheader_hex,16,2));
357 if ($this->debug) echo $this->ipAddress($source)." => ".$this->ipAddress($dest)." | ttl: ".$ttl."\n";
358 if ($source==$dest) $match=true;
359 else $match=false;
360
361 $this->last["set"]=true;
362 $this->last["source"]=$this->ipAddress($source);
363 $this->last["destination"]=$this->ipAddress($dest);
364 $this->last["ttl"]=$ttl;
365 $this->last["hops"]=$socket_ttl - $ttl;
366
367
368 }
369
370 if ( (($rx_parts[1]==0) || (($rx_parts[1]==8)&&($match))) && ($rx_parts[2]==0) )
371 { // is echo_reply (0) or is echo_request (8) AND match (from same host)
372 // and has code of 0
373 // valid response
374 if ($reply_identity != $dec_identity) return -8; // ID mismatch
375 else if ($reply_sequence != $dec_sequence) return -7; // sequence mismatch
376 else
377 {
378 $this->last["result"]=$elapsed;
379 return $elapsed;
380 }
381 }
382 else
383 { // ICMP Error
384 return -9;
385 }
386
387 }
388 socket_close($socket); // @
389 return -1; // timeout
390 }
391
392 /**
393 * Returns textual error for code
394 **/
395 function strError($code)
396 {
397 switch($code)
398 {
399 case -1: return "Timed Out"; break;
400 case -2: return "Reply Too Short"; break;
401 case -3: return "Failed to Open Socket"; break;
402 case -4: return "Invalid (false) Response"; break;
403 case -5: return "Hostname Lookup Failed"; break;
404 case -7: return "Sequence Mismatch"; break;
405 case -8: return "Identity Mismatch"; break;
406 case -9: return "ICMP Generic Error"; break;
407
408 default: return "Unknown Error"; break;
409 }
410 }
411
412
413 }
414
415 ?>