Magellan Linux

Annotation of /alx-src/tags/alx-web-0_7_0_20171218_1/include/ppping.inc.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11135 - (hide annotations) (download)
Mon Dec 18 12:03:27 2017 UTC (6 years, 5 months ago) by niro
File size: 9495 byte(s)
tagged 'alx-web-0_7_0_20171218_1'
1 niro 2195 <?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     ?>