1#
2# $Id: IPv6.pm 47 2015-01-20 18:20:28Z gomor $
3#
4package Net::Frame::Layer::IPv6;
5use strict;
6use warnings;
7
8our $VERSION = '1.07';
9
10use Net::Frame::Layer qw(:consts :subs);
11require Exporter;
12our @ISA = qw(Net::Frame::Layer Exporter);
13
14our %EXPORT_TAGS = (
15   consts => [qw(
16      NF_IPv6_HDR_LEN
17      NF_IPv6_PROTOCOL_ICMPv4
18      NF_IPv6_PROTOCOL_IGMP
19      NF_IPv6_PROTOCOL_IPIP
20      NF_IPv6_PROTOCOL_TCP
21      NF_IPv6_PROTOCOL_EGP
22      NF_IPv6_PROTOCOL_IGRP
23      NF_IPv6_PROTOCOL_CHAOS
24      NF_IPv6_PROTOCOL_UDP
25      NF_IPv6_PROTOCOL_IDP
26      NF_IPv6_PROTOCOL_DCCP
27      NF_IPv6_PROTOCOL_IPv6
28      NF_IPv6_PROTOCOL_IPv6ROUTING
29      NF_IPv6_PROTOCOL_IPv6FRAGMENT
30      NF_IPv6_PROTOCOL_IDRP
31      NF_IPv6_PROTOCOL_RSVP
32      NF_IPv6_PROTOCOL_GRE
33      NF_IPv6_PROTOCOL_ESP
34      NF_IPv6_PROTOCOL_AH
35      NF_IPv6_PROTOCOL_ICMPv6
36      NF_IPv6_PROTOCOL_EIGRP
37      NF_IPv6_PROTOCOL_OSPF
38      NF_IPv6_PROTOCOL_ETHERIP
39      NF_IPv6_PROTOCOL_PIM
40      NF_IPv6_PROTOCOL_VRRP
41      NF_IPv6_PROTOCOL_STP
42      NF_IPv6_PROTOCOL_SCTP
43      NF_IPv6_PROTOCOL_UDPLITE
44      NF_IPv6_PROTOCOL_IPv6HOPBYHOP
45      NF_IPv6_PROTOCOL_GGP
46      NF_IPv6_PROTOCOL_ST
47      NF_IPv6_PROTOCOL_CBT
48      NF_IPv6_PROTOCOL_PUP
49      NF_IPv6_PROTOCOL_ARGUS
50      NF_IPv6_PROTOCOL_EMCON
51      NF_IPv6_PROTOCOL_XNET
52      NF_IPv6_PROTOCOL_MUX
53      NF_IPv6_PROTOCOL_DCNMEAS
54      NF_IPv6_PROTOCOL_HMP
55      NF_IPv6_PROTOCOL_PRM
56      NF_IPv6_PROTOCOL_TRUNK1
57      NF_IPv6_PROTOCOL_TRUNK2
58      NF_IPv6_PROTOCOL_LEAF1
59      NF_IPv6_PROTOCOL_LEAF2
60      NF_IPv6_PROTOCOL_3PC
61      NF_IPv6_PROTOCOL_IDPR
62      NF_IPv6_PROTOCOL_XTP
63      NF_IPv6_PROTOCOL_DDP
64      NF_IPv6_PROTOCOL_IDPRCMTP
65      NF_IPv6_PROTOCOL_TPPLUSPLUS
66      NF_IPv6_PROTOCOL_IL
67      NF_IPv6_PROTOCOL_SDRP
68      NF_IPv6_PROTOCOL_IPv6NONEXT
69      NF_IPv6_PROTOCOL_IPv6DESTINATION
70      NF_IPv6_PROTOCOL_IPv6MOBILITY
71   )],
72);
73our @EXPORT_OK = (
74   @{$EXPORT_TAGS{consts}},
75);
76
77#
78# http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml
79#
80use constant NF_IPv6_HDR_LEN               => 40;
81use constant NF_IPv6_PROTOCOL_IPv6HOPBYHOP => 0x00;
82use constant NF_IPv6_PROTOCOL_ICMPv4       => 0x01;
83use constant NF_IPv6_PROTOCOL_IGMP         => 0x02;
84use constant NF_IPv6_PROTOCOL_GGP          => 0x03;
85use constant NF_IPv6_PROTOCOL_IPIP         => 0x04;
86use constant NF_IPv6_PROTOCOL_ST           => 0x05;
87use constant NF_IPv6_PROTOCOL_TCP          => 0x06;
88use constant NF_IPv6_PROTOCOL_CBT          => 0x07;
89use constant NF_IPv6_PROTOCOL_EGP          => 0x08;
90use constant NF_IPv6_PROTOCOL_IGRP         => 0x09;
91use constant NF_IPv6_PROTOCOL_PUP          => 0x0c;
92use constant NF_IPv6_PROTOCOL_ARGUS        => 0x0d;
93use constant NF_IPv6_PROTOCOL_EMCON        => 0x0e;
94use constant NF_IPv6_PROTOCOL_XNET         => 0x0f;
95use constant NF_IPv6_PROTOCOL_CHAOS        => 0x10;
96use constant NF_IPv6_PROTOCOL_UDP          => 0x11;
97use constant NF_IPv6_PROTOCOL_MUX          => 0x12;
98use constant NF_IPv6_PROTOCOL_DCNMEAS      => 0x13;
99use constant NF_IPv6_PROTOCOL_HMP          => 0x14;
100use constant NF_IPv6_PROTOCOL_PRM          => 0x15;
101use constant NF_IPv6_PROTOCOL_IDP          => 0x16;
102use constant NF_IPv6_PROTOCOL_TRUNK1       => 0x17;
103use constant NF_IPv6_PROTOCOL_TRUNK2       => 0x18;
104use constant NF_IPv6_PROTOCOL_LEAF1        => 0x19;
105use constant NF_IPv6_PROTOCOL_LEAF2        => 0x20;
106use constant NF_IPv6_PROTOCOL_DCCP         => 0x21;
107use constant NF_IPv6_PROTOCOL_3PC          => 0x22;
108use constant NF_IPv6_PROTOCOL_IDPR         => 0x23;
109use constant NF_IPv6_PROTOCOL_XTP          => 0x24;
110use constant NF_IPv6_PROTOCOL_DDP          => 0x25;
111use constant NF_IPv6_PROTOCOL_IDPRCMTP     => 0x26;
112use constant NF_IPv6_PROTOCOL_TPPLUSPLUS   => 0x27;
113use constant NF_IPv6_PROTOCOL_IL           => 0x28;
114use constant NF_IPv6_PROTOCOL_IPv6         => 0x29;
115use constant NF_IPv6_PROTOCOL_SDRP         => 0x2a;
116use constant NF_IPv6_PROTOCOL_IPv6ROUTING  => 0x2b;
117use constant NF_IPv6_PROTOCOL_IPv6FRAGMENT => 0x2c;
118use constant NF_IPv6_PROTOCOL_IDRP         => 0x2d;
119use constant NF_IPv6_PROTOCOL_RSVP         => 0x2e;
120use constant NF_IPv6_PROTOCOL_GRE          => 0x2f;
121use constant NF_IPv6_PROTOCOL_ESP          => 0x32;
122use constant NF_IPv6_PROTOCOL_AH           => 0x33;
123use constant NF_IPv6_PROTOCOL_ICMPv6       => 0x3a;
124use constant NF_IPv6_PROTOCOL_IPv6NONEXT   => 0x3b;
125use constant NF_IPv6_PROTOCOL_IPv6DESTINATION => 0x3c;
126use constant NF_IPv6_PROTOCOL_EIGRP           => 0x58;
127use constant NF_IPv6_PROTOCOL_OSPF            => 0x59;
128use constant NF_IPv6_PROTOCOL_ETHERIP         => 0x61;
129use constant NF_IPv6_PROTOCOL_PIM             => 0x67;
130use constant NF_IPv6_PROTOCOL_VRRP            => 0x70;
131use constant NF_IPv6_PROTOCOL_STP             => 0x76;
132use constant NF_IPv6_PROTOCOL_SCTP            => 0x84;
133use constant NF_IPv6_PROTOCOL_IPv6MOBILITY    => 0x87;
134use constant NF_IPv6_PROTOCOL_UDPLITE         => 0x88;
135
136our @AS = qw(
137   version
138   trafficClass
139   flowLabel
140   nextHeader
141   payloadLength
142   hopLimit
143   src
144   dst
145);
146__PACKAGE__->cgBuildIndices;
147__PACKAGE__->cgBuildAccessorsScalar(\@AS);
148
149BEGIN {
150   *protocol = \&nextHeader;
151}
152
153no strict 'vars';
154
155use Bit::Vector;
156
157sub new {
158   shift->SUPER::new(
159      version       => 6,
160      trafficClass  => 0,
161      flowLabel     => 0,
162      nextHeader    => NF_IPv6_PROTOCOL_TCP,
163      hopLimit      => 0xff,
164      src           => '::1',
165      dst           => '::1',
166      payloadLength => 0,
167      @_,
168   );
169}
170
171sub getLength { NF_IPv6_HDR_LEN }
172
173sub computeLengths {
174   my $self = shift;
175   my ($layers) = @_;
176
177   my $len = 0;
178   my $last;
179   my $start;
180   for my $l (@$layers) {
181      if (! $start) {
182         $start++ if $l->layer eq 'IPv6';
183         next;
184      }
185      $len += $l->getLength;
186      $last = $l;
187   }
188   if (defined($last->payload)) {
189      $len += length($last->payload);
190   }
191
192   $self->payloadLength($len);
193
194   return 1;
195}
196
197sub pack {
198   my $self = shift;
199
200   my $version      = Bit::Vector->new_Dec(4,  $self->[$__version]);
201   my $trafficClass = Bit::Vector->new_Dec(8,  $self->[$__trafficClass]);
202   my $flowLabel    = Bit::Vector->new_Dec(20, $self->[$__flowLabel]);
203   my $v32          = $version->Concat_List($trafficClass, $flowLabel);
204
205   $self->[$__raw] = $self->SUPER::pack('NnCCa*a*',
206      $v32->to_Dec,
207      $self->[$__payloadLength],
208      $self->[$__nextHeader],
209      $self->[$__hopLimit],
210      inet6Aton($self->[$__src]),
211      inet6Aton($self->[$__dst]),
212   ) or return undef;
213
214   $self->raw;
215}
216
217sub unpack {
218   my $self = shift;
219
220   my ($vTcFl, $pl, $nh, $hl, $sa, $da, $payload) =
221      $self->SUPER::unpack('NnCCa16a16 a*', $self->[$__raw])
222         or return undef;
223
224   my $v32 = Bit::Vector->new_Dec(32,  $vTcFl);
225
226   $self->[$__flowLabel]     = $v32->Chunk_Read(20,  0);
227   $self->[$__trafficClass]  = $v32->Chunk_Read( 8, 20);
228   $self->[$__version]       = $v32->Chunk_Read( 4, 28);
229   $self->[$__payloadLength] = $pl;
230   $self->[$__nextHeader]    = $nh;
231   $self->[$__hopLimit]      = $hl;
232   $self->[$__src]           = inet6Ntoa($sa);
233   $self->[$__dst]           = inet6Ntoa($da);
234
235   $self->[$__payload] = $payload;
236
237   $self;
238}
239
240sub encapsulate {
241   my $self = shift;
242
243   return $self->[$__nextLayer] if $self->[$__nextLayer];
244
245   my $types = {
246      NF_IPv6_PROTOCOL_ICMPv4()       => 'ICMPv4',
247      NF_IPv6_PROTOCOL_IGMP()         => 'IGMP',
248      NF_IPv6_PROTOCOL_IPIP()         => 'IPIP',
249      NF_IPv6_PROTOCOL_TCP()          => 'TCP',
250      NF_IPv6_PROTOCOL_EGP()          => 'EGP',
251      NF_IPv6_PROTOCOL_IGRP()         => 'IGRP',
252      NF_IPv6_PROTOCOL_CHAOS()        => 'CHAOS',
253      NF_IPv6_PROTOCOL_UDP()          => 'UDP',
254      NF_IPv6_PROTOCOL_IDP()          => 'IDP',
255      NF_IPv6_PROTOCOL_DCCP()         => 'DCCP',
256      NF_IPv6_PROTOCOL_IPv6()         => 'IPv6',
257      NF_IPv6_PROTOCOL_IPv6ROUTING()  => 'IPv6::Routing',
258      NF_IPv6_PROTOCOL_IPv6FRAGMENT() => 'IPv6::Fragment',
259      NF_IPv6_PROTOCOL_IDRP()         => 'IDRP',
260      NF_IPv6_PROTOCOL_RSVP()         => 'RSVP',
261      NF_IPv6_PROTOCOL_GRE()          => 'GRE',
262      NF_IPv6_PROTOCOL_ESP()          => 'ESP',
263      NF_IPv6_PROTOCOL_AH()           => 'AH',
264      NF_IPv6_PROTOCOL_ICMPv6()       => 'ICMPv6',
265      NF_IPv6_PROTOCOL_EIGRP()        => 'EIGRP',
266      NF_IPv6_PROTOCOL_OSPF()         => 'OSPF',
267      NF_IPv6_PROTOCOL_ETHERIP()      => 'ETHERIP',
268      NF_IPv6_PROTOCOL_PIM()          => 'PIM',
269      NF_IPv6_PROTOCOL_VRRP()         => 'VRRP',
270      NF_IPv6_PROTOCOL_STP()          => 'STP',
271      NF_IPv6_PROTOCOL_SCTP()         => 'SCTP',
272      NF_IPv6_PROTOCOL_UDPLITE()      => 'UDPLite',
273      NF_IPv6_PROTOCOL_IPv6DESTINATION() => 'IPv6::Destination',
274      NF_IPv6_PROTOCOL_IPv6MOBILITY()    => 'IPv6::Mobility',
275      NF_IPv6_PROTOCOL_IPv6HOPBYHOP()    => 'IPv6::HopByHop',
276      NF_IPv6_PROTOCOL_GGP()             => 'GGP',
277      NF_IPv6_PROTOCOL_ST()              => 'ST',
278      NF_IPv6_PROTOCOL_CBT()             => 'CBT',
279      NF_IPv6_PROTOCOL_PUP()             => 'PUP',
280      NF_IPv6_PROTOCOL_ARGUS()           => 'ARGUS',
281      NF_IPv6_PROTOCOL_EMCON()           => 'EMCON',
282      NF_IPv6_PROTOCOL_XNET()            => 'XNET',
283      NF_IPv6_PROTOCOL_MUX()             => 'MUX',
284      NF_IPv6_PROTOCOL_DCNMEAS()         => 'DCNMEAS',
285      NF_IPv6_PROTOCOL_HMP()             => 'HMP',
286      NF_IPv6_PROTOCOL_PRM()             => 'PRM',
287      NF_IPv6_PROTOCOL_TRUNK1()          => 'TRUNK1',
288      NF_IPv6_PROTOCOL_TRUNK2()          => 'TRUNK2',
289      NF_IPv6_PROTOCOL_LEAF1()           => 'LEAF1',
290      NF_IPv6_PROTOCOL_LEAF2()           => 'LEAF2',
291      NF_IPv6_PROTOCOL_3PC()             => '3PC',
292      NF_IPv6_PROTOCOL_IDPR()            => 'IDPR',
293      NF_IPv6_PROTOCOL_XTP()             => 'XTP',
294      NF_IPv6_PROTOCOL_DDP()             => 'DDP',
295      NF_IPv6_PROTOCOL_IDPRCMTP()        => 'IDPRCMTP',
296      NF_IPv6_PROTOCOL_TPPLUSPLUS()      => 'TPPlusPlus',
297      NF_IPv6_PROTOCOL_IL()              => 'IL',
298      NF_IPv6_PROTOCOL_SDRP()            => 'SDRP',
299      NF_IPv6_PROTOCOL_IPv6NONEXT()      => 'IPv6::NoNext',
300   };
301
302   $types->{$self->[$__nextHeader]} || NF_LAYER_UNKNOWN;
303}
304
305sub print {
306   my $self = shift;
307
308   my $l = $self->layer;
309   sprintf
310      "$l: version:%d  trafficClass:0x%02x  flowLabel:0x%05x  ".
311      "nextHeader:0x%02x\n".
312      "$l: payloadLength:%d  hopLimit:%d\n".
313      "$l: src:%s  dst:%s",
314         $self->[$__version], $self->[$__trafficClass], $self->[$__flowLabel],
315         $self->[$__nextHeader], $self->[$__payloadLength],
316         $self->[$__hopLimit], $self->[$__src], $self->[$__dst];
317}
318
3191;
320
321=head1 NAME
322
323Net::Frame::Layer::IPv6 - Internet Protocol v6 layer object
324
325=head1 SYNOPSIS
326
327   use Net::Frame::Layer::IPv6 qw(:consts);
328
329   # Build a layer
330   my $layer = Net::Frame::Layer::IPv6->new(
331      version       => 6,
332      trafficClass  => 0,
333      flowLabel     => 0,
334      nextHeader    => NF_IPv6_PROTOCOL_TCP,
335      hopLimit      => 0xff,
336      src           => '::1',
337      dst           => '::1',
338      payloadLength => 0,
339   );
340   $layer->pack;
341
342   print 'RAW: '.$layer->dump."\n";
343
344   # Read a raw layer
345   my $layer = Net::Frame::Layer::IPv6->new(raw = $raw);
346
347   print $layer->print."\n";
348   print 'PAYLOAD: '.unpack('H*', $layer->payload)."\n"
349      if $layer->payload;
350
351=head1 DESCRIPTION
352
353This modules implements the encoding and decoding of the IPv6 layer.
354
355RFC: ftp://ftp.rfc-editor.org/in-notes/rfc2460.txt
356
357See also B<Net::Frame::Layer> for other attributes and methods.
358
359=head1 ATTRIBUTES
360
361=over 4
362
363=item B<version> - 4 bits
364
365Version of Internet Protocol header.
366
367=item B<trafficClass> - 8 bits
368
369Traffic class field. Was Type of Service in IPv4.
370
371=item B<flowLabel> - 20 bits
372
373Flow label class field. Was IP ID in IPv4.
374
375=item B<nextHeader> - 8 bits
376
377The type of next header. Was protocol in IPv4.
378
379=item B<protocol>
380
381Is an alias for B<nextHeader>.
382
383=item B<payloadLength> - 16 bits
384
385Length in bytes of encapsulated layers (usually, that is layer 4 + layer 7).
386
387=item B<hopLimit> - 8 bits
388
389Was TTL field in IPv4.
390
391=item B<src> - 32 bits
392
393=item B<dst> - 32 bits
394
395Source and destination addresses.
396
397=back
398
399The following are inherited attributes. See B<Net::Frame::Layer> for more information.
400
401=over 4
402
403=item B<raw>
404
405=item B<payload>
406
407=item B<nextLayer>
408
409=back
410
411=head1 METHODS
412
413=over 4
414
415=item B<new>
416
417=item B<new> (hash)
418
419Object constructor. You can pass attributes that will overwrite default ones. See B<SYNOPSIS> for default values.
420
421=item B<computeLengths> ({ payloadLength => VALUE })
422
423In order to compute lengths attributes within IPv6 header, you need to pass via a hashref the number of bytes contained in IPv6 payload (that is, the sum of all layers after the IPv6 one).
424
425=back
426
427The following are inherited methods. Some of them may be overridden in this layer, and some others may not be meaningful in this layer. See B<Net::Frame::Layer> for more information.
428
429=over 4
430
431=item B<layer>
432
433=item B<computeLengths>
434
435=item B<pack>
436
437=item B<unpack>
438
439=item B<encapsulate>
440
441=item B<getLength>
442
443=item B<print>
444
445=item B<dump>
446
447=back
448
449=head1 CONSTANTS
450
451Load them: use Net::Frame::Layer::IPv6 qw(:consts);
452
453=over 4
454
455=item B<NF_IPv6_PROTOCOL_ICMPv4>
456
457=item B<NF_IPv6_PROTOCOL_IGMP>
458
459=item B<NF_IPv6_PROTOCOL_IPIP>
460
461=item B<NF_IPv6_PROTOCOL_TCP>
462
463=item B<NF_IPv6_PROTOCOL_EGP>
464
465=item B<NF_IPv6_PROTOCOL_IGRP>
466
467=item B<NF_IPv6_PROTOCOL_CHAOS>
468
469=item B<NF_IPv6_PROTOCOL_UDP>
470
471=item B<NF_IPv6_PROTOCOL_IDP>
472
473=item B<NF_IPv6_PROTOCOL_DCCP>
474
475=item B<NF_IPv6_PROTOCOL_IPv6>
476
477=item B<NF_IPv6_PROTOCOL_IPv6ROUTING>
478
479=item B<NF_IPv6_PROTOCOL_IPv6FRAGMENT>
480
481=item B<NF_IPv6_PROTOCOL_IDRP>
482
483=item B<NF_IPv6_PROTOCOL_RSVP>
484
485=item B<NF_IPv6_PROTOCOL_GRE>
486
487=item B<NF_IPv6_PROTOCOL_ESP>
488
489=item B<NF_IPv6_PROTOCOL_AH>
490
491=item B<NF_IPv6_PROTOCOL_ICMPv6>
492
493=item B<NF_IPv6_PROTOCOL_EIGRP>
494
495=item B<NF_IPv6_PROTOCOL_OSPF>
496
497=item B<NF_IPv6_PROTOCOL_ETHERIP>
498
499=item B<NF_IPv6_PROTOCOL_PIM>
500
501=item B<NF_IPv6_PROTOCOL_VRRP>
502
503=item B<NF_IPv6_PROTOCOL_STP>
504
505=item B<NF_IPv6_PROTOCOL_SCTP>
506
507=item B<NF_IPv6_PROTOCOL_UDPLITE>
508
509=item B<NF_IPv6_PROTOCOL_IPv6HOPBYHOP>
510
511=item B<NF_IPv6_PROTOCOL_GGP>
512
513=item B<NF_IPv6_PROTOCOL_ST>
514
515=item B<NF_IPv6_PROTOCOL_CBT>
516
517=item B<NF_IPv6_PROTOCOL_PUP>
518
519=item B<NF_IPv6_PROTOCOL_ARGUS>
520
521=item B<NF_IPv6_PROTOCOL_EMCON>
522
523=item B<NF_IPv6_PROTOCOL_XNET>
524
525=item B<NF_IPv6_PROTOCOL_MUX>
526
527=item B<NF_IPv6_PROTOCOL_DCNMEAS>
528
529=item B<NF_IPv6_PROTOCOL_HMP>
530
531=item B<NF_IPv6_PROTOCOL_PRM>
532
533=item B<NF_IPv6_PROTOCOL_TRUNK1>
534
535=item B<NF_IPv6_PROTOCOL_TRUNK2>
536
537=item B<NF_IPv6_PROTOCOL_LEAF1>
538
539=item B<NF_IPv6_PROTOCOL_LEAF2>
540
541=item B<NF_IPv6_PROTOCOL_3PC>
542
543=item B<NF_IPv6_PROTOCOL_IDPR>
544
545=item B<NF_IPv6_PROTOCOL_XTP>
546
547=item B<NF_IPv6_PROTOCOL_DDP>
548
549=item B<NF_IPv6_PROTOCOL_IDPRCMTP>
550
551=item B<NF_IPv6_PROTOCOL_TPPLUSPLUS>
552
553=item B<NF_IPv6_PROTOCOL_IL>
554
555=item B<NF_IPv6_PROTOCOL_SDRP>
556
557=item B<NF_IPv6_PROTOCOL_IPv6NONEXT>
558
559=item B<NF_IPv6_PROTOCOL_IPv6DESTINATION>
560
561=item B<NF_IPv6_PROTOCOL_IPv6MOBILITY>
562
563Constants for B<nextHeader> attribute.
564
565=back
566
567=head1 SEE ALSO
568
569L<Net::Frame::Layer>
570
571=head1 AUTHOR
572
573Patrice E<lt>GomoRE<gt> Auffret
574
575=head1 COPYRIGHT AND LICENSE
576
577Copyright (c) 2006-2015, Patrice E<lt>GomoRE<gt> Auffret
578
579You may distribute this module under the terms of the Artistic license.
580See LICENSE.Artistic file in the source distribution archive.
581
582=cut
583