File Coverage

blib/lib/Net/Frame/Layer/ICMPv6/RouterAdvertisement.pm
Criterion Covered Total %
statement 38 62 61.2
branch 2 4 50.0
condition 1 6 16.6
subroutine 9 13 69.2
pod 6 6 100.0
total 56 91 61.5


line stmt bran cond sub pod time code
1             #
2             # Router Advertisement message wrapper
3             # pvenegas@infoweapons.com
4             #
5             #
6             # $Id: RouterAdvertisement.pm,v b9194b248a66 2017/10/06 16:26:50 gomor $
7             #
8             package Net::Frame::Layer::ICMPv6::RouterAdvertisement;
9 2     2   926 use strict; use warnings;
  2     2   6  
  2         72  
  2         16  
  2         7  
  2         90  
10              
11 2     2   16 use Net::Frame::Layer qw(:consts :subs);
  2         6  
  2         655  
12             our @ISA = qw(Net::Frame::Layer);
13              
14             our @AS = qw(
15             curHopLimit
16             flags
17             reserved
18             routerLifetime
19             reachableTime
20             retransTimer
21             );
22             our @AA = qw(
23             options
24             );
25             __PACKAGE__->cgBuildIndices;
26             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
27             __PACKAGE__->cgBuildAccessorsArray (\@AA);
28              
29 2     2   19 use Net::Frame::Layer::ICMPv6 qw(:consts);
  2         6  
  2         565  
30 2     2   18 use Bit::Vector;
  2         6  
  2         96  
31 2     2   16 use Net::Frame::Layer::ICMPv6::Option;
  2         6  
  2         1662  
32              
33             # TODO: Double-check if defaults are sane
34             sub new {
35             shift->SUPER::new(
36 1     1 1 62 curHopLimit => 0,
37             flags => 0,
38             reserved => 0,
39             routerLifetime => 0,
40             reachableTime => 0,
41             retransTimer => 0,
42             options => [],
43             @_,
44             );
45             }
46              
47             sub getOptionsLength {
48 0     0 1 0 my $self = shift;
49 0         0 my $len = 0;
50 0         0 $len += $_->getLength for $self->options;
51 0         0 return $len;
52             }
53              
54             sub getLength {
55 0     0 1 0 my $self = shift;
56 0         0 return 12 + $self->getOptionsLength;
57             }
58              
59             sub pack {
60 1     1 1 370 my $self = shift;
61              
62 1         5 my $flags = Bit::Vector->new_Dec(6, $self->flags);
63 1         28 my $reserved = Bit::Vector->new_Dec(2, $self->reserved);
64 1         19 my $v8 = $flags->Concat_List($reserved);
65              
66 1 50       34 my $raw = $self->SUPER::pack("CcnLL",
67             $self->curHopLimit, $v8->to_Dec, $self->routerLifetime,
68             $self->reachableTime, $self->retransTimer
69             ) or return;
70              
71 1         75 for ($self->options) {
72 0         0 $raw .= $_->pack;
73             }
74              
75 1         21 $self->raw($raw);
76             }
77              
78             sub _unpackOptions {
79 0     0   0 my $self = shift;
80 0         0 my ($payload) = @_;
81            
82 0         0 my @options = ();
83 0   0     0 while (defined($payload) && length($payload)) {
84 0         0 my $opt = Net::Frame::Layer::ICMPv6::Option->new(raw => $payload)->unpack;
85 0         0 push @options, $opt;
86 0         0 $payload = $opt->payload;
87 0         0 $opt->payload(undef);
88             }
89 0         0 $self->options(\@options);
90 0         0 return $payload;
91             }
92              
93             sub unpack {
94 1     1 1 20 my $self = shift;
95              
96 1         5 my ($curHopLimit, $flagsReserved, $routerLifetime,
97             $reachableTime, $retransTimer, $payload) =
98             $self->SUPER::unpack("CcnLL a*", $self->raw);
99              
100 1         36 my $v8 = Bit::Vector->new_Dec(8, $flagsReserved);
101              
102 1         6 $self->curHopLimit($curHopLimit);
103 1         17 $self->reserved($v8->Chunk_Read(2, 0));
104 1         21 $self->flags ($v8->Chunk_Read(6, 2));
105 1         15 $self->routerLifetime($routerLifetime);
106 1         14 $self->reachableTime($reachableTime);
107 1         14 $self->retransTimer($retransTimer);
108            
109 1 50 33     20 if (defined($payload) && length($payload)) {
110 0         0 $payload = $self->_unpackOptions($payload);
111             }
112              
113 1         7 $self->payload($payload);
114              
115 1         22 return $self;
116             }
117              
118             sub print {
119 0     0 1   my $self = shift;
120              
121 0           my $l = $self->layer;
122 0           my $buf = sprintf "$l: curHopLimit: %d flags: 0x%02x reserved: 0x%02x\n" .
123             "$l: routerLifetime: %d reachableTime: %d retransTimer: %d",
124             $self->curHopLimit,
125             $self->flags,
126             $self->reserved,
127             $self->routerLifetime,
128             $self->reachableTime,
129             $self->retransTimer;
130              
131 0           for ($self->options) {
132 0           $buf .= "\n" . $_->print;
133             }
134              
135 0           return $buf;
136             }
137              
138             1;
139              
140             __END__