Net-Frame-Layer-IPv6

 view release on metacpan or  search on metacpan

lib/Net/Frame/Layer/IPv6/Routing.pm  view on Meta::CPAN

package Net::Frame::Layer::IPv6::Routing;
use strict; use warnings;

our $VERSION = '1.08';

use Net::Frame::Layer qw(:consts :subs);
use Exporter;
our @ISA = qw(Net::Frame::Layer Exporter);

our @AS = qw(
   nextHeader
   hdrExtLen
   routingType
   segmentsLeft
   reserved
);
our @AA = qw(
   addresses
);
__PACKAGE__->cgBuildIndices;
__PACKAGE__->cgBuildAccessorsScalar(\@AS);
__PACKAGE__->cgBuildAccessorsArray(\@AA);

use Net::Frame::Layer::IPv6 qw(:consts);
my $IPv6RoutingComputeSegmentsLeft = 1;

sub new {
   shift->SUPER::new(
      nextHeader   => NF_IPv6_PROTOCOL_TCP,
      hdrExtLen    => 2,
      routingType  => 0,
      segmentsLeft => 1,
      reserved     => 0,
      addresses    => ['::1'],
      @_,
   );
}

sub _getAddressesLength {
   my $self = shift;
   my $len = 0;
   $len += 16 for $self->addresses;
   return $len;
}

sub getLength {
   my $self = shift;
   return 8 + $self->_getAddressesLength;
}

sub pack {
   my $self = shift;

   my $raw = $self->SUPER::pack('CCCCN',
      $self->nextHeader, $self->hdrExtLen, $self->routingType,
      $self->segmentsLeft, $self->reserved
   ) or return;

   for ($self->addresses) {
      $raw .= $self->SUPER::pack('a16',
         inet6Aton($_)
      ) or return;
   }

   return $self->raw($raw);
}

sub unpack {
   my $self = shift;

   my ($nextHeader, $hdrExtLen, $routingType, $segmentsLeft, $reserved, $rest) =
      $self->SUPER::unpack('CCCCN a*', $self->raw)
         or return;

   $self->nextHeader($nextHeader);
   $self->hdrExtLen($hdrExtLen);
   $self->routingType($routingType);
   $self->segmentsLeft($segmentsLeft);
   $self->reserved($reserved);

   my @addresses = ();
   for (1..$hdrExtLen/2) {
      my ($address) =
         $self->SUPER::unpack('a16', substr $rest, 16*($_-1))
            or return;
      push @addresses, inet6Ntoa($address)
   }

   $self->addresses(\@addresses);

   $self->payload(substr $rest, 16*$hdrExtLen/2);

   return $self;
}

sub computeSegmentsLeft {
   my ($self, $arg) = @_;

   if (defined($arg)) {
      if (($arg =~ /^\d$/) && ($arg == 0)) {
         $IPv6RoutingComputeSegmentsLeft = 0
      } else {
         $IPv6RoutingComputeSegmentsLeft = 1
      }
   }
   return $IPv6RoutingComputeSegmentsLeft
}

sub computeLengths {
   my $self = shift;

   my $hdrExtLen = 0;
   $hdrExtLen += 2 for $self->addresses;
   $self->hdrExtLen($hdrExtLen);

   if ($IPv6RoutingComputeSegmentsLeft) {
      my $segmentsLeft = 0;
      $segmentsLeft += 1 for $self->addresses;
      $self->segmentsLeft($segmentsLeft);
   }

   return 1;
}

sub encapsulate {
   my $self = shift;

   return $self->nextLayer if $self->nextLayer;

   if ($self->payload) {
      my $next = $self->nextHeader;
      return Net::Frame::Layer::IPv6->new(nextHeader=>$self->nextHeader)->encapsulate
   }

   return NF_LAYER_NONE;
}

sub print {
   my $self = shift;

   my $l = $self->layer;
   my $buf = sprintf
      "$l: nextHeader:0x%02x  hdrExtLen:%d  routingType:%d\n".
      "$l: segmentsLeft:%d  reserved:%d",
         $self->nextHeader, $self->hdrExtLen, $self->routingType,
         $self->segmentsLeft, $self->reserved;



( run in 0.660 second using v1.01-cache-2.11-cpan-df04353d9ac )