File Coverage

blib/lib/Net/Frame/Layer/ICMPv6/NeighborAdvertisement.pm
Criterion Covered Total %
statement 35 59 59.3
branch 3 6 50.0
condition 1 6 16.6
subroutine 9 13 69.2
pod 6 6 100.0
total 54 90 60.0


line stmt bran cond sub pod time code
1             #
2             # $Id: NeighborAdvertisement.pm,v bc01789674fd 2019/05/23 05:51:45 gomor $
3             #
4             package Net::Frame::Layer::ICMPv6::NeighborAdvertisement;
5 2     2   820 use strict; use warnings;
  2     2   4  
  2         45  
  2         10  
  2         3  
  2         45  
6              
7 2     2   10 use Net::Frame::Layer qw(:consts :subs);
  2         4  
  2         415  
8             our @ISA = qw(Net::Frame::Layer);
9              
10             our @AS = qw(
11             flags
12             reserved
13             targetAddress
14             );
15             our @AA = qw(
16             options
17             );
18             __PACKAGE__->cgBuildIndices;
19             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
20             __PACKAGE__->cgBuildAccessorsArray (\@AA);
21              
22 2     2   13 use Net::Frame::Layer::ICMPv6 qw(:consts);
  2         4  
  2         348  
23 2     2   29 use Bit::Vector;
  2         6  
  2         68  
24 2     2   742 use Net::Frame::Layer::ICMPv6::Option;
  2         5  
  2         1025  
25              
26             sub new {
27             shift->SUPER::new(
28 1     1 1 15 flags => NF_ICMPv6_FLAG_SOLICITED,
29             reserved => 0,
30             targetAddress => '::1',
31             options => [],
32             @_,
33             );
34             }
35              
36             sub getOptionsLength {
37 0     0 1 0 my $self = shift;
38 0         0 my $len = 0;
39 0         0 $len += $_->getLength for $self->options;
40 0         0 return $len;
41             }
42              
43             sub getLength {
44 0     0 1 0 my $self = shift;
45 0         0 return 20 + $self->getOptionsLength;
46             }
47              
48             sub pack {
49 1     1 1 181 my $self = shift;
50              
51 1         4 my $flags = Bit::Vector->new_Dec( 3, $self->flags);
52 1         26 my $reserved = Bit::Vector->new_Dec(29, $self->reserved);
53 1         14 my $v32 = $flags->Concat_List($reserved);
54              
55 1 50       7 my $raw = $self->SUPER::pack('Na16',
56             $v32->to_Dec, inet6Aton($self->targetAddress),
57             ) or return;
58              
59 1         38 for ($self->options) {
60 0         0 $raw .= $_->pack;
61             }
62              
63 1         18 return $self->raw($raw);
64             }
65              
66             sub _unpackOptions {
67 0     0   0 my $self = shift;
68 0         0 my ($payload) = @_;
69              
70 0         0 my @options = ();
71 0   0     0 while (defined($payload) && length($payload)) {
72 0         0 my $opt = Net::Frame::Layer::ICMPv6::Option->new(raw => $payload)->unpack;
73 0         0 push @options, $opt;
74 0         0 $payload = $opt->payload;
75 0         0 $opt->payload(undef);
76             }
77 0         0 $self->options(\@options);
78 0         0 return $payload;
79             }
80              
81             sub unpack {
82 1     1 1 16 my $self = shift;
83              
84 1 50       4 my ($flagsReserved, $targetAddress, $payload) =
85             $self->SUPER::unpack('Na16 a*', $self->raw)
86             or return undef;
87              
88 1         26 my $v32 = Bit::Vector->new_Dec(32, $flagsReserved);
89              
90 1         7 $self->reserved($v32->Chunk_Read(29, 0));
91 1         11 $self->flags ($v32->Chunk_Read( 3, 29));
92 1         11 $self->targetAddress(inet6Ntoa($targetAddress));
93              
94 1 50 33     24 if (defined($payload) && length($payload)) {
95 0         0 $payload = $self->_unpackOptions($payload);
96             }
97              
98 1         5 $self->payload($payload);
99              
100 1         14 return $self;
101             }
102              
103             sub print {
104 0     0 1   my $self = shift;
105              
106 0           my $l = $self->layer;
107 0           my $buf = sprintf "$l: flags:%02x reserved:%d\n".
108             "$l: targetAddress:%s",
109             $self->flags, $self->reserved, $self->targetAddress;
110              
111 0           for ($self->options) {
112 0           $buf .= "\n".$_->print;
113             }
114              
115 0           return $buf;
116             }
117              
118             1;
119              
120             __END__