File Coverage

blib/lib/Net/Canopy/BAM.pm
Criterion Covered Total %
statement 15 85 17.6
branch 0 12 0.0
condition 0 3 0.0
subroutine 5 12 41.6
pod 7 7 100.0
total 27 119 22.6


line stmt bran cond sub pod time code
1             package Net::Canopy::BAM;
2              
3 1     1   28732 use 5.008008;
  1         4  
  1         40  
4 1     1   6 use strict;
  1         2  
  1         36  
5 1     1   5 use warnings;
  1         7  
  1         41  
6 1     1   1050 use Bit::Vector;
  1         2557  
  1         93  
7              
8 1     1   1489 use Data::Dumper;
  1         12248  
  1         1103  
9              
10             require Exporter;
11              
12             our $VERSION = '0.04';
13              
14             =head1 NAME
15              
16             Net::Canopy::BAM - Identifies, assembles, and disassembles Canopy BAM packets.
17              
18             =head1 SYNOPSIS
19              
20             use Net::Canopy::BAM;
21              
22             =head1 DESCRIPTION
23              
24             Common Packet Assembly, Disassembly, and Identification for the JungleAuth
25             (http://code.google.com/p/jungleauth/) implementation of Canopy BAM.
26              
27             Also provides a BAM test client.
28              
29             =head1 METHODS
30              
31             =head3 new
32              
33             my $ncb = Net::Canopy::BAM->new();
34            
35             Instantiates Net::Canopy::BAM.
36              
37             =cut
38              
39             sub new {
40 0     0 1   my $invocant = shift;
41 0   0       my $class = ref($invocant) || $invocant;
42            
43 0           my $self = {
44             @_
45             };
46            
47 0           return bless $self, $class;
48             }
49              
50              
51             =head3 buildQstr
52              
53             my $QoSstr = $ncb->buildQstr(
54             upspeed => 512, # Upload speed in Kbps
55             downspeed => 1024, # Download speed in Kbps
56             upbucket => 320000, # Upload bucket size in Kb
57             downbucket => 5120000 # Download bucket size in Kb
58             );
59            
60             Builds a QoS string.
61              
62             =cut
63              
64             # Take hash of QoS settings and return formatted qosstr
65             sub buildQstr {
66 0     0 1   my ($class, %args) = @_;
67 0           my $tailpad = "0000000000000000000000000000000000000000";
68            
69 0           my $upspeed = Bit::Vector->new_Dec(16, $args{upspeed});
70 0           $upspeed = $upspeed->to_Hex();
71            
72 0           my $downspeed = Bit::Vector->new_Dec(16, $args{downspeed});
73 0           $downspeed = $downspeed->to_Hex();
74            
75 0           my $upbucket = Bit::Vector->new_Dec(32, $args{upbucket});
76 0           $upbucket = $upbucket->to_Hex();
77            
78 0           my $downbucket = Bit::Vector->new_Dec(32, $args{downbucket});
79 0           $downbucket = $downbucket->to_Hex();
80            
81 0           my $qstr = $upspeed . $downspeed . $upbucket . $downbucket . $tailpad;
82            
83 0           return $qstr;
84             }
85              
86             =head3 parseQstr
87              
88             my $QoShash = $ncb->parseQstr(qstr => $qosstring);
89              
90             Reads a QoS string and returns its component values as a hashref
91              
92             =cut
93              
94             # Return hash of QoS str values
95             sub parseQstr {
96 0     0 1   my ($class, %args) = @_;
97 0           my %qhash=();
98            
99 0           my $upspeed = hex(substr($args{qstr}, 0, 4));
100            
101 0           my $downspeed = hex(substr($args{qstr}, 4, 4));
102 0           my $upbucket = hex(substr($args{qstr}, 8, 8));
103 0           my $downbucket = hex(substr($args{qstr}, 16, 8));
104            
105 0           %qhash = (
106             'upspeed', $upspeed,
107             'downspeed', $downspeed,
108             'upbucket', $upbucket,
109             'downbucket', $downbucket
110             );
111            
112 0           return \%qhash;
113             }
114              
115             =head3 mkAcceptPacket
116              
117             my $packet = $ncb->mkAcceptPacket(
118             seq => $sequenceNumber.
119             mac => $smMAC,
120             qos => $QoSstr
121             );
122            
123             Returns a authentication acceptance packet
124              
125             =cut
126             # Assemble accept packet
127             sub mkAcceptPacket {
128 0     0 1   my ($class, %args) = @_;
129 0           my $magic1 = "250400000000";
130 0           my $magic2 = "000000670000000100000006";
131 0           my $magic3 = "0000000300000001000000000700000018";
132 0           my $magic4 = "ab8d3702bcc7d757280a7d7848f32e5910bf994e739517c";
133 0           my $qosPre = "60000000600000020";
134 0           my $qosPost = "0000000000000000";
135            
136 0           my $seq = sprintf("%04x", $args{seq});
137            
138 0           my $packet = $magic1 . $seq . $magic2 . $args{mac} . $magic3 . $magic4 . $qosPre .
139             $args{qos} . $qosPost;
140 0           $packet = pack('H*', $packet);
141            
142 0           return $packet;
143             }
144              
145             =head3 mkRejectPacket
146              
147             my $packet = $ncb->mkRejectPacket(
148             seq => $sequenceNumber,
149             mac => $smMAC
150             );
151              
152             Returns a rejection response packet.
153              
154             =cut
155              
156             # Assemble reject packet
157             sub mkRejectPacket {
158 0     0 1   my ($class, %args) = @_;
159              
160 0           my $magic1 = "230400000000";
161 0           my $magic2 = "000000370000000100000006";
162 0           my $magic3 = "0000000300000001010000000400000010000000000000000000000000000000000000000000000000";
163            
164 0           my $seq = sprintf("%04x", $args{seq});
165            
166 0           my $packet = $magic1 . $seq . $magic2 . $args{mac} . $magic3;
167 0           $packet = pack('H*', $packet);
168            
169 0           return $packet;
170             }
171              
172             =head3 mkConfirmPacket
173              
174             my $packet = $ncb->mkConfirmPacket(confirmation_token);
175              
176             =cut
177             # Assemble confirmation packet
178             sub mkConfirmPacket {
179 0     0 1   my ($class, $token) = @_;
180              
181 0           my $magic1 = "46000000";
182            
183 0           my $packet = $magic1 . $token;
184 0           $packet = pack('H*', $packet);
185              
186 0           return $packet;
187             }
188              
189             =head3 parsePacket
190              
191             my $parsedPacket = $ncb->parsePacket(packet => $packet);
192              
193             Identify packet and parse out data. Returns packet type and data as hashref
194              
195             =head4 Packet types
196              
197             =over
198              
199             =item authreq
200              
201             Authentication request from AP
202              
203             =over
204              
205             =item type - packet type
206              
207             =item sm - SM MAC address
208              
209             =item ap - AP MAC address
210              
211             =item luid - SM LUID on AP
212              
213             =item seq - Packet sequence number
214              
215             =back
216              
217             =item authchal-1
218              
219             Authentication challange from AP
220              
221             =item authchal-2
222              
223             Second Authentication challange from AP
224              
225             =item authgrant
226              
227             Authentication grant
228              
229             =item authverify
230              
231             =over
232              
233             =item token - verification session token
234              
235             =back
236              
237             Authentication verification
238              
239             =item authconfirm
240              
241             Authentication confirmation
242              
243             =back
244              
245             =cut
246              
247             sub parsePacket {
248 0     0 1   my ($class, %args) = @_;
249 0           my %pinfo = ();
250            
251 0           my $packet = unpack('H*', $args{packet});
252 0           my $type = substr($packet, 0, 2);
253            
254 0 0         if ($type eq '01') { # Auth request
    0          
    0          
    0          
    0          
    0          
255 0           $pinfo{'type'} = 'authreq';
256            
257 0           $pinfo{'sm'} = substr($packet, 2, 12);
258 0           $pinfo{'ap'} = substr($packet, 14, 12);
259 0           $pinfo{'luid'} = hex(substr($packet, 30, 2));
260 0           $pinfo{'seq'} = hex(substr($packet, 36, 4));
261            
262             } elsif ($type eq '23') { # Auth Challange APAS->AP or Rejection APAS->AP
263 0           $pinfo{'type'} = 'authchal-1';
264            
265             } elsif ($type eq '24') { # Auth Challange AP->APAS
266 0           $pinfo{'type'} = 'authchal-2';
267            
268             } elsif ($type eq '25') { # Auth grant
269 0           $pinfo{'type'} = 'authgrant';
270            
271             } elsif ($type eq '45') { # Auth verify
272 0           $pinfo{'type'} = 'authverify';
273            
274 0           $pinfo{'magic1'} = substr($packet, 0, 8);
275 0           $pinfo{'token'} = substr($packet, 8, 16);
276 0           $pinfo{'magic2'} = substr($packet, 16, 8);
277 0           $pinfo{'sm'} = substr($packet, 24, 12);
278 0           $pinfo{'magic3'} = substr($packet, 36, 214);
279            
280             } elsif ($type eq '46') { # Auth confirm
281 0           $pinfo{'type'} = 'authconfirm';
282            
283             } else {
284 0           print "Unknown packet: $packet\n";
285             }
286            
287 0           return \%pinfo;
288             }
289              
290             1;
291             __END__