PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Networking » Net_Traceroute » Bug #5665

Improved _parseResult...() using RegExp

Details

Request #5665Improved _parseResult...() using RegExp
Submitted2005-10-12 07:25 UTC
Frompear dot php dot net at tjworld dot net
Assignedneufeind
StatusWont fix
PackageNet_Traceroute
PHP Version5.0.3
OSWindows/*
Roadmaps(Not assigned)

Comments

[2005-10-12 07:25 UTC] pear dot php dot net at tjworld dot net

Description:
------------
I had some problems running this on Windows 2003 Server, experiencing the bugs already mentioned here and more.

The problems are in the way the Class parses the output of the "traceroute" commands - its inflexible and can't cope well with change.

Debugging the logic of the functions is also problematic, so I decided to write a replacement function that uses regular expressions.

Here's the result. You can paste this into the package's "Traceroute.php". **MAKE SURE** to remove the line-feeds that have been inserted by the HTML form here - all statements are on one line unless inside a {...} block!

If you find your particular "traceroute" confuses the _parse function it is easy to tinker with the regular expressions.

To allow the new function to be used the existing code, that calls the appropriate parse function, needs to be edited:

function _parseResult()
{
- $this->{'_parseResult' . $this->_sysname}();
+ $this->_parseResultRegExp();

}

---- Add to Traceroute.php -----------
/**
* parses generic traceroute command output using Regular Expressions
* written by TJ <hacker@tjworld.net> 12 October, 2005
* http://tjworld.net/
*
* @ access private
*/
function _parseResultRegExp() {
// define RegExp for each type of response line
$reTraceTo = '/^\s*(\w+\b)*.*to\s([\w\.\-\_]+)*\s\[*(\d+\.\d+\.\d+\.\d+)\]*/';
$reHopCount = '/^.*maximum of\s(\d+)\shops/i';
$reHop = '/\s*(\d+)\s+(?:\s|\<)(\d+|\*)\s.*(?:\s|\<)(\d+|\*)\s.*(?:\s|\<)(\d+|\*)*\s.*\s([\w\.\-\_]+)*\s\[*(\d+\.\d+\.\d+\.\d+)\]*/';
$reHopFailed = '/^\s*(\d+)\s+(\d+|\*)\s.+\s(\d+|\*)\s.+\s(\d+|\*)*/';
$reReqTimedOut = '/^\s+\*\s+\*\s+\*\s+Request\btimed\bout\b/i';
$reDestHostUnreachable = '/^\s*(\d+).*\s([\w\.\-\_]+)*\s\[*(\d+\.\d+\.\d+\.\d+)\]*/s+(?:\w+)\:\s+Destination\bhost\bunreachable.*/i';
$reTraceComplete = '/Trace complete/i';

$hops = array();
$data = $this->_raw_data;
for($row=0; $row < count($this->_raw_data); $row++) {
if(!empty($this->_raw_data[$row])) {
$match = array();

$target = preg_match($reTraceTo, $this->_raw_data[$row], $match); // Destination, trace starting
if($target) $this->_target_ip = $match[3];

$target = preg_match($reHopCount, $this->_raw_data[$row], $match); // number of hops (TTL)
if($target) $this->_ttl = $match[1];

$reqTimedOut = preg_match($reReqTimedOut, $this->_raw_data[$row], $match); // Request timed out

$target = preg_match($reHop, $this->_raw_data[$row], $match); // Request received
if($target || $reqTimedOut) { // two types of hop-response handled in one code block
$responsetimes = array(); // add the min/max/avg response times
$responsetimes[] = (float) ($reqTimedOut ? -1 : ($match[2] == "*" ? -1 : $match[2]));
$responsetimes[] = (float) ($reqTimedOut ? -1 : ($match[3] == "*" ? -1 : $match[3]));
$responsetimes[] = (float) ($reqTimedOut ? -1 : ($match[4] == "*" ? -1 : $match[4]));
$hop = array();
$hop['responsetimes'] = $responsetimes;
$hop['machine'] = $reqTimedOut ? "" : $match[5];
$hop['ip'] = $reqTimedOut ? "" : $match[6];
$hops[] = $hop; // add the hop to the array
}
$target = preg_match($reTraceComplete, $this->_raw_data[$row], $match);
if($target); // Trace finished
}
// else "empty"
}
$this->_hops = $hops;
}