Home » Networking » Net_Traceroute » Bug #5665
Improved _parseResult...() using RegExp
Details
| Request #5665 | Improved _parseResult...() using RegExp |
|---|---|
| Submitted | 2005-10-12 07:25 UTC |
| From | pear dot php dot net at tjworld dot net |
| Assigned | neufeind |
| Status | Wont fix |
| Package | Net_Traceroute |
| PHP Version | 5.0.3 |
| OS | Windows/* |
| 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;
}