File Coverage

blib/lib/Net/Frame/Layer/OSPF/Lsa.pm
Criterion Covered Total %
statement 32 86 37.2
branch 5 30 16.6
condition 1 9 11.1
subroutine 7 11 63.6
pod 7 7 100.0
total 52 143 36.3


line stmt bran cond sub pod time code
1             #
2             # $Id: Lsa.pm 73 2015-01-14 06:42:49Z gomor $
3             #
4             package Net::Frame::Layer::OSPF::Lsa;
5 14     14   5040 use strict; use warnings;
  14     14   22  
  14         475  
  14         62  
  14         18  
  14         413  
6              
7 14     14   618 use Net::Frame::Layer qw(:consts :subs);
  14         61801  
  14         3429  
8             our @ISA = qw(Net::Frame::Layer);
9              
10             our @AS = qw(
11             lsAge
12             options
13             lsType
14             linkStateId
15             advertisingRouter
16             lsSequenceNumber
17             lsChecksum
18             length
19             lsa
20             full
21             );
22             __PACKAGE__->cgBuildIndices;
23             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
24              
25 14     14   674 use Net::Frame::Layer::OSPF qw(:consts);
  14         22  
  14         15577  
26             require Net::Frame::Layer::OSPF::Lsa::Opaque;
27             require Net::Frame::Layer::OSPF::Lsa::Router;
28             require Net::Frame::Layer::OSPF::Lsa::Network;
29             require Net::Frame::Layer::OSPF::Lsa::SummaryIp;
30              
31             sub new {
32             shift->SUPER::new(
33 1     1 1 28 lsAge => 30,
34             options => 0,
35             lsType => NF_OSPF_LSTYPE_ROUTER,
36             linkStateId => '0.0.0.0',
37             advertisingRouter => '0.0.0.0',
38             lsSequenceNumber => 0,
39             lsChecksum => 0,
40             length => NF_OSPF_LSA_HDR_LEN,
41             full => 1,
42             @_,
43             );
44             }
45              
46             # Lsa begins with standard 20 bytes header
47             sub getLength {
48 0     0 1 0 my $self = shift;
49 0         0 my $len = NF_OSPF_LSA_HDR_LEN;
50 0 0       0 $len += $self->lsa->getLength if $self->lsa;
51 0         0 $len;
52             }
53              
54             sub computeLengths {
55 0     0 1 0 my $self = shift;
56 0         0 my $len = $self->getLength;
57 0         0 $self->length($len);
58             }
59              
60             sub computeChecksums {
61 0     0 1 0 my $self = shift;
62              
63 0         0 $self->lsChecksum(0);
64 0         0 my $raw = $self->pack;
65 0         0 my $data = substr($raw, 2);
66             # We pad the data to the possibly fake length
67 0         0 my @chars = unpack('C*', $data.("0"x($self->length - length($data))));
68              
69 0         0 my $c0 = 0;
70 0         0 my $c1 = 0;
71 0         0 my $length = $self->length - 2;
72 0         0 my $MODX = 4102;
73 0         0 my ($sp, $ep, $p, $q);
74 0         0 $sp = 0;
75 0         0 for ($ep = $length; $sp < $ep; $sp = $q) {
76 0         0 $q = $sp + $MODX;
77 0 0       0 if ($q > $ep) {
78 0         0 $q = $ep;
79             }
80 0         0 for ($p = $sp; $p < $q; $p++) {
81 0         0 $c0 += $chars[$p];
82 0         0 $c1 += $c0;
83             }
84 0         0 $c0 %= 255;
85 0         0 $c1 %= 255;
86             }
87 0         0 my $x = (($length - 15) * $c0 - $c1) % 255;
88 0 0       0 if ($x <= 0) {
89 0         0 $x += 255;
90             }
91 0         0 my $y = 510 - $c0 - $x;
92 0 0       0 if ($y > 255) {
93 0         0 $y -= 255;
94             }
95              
96 0         0 $self->lsChecksum(($x << 8) + $y);
97             }
98              
99             sub pack {
100 1     1 1 412 my $self = shift;
101              
102 1 50       6 my $raw = $self->SUPER::pack('nCCa4a4Nnn a*',
103             $self->lsAge, $self->options, $self->lsType, inetAton($self->linkStateId),
104             inetAton($self->advertisingRouter), $self->lsSequenceNumber,
105             $self->lsChecksum, $self->length,
106             ) or return undef;
107              
108 1 50       153 $raw .= $self->lsa->pack if $self->lsa;
109              
110 1         20 $self->raw($raw);
111             }
112              
113             sub unpack {
114 1     1 1 18 my $self = shift;
115              
116 1 50       13 my ($lsAge, $options, $lsType, $linkStateId, $advertisingRouter,
117             $lsSequenceNumber, $lsChecksum, $length, $payload)
118             = $self->SUPER::unpack('nCCa4a4Nnn a*', $self->raw)
119             or return undef;
120              
121 1         51 $self->lsAge($lsAge);
122 1         15 $self->options($options);
123 1         11 $self->lsType($lsType);
124 1         12 $self->linkStateId(inetNtoa($linkStateId));
125 1         19 $self->advertisingRouter(inetNtoa($advertisingRouter));
126 1         18 $self->lsSequenceNumber($lsSequenceNumber);
127 1         11 $self->lsChecksum($lsChecksum);
128 1         10 $self->length($length);
129              
130 1         9 my $next;
131 1 50 33     6 if ($self->full && $payload) {
132 0 0 0     0 if ($lsType == NF_OSPF_LSTYPE_OPAQUELINKLOCAL
    0 0        
    0          
    0          
133             || $lsType == NF_OSPF_LSTYPE_OPAQUEAREALOCAL
134             || $lsType == NF_OSPF_LSTYPE_OPAQUEDOMAIN) {
135 0         0 my $pLen = length($payload);
136 0 0       0 if ($length > $pLen) {
137 0         0 my $oLen = $length - NF_OSPF_LSA_HDR_LEN;
138 0         0 my $opaque = substr($payload, 0, $oLen);
139 0         0 $next = Net::Frame::Layer::OSPF::Lsa::Opaque->new(raw => $opaque);
140 0         0 $payload = substr($payload, $oLen);
141 0         0 $next->payload($payload);
142             }
143             }
144             elsif ($lsType == NF_OSPF_LSTYPE_ROUTER) {
145 0         0 $next = Net::Frame::Layer::OSPF::Lsa::Router->new(raw => $payload);
146             }
147             elsif ($lsType == NF_OSPF_LSTYPE_NETWORK) {
148 0         0 $next = Net::Frame::Layer::OSPF::Lsa::Network->new(raw => $payload);
149             }
150             elsif ($lsType == NF_OSPF_LSTYPE_SUMMARYIP) {
151 0         0 $next = Net::Frame::Layer::OSPF::Lsa::SummaryIp->new(raw => $payload);
152             }
153             }
154              
155 1 50       19 if ($next) {
156 0         0 $next->unpack;
157 0         0 $self->lsa($next);
158 0         0 $payload = $next->payload;
159             }
160              
161 1         9 $self->payload($payload);
162              
163 1         9 $self;
164             }
165              
166             sub print {
167 0     0 1   my $self = shift;
168              
169 0           my $l = $self->layer;
170 0           my $buf = sprintf
171             "$l: lsAge:%d options:0x%02x lsType:0x%02x linkStateId:%s\n".
172             "$l: advertisingRouter:%s lsSequenceNumber:0x%08x\n".
173             "$l: lsChecksum:0x%04x length:%d",
174             $self->lsAge,
175             $self->options,
176             $self->lsType,
177             $self->linkStateId,
178             $self->advertisingRouter,
179             $self->lsSequenceNumber,
180             $self->lsChecksum,
181             $self->length,
182             ;
183              
184 0 0         if ($self->lsa) {
185 0           $buf .= "\n".$self->lsa->print;
186             }
187              
188 0           $buf;
189             }
190              
191             1;
192              
193             __END__