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 )