File Coverage

blib/lib/Net/Frame/Layer/ICMPv6/RouterSolicitation.pm
Criterion Covered Total %
statement 30 54 55.5
branch 3 6 50.0
condition 1 6 16.6
subroutine 9 13 69.2
pod 6 6 100.0
total 49 85 57.6


line stmt bran cond sub pod time code
1             #
2             # Router Solicitation message wrapper, compliant to RFC 4861
3             # pvenegas@infoweapons.com
4             #
5             #
6             # $Id: RouterSolicitation.pm,v bc01789674fd 2019/05/23 05:51:45 gomor $
7             #
8             package Net::Frame::Layer::ICMPv6::RouterSolicitation;
9 2     2   821 use strict; use warnings;
  2     2   5  
  2         46  
  2         8  
  2         4  
  2         47  
10              
11 2     2   9 use Net::Frame::Layer qw(:consts :subs);
  2         3  
  2         406  
12             our @ISA = qw(Net::Frame::Layer);
13              
14             our @AS = qw(
15             reserved
16             );
17             our @AA = qw(
18             options
19             );
20             __PACKAGE__->cgBuildIndices;
21             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
22             __PACKAGE__->cgBuildAccessorsArray (\@AA);
23              
24 2     2   14 use Net::Frame::Layer::ICMPv6 qw(:consts);
  2         3  
  2         366  
25 2     2   13 use Bit::Vector;
  2         2  
  2         56  
26 2     2   10 use Net::Frame::Layer::ICMPv6::Option;
  2         9  
  2         910  
27              
28             sub new {
29             shift->SUPER::new(
30 1     1 1 13 reserved => 0,
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 4 + $self->getOptionsLength;
46             }
47              
48             sub pack {
49 1     1 1 601 my $self = shift;
50              
51 1 50       5 my $raw = $self->SUPER::pack('L', $self->reserved)
52             or return;
53              
54 1         29 for ($self->options) {
55 0         0 $raw .= $_->pack;
56             }
57              
58 1         16 return $self->raw($raw);
59             }
60              
61             sub _unpackOptions {
62 0     0   0 my $self = shift;
63 0         0 my ($payload) = @_;
64            
65 0         0 my @options = ();
66 0   0     0 while (defined($payload) && length($payload)) {
67 0         0 my $opt = Net::Frame::Layer::ICMPv6::Option->new(raw => $payload)->unpack;
68 0         0 push @options, $opt;
69 0         0 $payload = $opt->payload;
70 0         0 $opt->payload(undef);
71             }
72 0         0 $self->options(\@options);
73 0         0 return $payload;
74             }
75              
76             sub unpack {
77 1     1 1 13 my $self = shift;
78              
79 1 50       3 my ($reserved, $payload) =
80             $self->SUPER::unpack('L a*', $self->raw)
81             or return;
82              
83 1         35 $self->reserved($reserved);
84 1         14 $self->payload($payload);
85              
86 1 50 33     14 if (defined($payload) && length($payload)) {
87 0         0 $payload = $self->_unpackOptions($payload);
88             }
89              
90 1         4 $self->payload($payload);
91              
92 1         12 return $self;
93             }
94              
95             sub print {
96 0     0 1   my $self = shift;
97              
98 0           my $l = $self->layer;
99 0           my $buf = sprintf "$l: reserved: 0x%02x",
100             $self->reserved;
101              
102 0           for ($self->options) {
103 0           $buf .= "\n" . $_->print;
104             }
105              
106 0           return $buf;
107             }
108              
109             1;
110              
111             __END__