#24826 [Csd->Asn]: PEAR::Net Ping Bug
| From: | et@php.net | 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