Agent-TCLI-Package-Net
view release on metacpan or search on metacpan
lib/Agent/TCLI/Package/Net/Traceroute.pm view on Meta::CPAN
$kernel->post('tracer' => 'shutdown');
$kernel->alarm_remove_all();
return($self->name.":_shutdown complete ");
}
=item trace
This POE event handler processes the trace command
=cut
sub trace {
my ($kernel, $self, $session, $request, ) =
@_[KERNEL, OBJECT, SESSION, ARG0, ];
my $txt = '';
my $param;
my $command = $request->command->[0];
my $cmd = $self->commands->{'traceroute'};
return unless ( $param = $cmd->Validate($kernel, $request, $self) );
$self->Verbose("trace: param dump",4,$param);
my $target;
if ( defined( $param->{'target'} ) && ref( $param->{'target'} ) eq 'NetAddr::IP' )
{
$target = $param->{'target'}
}
else
{
$self->Verbose('trace: target not specified ');
$request->Respond($kernel, "Target must be defined in command line or in default settings.",412);
return;
}
if ( $param->{'target'}->version() == 6 )
{
$request->Respond($kernel, "IPv6 currently not supported.",400);
return;
}
if ( $param->{'target'}->masklen() != 32 )
{
$request->Respond($kernel, "Address blocks not supported.",400);
return;
}
$self->Verbose("trace: target(".$param->{'target'}.") \n",2);
# only one traceroute per host at a time
if (defined($self->requests->{$param->{'target'}->addr}{'request'} ))
{
$self->Verbose('trace: trace in progress for target'.$param->{'target'}->addr);
$request->Respond($kernel,"trace already in progress for ".$param->{'target'}->addr,409);
return;
}
# $txt will be populated if there was an error.
if ($txt)
{
$self->Verbose('trace: argument error '.$txt);
$request->Respond($kernel, $txt,412);
return;
}
my @trace_options;
push(@trace_options,
'MaxTTL' => $param->{'max_ttl'},
'FirstHop' => $param->{'firsthop'},
'Timeout' => $param->{'timeout'},
'QueryTimeout' => $param->{'querytimeout'},
'Queries' => $param->{'queries'},
'BasePort' => $param->{'baseport'},
);
push(@trace_options,'PerHopPostBack','TraceHopResponse')
if $param->{'trace_verbose'};
push(@trace_options,'UseICMP',1)
if ($param->{'useicmp'} || ($^O eq "MSWin32"));
$self->requests->{$param->{'target'}->addr}{'request'} = $request;
$self->Verbose(" target ".$param->{'target'}->addr." options ",
1,\@trace_options );
# execution
$kernel->post(
"tracer", # Post request to 'tracer' component
"traceroute", # Ask it to traceroute to an address
"TraceResponse", # Post answers to 'trace_response'
$param->{'target'}->addr, # This is the host to traceroute to
\@trace_options
# [
# PerHopPostback => 'TraceHopResponse',
# Queries => 5, # Override the global queries parameter
# MaxTTL => 30, # Override the global MaxTTL parameter
# Callback => [ $args ], # Data to send back with postback event
# ]
);
return($self->name.":trace done");
}
=item TraceResponse
This POE event handler processes the return data from the PoCo::Client::Traceroute.
=cut
sub TraceResponse {
my ($kernel, $self, $trace, $reply) =
@_[KERNEL, OBJECT, ARG0, ARG1];
my ($destination, $options, $callback) = @$trace;
my ($hops, $data, $error) = @$reply;
$self->Verbose("TraceResponse: destination(".$destination.")");
my ($txt,$code);
my $request = delete($self->requests->{$destination}{'request'});
# define code first, so that error can include hops that might
# have been successful.
$code = 200;
if ($error)
{
$txt = "trace failed for ".$destination.": ".$error;
$code = 400; # request_timeout
}
# Hops are returned whether success of failure.
if ($hops)
{
$txt .= "Traceroute results for $destination\n";
foreach my $hop (@$data)
{
my $hopnumber = $hop->{hop};
my $routerip = $hop->{routerip};
my @rtts = @{$hop->{results}};
$txt .= "$hopnumber\t$routerip";
foreach (@rtts)
{
if ($_ eq "*") { $txt .= "\t * "; }
else { $txt .= "\t".sprintf "%0.3fms ", $_*1000; }
}
$txt .= "\n";
}
}
$request->Respond($kernel, $txt, $code );
return($self->name.":TraceResponse done");
}
=item TraceHopResponse
This POE event handler processes the per hop return data from the
PoCo::Client::Traceroute.
=cut
sub TraceHopResponse {
my ($kernel, $self, $trace, $reply) =
@_[KERNEL, OBJECT, ARG0, ARG1];
my ($destination, $options, $callback) = @$trace;
my ($hops, $data, $error) = @$reply;
$self->Verbose("TraceResponse: destination(".$destination.")");
my ($txt,$code);
my $request = delete($self->requests->{$destination}{'request'});
# define code first, so that error can include hops that might
# have been successful.
$code = 206; # partial content
if ($error)
{
$txt = "trace failed for ".$destination.": ".$error;
$code = 400; # request_timeout
}
# Hops are returned whether success of failure.
if ($hops)
{
$txt .= "Traceroute results for $destination\n";
foreach my $hop (@$data)
{
my $hopnumber = $hop->{hop};
my $routerip = $hop->{routerip};
my @rtts = @{$hop->{results}};
$txt .= "$hopnumber\t$routerip\t";
foreach (@rtts)
{
if ($_ eq "*") { $txt .= "* "; }
else { $txt .= sprintf "%0.3fms ", $_*1000; }
}
$txt .= "\n";
}
}
$request->Respond($kernel, $txt, $code );
return($self->name.":TraceResponse done");
}
sub _preinit :PreInit {
my ($self,$args) = @_;
$args->{'name'} = 'tcli_trace';
$args->{'session'} = POE::Session->create(
object_states => [
$self => [qw(
_start
_stop
_shutdown
_default
_child
establish_context
trace
TraceResponse
TraceHopResponse
settings
show
)],
],
);
}
sub _init :Init {
my $self = shift;
$self->LoadYaml(<<'...');
---
Agent::TCLI::Parameter:
name: firsthop
constraints:
- UINT
default: 1
help: Set the first hop.
manual: >
Firsthop sets the starting TTL value for the traceroute. firsthop
defaults to 1 and can not be set higher than 255 or greater than max_ttl.
type: Param
class: numeric
---
Agent::TCLI::Parameter:
name: max_ttl
constraints:
- UINT
default: 30
help: Set the maximum TTL.
manual: >
Maxttl sets the maximum TTL for the traceroute. Once this many hops
have been attempted, if the target has still not been reached, the
traceroute finishes and a 'MaxTTL exceeded without reaching target'
error is returned along with all of the data collected. max_ttl
defaults to 32 and can not be set higher than 255.
type: Param
class: numeric
---
Agent::TCLI::Parameter:
name: timeout
constraints:
- UINT
default: 0
help: Set global timeout in seconds.
manual: >
Timeout sets the maximum time any given traceroute will run. After
this time the traceroute will stop in the middle of where ever it
is and a 'Traceroute session timeout' error is returned along with
all of the data collected. Timeout defaults to 0, which disables
it completely.
type: Param
class: numeric
---
Agent::TCLI::Parameter:
name: querytimeout
constraints:
- UINT
default: 3
help: Set timeout for each query in seconds.
manual: >
Querytimeout sets the maximum before an individual query times out.
If the query times out an * is set for the response time and the
router IP address in the results data.
QueryTtimeout defaults to 3 seconds.
type: Param
class: numeric
---
Agent::TCLI::Parameter:
name: queries
constraints:
- UINT
default: 3
help: Set number of queries per hop.
manual: >
Queries sets the number of queries (packets) for each hop to send.
The response time for each query is recorded in the results table.
The higher this is, the better the chance of getting a response
from a flaky device, but the longer a traceroute takes to run.
Queries defaults to 3.
type: Param
class: numeric
---
Agent::TCLI::Parameter:
name: baseport
constraints:
- UINT
-
- BETWEEN
- 1
- 65279
default: 33434
help: The starting port for udp traces.
manual: >
Baseport sets the first port used for traceroute when not using ICMP.
The baseport is incremented by one for each hop, by traceroute
convention. BasePort defaults to 33434 and can not be higher than 65279.
type: Param
class: numeric
---
Agent::TCLI::Parameter:
name: useicmp
constraints:
- UINT
help: Turns on icmp instead of udp.
manual: >
Useicmp causes the traceroute to use ICMP Echo Requests instead of UDP
packets. This is advantagious in networks where ICMP Unreachables are
disabled, as ICMP Echo Responses are usually still allowed.
( run in 1.152 second using v1.01-cache-2.11-cpan-39bf76dae61 )