php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #24826 PEAR::Net Ping Bug
Submitted: 2003-07-27 03:13 UTC Modified: 2004-03-15 08:37 UTC
Votes:3
Avg. Score:4.0 ± 0.8
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:1 (33.3%)
From: young at sl dot com dot ua Assigned: jan (profile)
Status: No Feedback Package: PEAR related
PHP Version: 4.3.2 OS: Linux
Private report: No CVE-ID: None
 [2003-07-27 03:13 UTC] young at sl dot com dot ua
Description:
------------
Result object: 
----------------------------------------------------------- 

net_ping_result Object
(
[_icmp_sequence] => Array
(
[.166):] => 1
)

[_target_ip] => www.example.co
[_bytes_per_request] => 64
[_bytes_total] => 704
[_ttl] => _seq=10
[_raw_data] => Array
(
[0] => PING example.com (192.0.34.166) 56(84) bytes of data.
[1] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=1 ttl=41 time=248 ms
[2] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=2 ttl=41 time=231 ms
[3] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=3 ttl=41 time=231 ms
[4] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=4 ttl=41 time=237 ms
[5] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=5 ttl=41 time=238 ms
[6] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=6 ttl=41 time=227 ms
[7] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=7 ttl=41 time=242 ms
[8] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=8 ttl=41 time=249 ms
[9] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=9 ttl=41 time=242 ms
[10] => 64 bytes from www.example.com (192.0.34.166): icmp_seq=10 ttl=41 time=229 ms
[11] => 
[12] => --- example.com ping statistics ---
[13] => 10 packets transmitted, 10 received, 0% packet loss, time 9098ms
[14] => rtt min/avg/max/mdev = 227.624/237.838/249.118/7.252 ms
)

[_sysname] => linux
[_round_trip] => Array
(
[min] => mdev 
[avg] => 227.624
[max] => 237.838
)

[_transmitted] => 10
[_received] => 10
[_loss] => 0
)
 

-----------------------------------------------------------
Error here:  
-----------------------------------------------------------
 

[min] => mdev 
[avg] => 227.624
[max] => 237.838
 

----------------------------------------------------------- 





Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-07-27 04:29 UTC] nicos@php.net
Here is the patch...

Is it ok?


cvs server: Diffing .
Index: Ping.php
===================================================================
RCS file: /repository/pear/Net_Ping/Ping.php,v
retrieving revision 1.25
diff -u -u -r1.25 Ping.php
--- Ping.php    14 Jul 2003 20:26:55 -0000      1.25
+++ Ping.php    27 Jul 2003 09:28:27 -0000
@@ -606,13 +606,14 @@

             /* 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];
-            } else {
-                $this->_round_trip['min']    = ltrim($round_trip[3]);
-                $this->_round_trip['avg']    = $round_trip[4];
-                $this->_round_trip['max']    = $round_trip[5];
             }
     }


 [2003-07-27 07:53 UTC] jan@php.net
Hi,
I can commit the patch, but I can't test it due to a 
lack of linux around here. Can you please make sure it 
works AND doesn't brake anything else?

Jan
 [2003-07-27 09:30 UTC] nicos@php.net
Lack of linux! What! Jan! 

:-)

I can commit too. It should work fine with every OS, but I'm not sure thats why I wait for feedback of the maintainer...
 [2003-07-27 10:44 UTC] mj@php.net
The patch looks fine for me and it obviously does not break anything. Can any of guys take care of committing it and rolling a new release afterwards?
 [2003-07-30 15:33 UTC] nicos@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.

.
 [2003-08-13 06:31 UTC] 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
 [2003-08-16 16:04 UTC] 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-18 08:48 UTC] jan@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 [2003-08-20 03:32 UTC] young at sl dot com dot ua
-----------
  [14] => rtt min/avg/max/mdev = 250.889/298.179/397.075/41.305 ms
        )

    [_sysname] => linux
    [_round_trip] => Array
        (
            [min] => 298.179
            [avg] => 397.075
            [max] => 41.305
        )

-----------------
I get it again from  CVS.
There are another error.

min/avg/max/mdev = rtt min/avg/max/mdev = 250.889/298.179/397.075/41.305 ms
Now: 
            [min] => 298.179
            [avg] => 397.075
            [max] => 41.305
Need:
            [min] => 250.889
            [avg] => 298.179
            [max] => 397.075
 [2003-08-20 05:47 UTC] young at sl dot com dot ua
why there is no parametr -i in Linux options ?!!

       -i interval
              Wait interval seconds between sending each packet.  The default is to wait for one  second  between
              each packet normally, or not to wait in flood mode.
 [2003-08-20 05:58 UTC] young at sl dot com dot ua
For repair this bug need to change:
From:
---------
            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];
            }
------------------
To:
            if (strpos($this->_raw_data[$raw_data_len - 1], 'mdev')) {
		/* do not forget the rtt field */
                $this->_round_trip['min']    = ltrim($round_trip[4]);
                $this->_round_trip['avg']    = $round_trip[5];
                $this->_round_trip['max']    = $round_trip[6];
            } else {
                $this->_round_trip['min']    = ltrim($round_trip[4]);
                $this->_round_trip['avg']    = $round_trip[5];
                $this->_round_trip['max']    = $round_trip[6];
            }
------------------
 [2003-08-20 06:18 UTC] neufeind@php.net
Hmm, the code mentioned above seems quite strange - since it has the same code in both parts of the if-tree :-))

Don't the patches from Progman2002 work fine? Didn't have time to try but had a look at the source. And his ideas seem to make the parser more flexible. They should also catch the recent problems correctly.

Might somebody of the Net_Ping-team please have a look? Do they maybe have sample-outputs from various linux-systems at hand - or is the output the same on all variants / versions?
 [2004-03-07 11:20 UTC] mj@php.net
There have been a number of new releases for Net_Ping recently. Can you please the latest and report back, if the problem persists?
 [2004-03-07 11:27 UTC] kennyt@php.net
Oops, probably my fault. :-)
 [2004-03-15 08:37 UTC] sniper@php.net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Oct 04 08:01:28 2024 UTC