Net-Frame

 view release on metacpan or  search on metacpan

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

__PACKAGE__->cgBuildAccessorsScalar(\@AS);

no strict 'vars';

sub new {
   my $self = shift->SUPER::new(
      hType   => NF_ARP_HTYPE_ETH,
      pType   => NF_ARP_PTYPE_IPv4,
      hSize   => NF_ARP_HSIZE_ETH,
      pSize   => NF_ARP_PSIZE_IPv4,
      opCode  => NF_ARP_OPCODE_REQUEST,
      src     => '00:00:00:00:00:00',
      dst     => NF_ARP_ADDR_BROADCAST,
      srcIp   => '127.0.0.1',
      dstIp   => '127.0.0.1',
      @_,
   );

   $self->[$__src] = lc($self->[$__src]) if $self->[$__src];
   $self->[$__dst] = lc($self->[$__dst]) if $self->[$__dst];

   return $self;
}

sub getLength {
   my $self = shift;
   my $len = NF_ARP_HDR_LEN;
   $len += 24 if $self->[$__pType] == NF_ARP_PTYPE_IPv6;
   return $len;
}

sub pack {
   my $self = shift;

   (my $srcMac = $self->[$__src]) =~ s/://g;
   (my $dstMac = $self->[$__dst]) =~ s/://g;

   # IPv4 packing
   if ($self->[$__pType] == NF_ARP_PTYPE_IPv4) {
      $self->[$__raw] = $self->SUPER::pack('nnCCnH12a4H12a4',
         $self->[$__hType],
         $self->[$__pType],
         $self->[$__hSize],
         $self->[$__pSize],
         $self->[$__opCode],
         $srcMac,
         inetAton($self->[$__srcIp]),
         $dstMac,
         inetAton($self->[$__dstIp]),
      ) or return;
   }
   # IPv6 packing
   else {
      $self->[$__raw] = $self->SUPER::pack('nnCCnH12a*H12a*',
         $self->[$__hType],
         $self->[$__pType],
         $self->[$__hSize],
         $self->[$__pSize],
         $self->[$__opCode],
         $srcMac,
         inet6Aton($self->[$__srcIp]),
         $dstMac,
         inet6Aton($self->[$__dstIp]),
      ) or return;
   }

   return $self->[$__raw];
}

sub unpack {
   my $self = shift;

   my ($hType, $pType, $tail) = $self->SUPER::unpack('nn a*',
      $self->[$__raw])
         or return;

   my ($hSize, $pSize, $opCode, $srcMac, $srcIp, $dstMac, $dstIp,
       $payload);

   # IPv4 unpacking
   if ($pType == NF_ARP_PTYPE_IPv4) {
      ($hSize, $pSize, $opCode, $srcMac, $srcIp, $dstMac, $dstIp,
       $payload) = $self->SUPER::unpack('CCnH12a4H12a4 a*', $tail)
         or return;
      $self->[$__srcIp] = inetNtoa($srcIp);
      $self->[$__dstIp] = inetNtoa($dstIp);
   }
   # IPv6 unpacking
   else {
      ($hSize, $pSize, $opCode, $srcMac, $srcIp, $dstMac, $dstIp,
       $payload) = $self->SUPER::unpack('CCnH12a16H12a16 a*', $tail)
         or return;
      $self->[$__srcIp] = inet6Ntoa($srcIp);
      $self->[$__dstIp] = inet6Ntoa($dstIp);
   }

   $self->[$__hType]  = $hType;
   $self->[$__pType]  = $pType;
   $self->[$__hSize]  = $hSize;
   $self->[$__pSize]  = $pSize;
   $self->[$__opCode] = $opCode;
   $self->[$__src]    = convertMac($srcMac);
   $self->[$__dst]    = convertMac($dstMac);

   $self->[$__payload] = $payload;

   return $self;
}

sub getKey        { shift->layer }
sub getKeyReverse { shift->layer }

sub match {
   my $self = shift;
   my ($with) = @_;
      ($self->[$__opCode] == NF_ARP_OPCODE_REQUEST)
   && ($with->[$__opCode] == NF_ARP_OPCODE_REPLY)
   && ($with->[$__dst]    eq $self->[$__src])
   && ($with->[$__srcIp]  eq $self->[$__dstIp])
   && ($with->[$__dstIp]  eq $self->[$__srcIp]);
}

sub encapsulate {
   my $self = shift;
   return $self->[$__nextLayer];
}

sub print {
   my $self = shift;

   my $l = $self->layer;
   sprintf
      "$l: hType:0x%04x  pType:0x%04x  hSize:0x%02x  pSize:0x%02x".
      "  opCode:0x%04x\n".
      "$l: src:%s  srcIp:%s\n".
      "$l: dst:%s  dstIp:%s",
         $self->[$__hType], $self->[$__pType], $self->[$__hSize],
         $self->[$__pSize], $self->[$__opCode], $self->[$__src],
         $self->[$__srcIp], $self->[$__dst],  $self->[$__dstIp];
}

1;

__END__

=head1 NAME

Net::Frame::Layer::ARP - Address Resolution Protocol layer object

=head1 SYNOPSIS

   use Net::Frame::Layer::ARP qw(:consts);

   # Build a layer



( run in 0.658 second using v1.01-cache-2.11-cpan-e1769b4cff6 )