#24826 [Csd->Asn]: PEAR::Net Ping Bug

From: Date: Sat, 16 Aug 2003 21:10:44 +0000
Subject: #24826 [Csd->Asn]: PEAR::Net Ping Bug
References: 1  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-19907@lists.php.net to get a copy of this message
ID: 24826 Updated by: et@php.net Reported By: young at sl dot com dot ua -Status: Closed +Status: Assigned Bug Type: PEAR related Operating System: Linux PHP Version: 4.3.2 Assigned To: jan Previous Comments: ------------------------------------------------------------------------ [2003-08-16 16:04:27] Progman2002 at gmx dot de There are a lot of more bugs in the PEAR::Net_Ping package. I have tested it only on linux but i believe these bugs are in the parse-functions of all non-windows plattforms, too. Look at these var_dump-outputs of a Ping_Result object of reachable and not-reachable hosts. --- var_dump outputs --- object(net_ping_result)(11) { ["_icmp_sequence"]=> array(1) { ["0.24):"]=> string(1) "4" } ["_target_ip"]=> string(15) "Dresden.brepm.d" ["_bytes_per_request"]=> string(2) "64" ["_bytes_total"]=> int(256) ["_ttl"]=> string(6) "_seq=3" ["_raw_data"]=> array(8) { [0]=> string(58) "PING dresden.brepm.de (192.168.0.24) 56(84) bytes of data." [1]=> string(78) "64 bytes from Dresden.brepm.de (192.168.0.24): icmp_seq=1 ttl=64 time=0.056 ms" [2]=> string(78) "64 bytes from Dresden.brepm.de (192.168.0.24): icmp_seq=2 ttl=64 time=0.074 ms" [3]=> string(78) "64 bytes from Dresden.brepm.de (192.168.0.24): icmp_seq=3 ttl=64 time=0.060 ms" [4]=> string(0) "" [5]=> string(40) "--- dresden.brepm.de ping statistics ---" [6]=> string(62) "3 packets transmitted, 3 received, 0% packet loss, time 2008ms" [7]=> string(49) "rtt min/avg/max/mdev = 0.056/0.063/0.074/0.010 ms" } ["_sysname"]=> string(5) "linux" ["_round_trip"]=> array(3) { ["min"]=> string(5) "0.063" ["avg"]=> string(5) "0.074" ["max"]=> string(5) "0.010" } ["_transmitted"]=> string(1) "3" ["_received"]=> string(1) "3" ["_loss"]=> int(0) } object(net_ping_result)(11) { ["_icmp_sequence"]=> array(1) { ["on"]=> string(6) "chable" } ["_target_ip"]=> string(9) "icmp_seq=" ["_bytes_per_request"]=> string(4) "From" ["_bytes_total"]=> int(0) ["_ttl"]=> bool(false) ["_raw_data"]=> array(8) { [0]=> string(61) "PING Client-A40.brepm.de (192.168.0.40) 56(84) bytes of data." [1]=> string(76) "From Dresden.brepm.de (192.168.0.24) icmp_seq=1 Destination Host Unreachable" [2]=> string(76) "From Dresden.brepm.de (192.168.0.24) icmp_seq=2 Destination Host Unreachable" [3]=> string(76) "From Dresden.brepm.de (192.168.0.24) icmp_seq=3 Destination Host Unreachable" [4]=> string(0) "" [5]=> string(43) "--- Client-A40.brepm.de ping statistics ---" [6]=> string(75) "3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2011ms" [7]=> string(8) ", pipe 3" } ["_sysname"]=> string(5) "linux" ["_round_trip"]=> array(3) { ["min"]=> string(0) "" ["avg"]=> NULL ["max"]=> NULL } ["_transmitted"]=> string(1) "3" ["_received"]=> string(1) "0" ["_loss"]=> int(3) } --- end of var_dump outputs --- The second try with an unreachable host will produce also this output: Notice: Undefined offset: 4 in /usr/lib/php/Net/Ping.php on line 614 Notice: Undefined offset: 5 in /usr/lib/php/Net/Ping.php on line 615 Notice: Undefined offset: 6 in /usr/lib/php/Net/Ping.php on line 616 As you can see the values in the properties are almost everywhere wrong. The method checkhost() create also a lot of errors, but there is only 1 line wrong... So, I have studied the sourcecode of Ping.php and have written this patch. --- start of diff-file --- Index: Ping.php =================================================================== RCS file: /repository/pear/Net_Ping/Ping.php,v retrieving revision 1.26 diff -u -r1.26 Ping.php --- Ping.php 30 Jul 2003 20:33:55 -0000 1.26 +++ Ping.php 16 Aug 2003 20:45:40 -0000 @@ -327,6 +327,7 @@ if (PEAR::isError($res)) { return false; } + $res = $res->getRawData(); if (!preg_match_all('|\d+|', $res[3], $m) || count($m[0]) < 3) { ob_start(); var_dump($line); @@ -579,42 +580,60 @@ function _parseResultlinux() { $raw_data_len = count($this->_raw_data); - $icmp_seq_count = $raw_data_len - 4; + $icmp_seq_count = $raw_data_len - 5; /* loop from second elment to the fifths last */ - for($idx = 1; $idx < $icmp_seq_count; $idx++) - { - $parts = explode(' ', $this->_raw_data[$idx]); - $this->_icmp_sequence[substr(@$parts[4], 9, strlen(@$parts[4]))] = substr(@$parts[6], 5, strlen(@$parts[6])); - } - $this->_bytes_per_request = $parts[0]; - $this->_bytes_total = (int)$parts[0] * $icmp_seq_count; - $this->_target_ip = substr($parts[3], 0, -1); - $this->_ttl = substr($parts[5], 4, strlen($parts[3])); - - $stats = explode(',', $this->_raw_data[$raw_data_len - 2]); - $transmitted = explode(' ', $stats[0]); - $this->_transmitted = $transmitted[0]; - - $received = explode(' ', $stats[1]); - $this->_received = $received[1]; - - $loss = explode(' ', $stats[2]); - $this->_loss = (int)$loss[1]; - - $round_trip = explode('/', str_replace('=', '/', substr($this->_raw_data[$raw_data_len - 1], 0, -3))); - - /* if mdev field exists, shift input one unit left */ - if (strpos($this->_raw_data[$raw_data_len - 1], 'mdev')) { - /* do not forget the rtt field */ - $this->_round_trip['min'] = ltrim($round_trip[5]); - $this->_round_trip['avg'] = $round_trip[6]; - $this->_round_trip['max'] = $round_trip[7]; + for($idx = 1; $idx <= $icmp_seq_count; $idx++) + { + if(preg_match('#icmp_seq=(\d+) ttl=(\d+) time=(\S+)#', $this->_raw_data[$idx], $matches)) { + $this->_icmp_sequence[$matches[1]] = $matches[3]; + $this->_ttl = isset($this->_ttl)?$this->_ttl:(int)$matches[2]; + } elseif(preg_match('#^From \S+ icmp_seq=(\d+)#', $this->_raw_data[$idx], $matches)) { + //$this->_icmp_sequence[$matches[1]] = null; } else { - $this->_round_trip['min'] = ltrim($round_trip[4]); - $this->_round_trip['avg'] = $round_trip[5]; - $this->_round_trip['max'] = $round_trip[6]; + ob_start(); + var_dump($this->_raw_data[$idx]); + $rep = ob_get_contents(); + ob_end_clean(); + trigger_error("Output format seems not to be supported, please report ". + "the following to pear-dev@lists.php.net, including your ". + "version of ping:\n $rep"); } + } + if(!preg_match('#^PING \S+ \((\S+)\) (\d+)\(\d+\) bytes of data\.$#', $this->_raw_data[0], $matches)) { + ob_start(); + var_dump($this->_raw_data[0]); + $rep = ob_get_contents(); + ob_end_clean(); + trigger_error("Output format seems not to be supported, please report ". + "the following to pear-dev@lists.php.net, including your ". + "version of ping:\n $rep"); + } else { + $this->_bytes_per_request = $matches[2]+8; + $this->_target_ip = $matches[1]; + $this->_bytes_total = $icmp_seq_count * $this->_bytes_per_request; + } + + $stats = explode(',', $this->_raw_data[$raw_data_len - 2]); + $transmitted = explode(' ', $stats[0]); + $this->_transmitted = (int)$transmitted[0]; + + $received = explode(' ', $stats[1]); + $this->_received = (int)$received[1]; + + + $loss = explode(' ', (strpos('loss',$stats[2])===false)?$stats[3]:$stats[2]); + $this->_loss = (int)$loss[1]; + #the second element could be '+X errors, ' + + if($this->_received) { # valueinfos exist only if a packet is received + $round_trip_infos = explode(' ', $this->_raw_data[$raw_data_len - 1]); + $round_trip['names'] = explode('/', $round_trip_infos[1]); + $round_trip['values'] = explode('/', $round_trip_infos[3]); + for($i=0; $i < min(count($round_trip['names']),count($round_trip['values'])); $i++) { + $this->_round_trip[$round_trip['names'][$i]] = trim($round_trip['values'][$i]); + } + } } /** --- end of diff-file --- This patch will also convert some number-values to integer-values and add a "mdev" field in the _round_trip property, if it exists. Btw.: The methodes below Ping_Result::getTargetIp() are all marked as private methodes but haven't a '_' prefix. Are they all deprecated in favor of Ping_Result::getValue() or are the all public? Peter ------------------------------------------------------------------------ [2003-08-13 06:31:32] Progman2002 at gmx dot de There is still a bug: [var_dump()-snip] string(62) "2 packets transmitted, 2 received, 0% packet loss, time 1007ms" [6]=> string(55) "rtt min/avg/max/mdev = 224.307/224.317/224.327/0.010 ms" } ["_sysname"]=> string(5) "linux" ["_round_trip"]=> array(3) { ["min"]=> string(7) "224.317" ["avg"]=> string(7) "224.327" ["max"]=> string(5) "0.010" } [/snip] You can see he read out the wrong values for the round-trip-infos. There are 2 solutions. The first one is to decrease all indices by one or the second solution is this patch Index: Ping.php =================================================================== RCS file: /repository/pear/Net_Ping/Ping.php,v retrieving revision 1.26 diff -u -r1.26 Ping.php --- Ping.php 30 Jul 2003 20:33:55 -0000 1.26 +++ Ping.php 13 Aug 2003 11:13:41 -0000 @@ -602,18 +602,11 @@ $loss = explode(' ', $stats[2]); $this->_loss = (int)$loss[1]; - $round_trip = explode('/', str_replace('=', '/', substr($this->_raw_data[$raw_data_len - 1], 0, -3))); - - /* if mdev field exists, shift input one unit left */ - if (strpos($this->_raw_data[$raw_data_len - 1], 'mdev')) { - /* do not forget the rtt field */ - $this->_round_trip['min'] = ltrim($round_trip[5]); - $this->_round_trip['avg'] = $round_trip[6]; - $this->_round_trip['max'] = $round_trip[7]; - } else { - $this->_round_trip['min'] = ltrim($round_trip[4]); - $this->_round_trip['avg'] = $round_trip[5]; - $this->_round_trip['max'] = $round_trip[6]; + $round_trip_infos = explode(' ', $this->_raw_data[$raw_data_len - 1]); + $round_trip['names'] = explode('/', $round_trip_infos[1]); + $round_trip['values'] = explode('/', $round_trip_infos[3]); + for($i=0; $i < min(count($round_trip['names']), count($round_trip['values'])); $i++) { + $this->_round_trip[$round_trip['names'][$i]] = $round_trip['values'][$i]; } } The patch will also add a "mdev" index, if the ping-command produce it ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/24826 -- Edit this bug report at http://bugs.php.net/?id=24826&edit=1

« previous php.pear.dev (#19907) next »