1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // ext_hdr.h - IPv6 extension headers
15 // Defines the basic classes for accessing the extension
16 // header structures within IPv6 packets.
17 // All return types codified as TInt (Native form and signed)
24 @ingroup ip_packet_formats
36 * @addtogroup ip_packet_formats
41 * @name Additional protocol numbers
45 /** Hop-by-Hop Extension Header. See TInet6HeaderHopByHop. */
46 const TUint KProtocolInet6HopOptions = 0;
47 /** Tunneled IPv4. The next header is TInet6HeaderIP4. */
48 const TUint KProtocolInetIpip = 4;
49 /** Routing Header. See TInet6HeaderRouting. */
50 const TUint KProtocolInet6RoutingHeader = 43;
51 /** IPv6 Fragment Header. See TInet6HeaderFragment. */
52 const TUint KProtocolInet6Fragment = 44;
53 /** IPsec ESP header. See TInet6HeaderESP. */
54 const TUint KProtocolInetEsp = 50;
55 /** IPsec AH header. See TInet6HeaderAH. */
56 const TUint KProtocolInetAh = 51;
57 /** No Next Header. */
58 const TUint KProtocolInet6NoNextHeader = 59;
59 /** Destination Options Extension Header. See TInet6Options. */
60 const TUint KProtocolInet6DestinationOptions = 60;
64 // TInet6HeaderExtension
65 // *********************
66 class TInet6HeaderExtension
68 * Basic part of normal IPv6 extension headers.
70 * This is simple class to be used in scanning the extension headers
71 * which are known to follow the following format:
73 * - 1st octet = Next Header field
75 * - 2nd octet = Length of the extension header (= (x+1)*8 octets)
78 * Extension headers do not need to follow this format. Unknown
79 * headers cannot be skipped over by just assuming this format!
86 inline static TInt MinHeaderLength() {return 8; }
87 inline static TInt MaxHeaderLength() {return 8; }
89 inline TUint8* EndPtr() { return i + HeaderLength(); }
90 inline TInt NextHeader() const { return i[0]; }
91 inline TInt HdrExtLen() const { return i[1]; } // Return raw value
92 inline TInt HeaderLength() const { return (i[1]+1) << 3; } // Return true byte length
97 TUint32 iAlign; // A dummy member to force the 4 byte alignment
102 class TInet6HeaderHBH
104 * IPv6 Hop-by-hop options header.
108 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109 | Next Header | Hdr Ext Len | |
110 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118 Next Header 8-bit selector. Identifies the type of header
119 immediately following the Hop-by-Hop Options
120 header. Uses the same values as the IPv4
121 Protocol field [RFC-1700 et seq.].
123 Hdr Ext Len 8-bit unsigned integer. Length of the Hop-by-
124 Hop Options header in 8-octet units, not
125 including the first 8 octets.
127 Options Variable-length field, of length such that the
128 complete Hop-by-Hop Options header is an integer
129 multiple of 8 octets long. Contains one or more
130 TLV-encoded options, as described in section
135 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
136 | Option Type | Opt Data Len | Option Data
137 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
139 Option Type 8-bit identifier of the type of option.
141 Opt Data Len 8-bit unsigned integer. Length of the Option
142 Data field of this option, in octets.
144 Option Data Variable-length field. Option-Type-specific
152 inline TInt HeaderLength() const
154 return (i[1]+1) << 3; // Return length in octets.
157 inline TUint8* EndPtr() { return i + HeaderLength(); }
159 inline static TInt MinHeaderLength() {return 8; }
160 inline static TInt MaxHeaderLength() {return 8; }
163 // Access, Get Hop By Hop header values from the packet
165 inline TInt NextHeader() const
171 inline TInt OptionType() const
172 /** @return The type of the first option */
176 inline TInt OptionDataLen() const
177 /** @return The data length of the first option */
183 // Access, SET Hop By Hop header values
185 inline void SetHdrExtLen(TInt aLength)
187 i[1]=(TUint8)aLength;
190 inline void SetNextHeader(TInt aNext)
196 inline void SetOptionType(TInt aType)
197 /** Sets type of the first option.*/
202 inline void SetOptionDataLen(TInt aLength)
203 /** Sets data length of the first option.*/
205 i[3]=(TUint8)aLength;
212 TUint32 iAlign; // A dummy member to force the 4 byte alignment
217 class TInet6HeaderHopByHop
219 * IPv6 Hop-by-hop options header.
222 * Because of the non-standard method naming and
223 * semantics. Use TInet6HeaderHBH instead.
227 inline TInt HeaderLength() const
232 inline TUint8* EndPtr() { return i + HeaderLength() * 8 + MinHeaderLength(); }
234 inline static TInt MinHeaderLength() {return 8; }
235 inline static TInt MaxHeaderLength() {return 8; }
238 // Access, Get Hop By Hop header values from the packet
240 inline TInt NextHeader() const
241 /** @return The length in 8-byte units! (non-standard, should be bytes!) */
247 inline TInt OptionType() const
248 /** @return The type of the first option */
252 inline TInt OptionDataLen() const
253 /** @return The data length of the first option */
259 // Access, SET Hop By Hop header values
261 inline void SetHeaderLength(TInt aLength)
263 i[1]=(TUint8)aLength;
266 inline void SetNextHeader(TInt aNext)
272 inline void SetOptionType(TInt aType)
273 /** Sets type of the first option.*/
278 inline void SetOptionDataLen(TInt aLength)
279 /** Sets data length of the first option.*/
281 i[3]=(TUint8)aLength;
288 TUint32 iAlign; // A dummy member to force the 4 byte alignment
292 class TInet6HeaderRouting
294 * IPv6 Routing Header.
295 * The Type 0 Routing header has the following format:
298 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
299 | Next Header | Hdr Ext Len | Routing Type=0| Segments Left |
300 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
302 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
310 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
318 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
322 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
330 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
332 Next Header 8-bit selector. Identifies the type of header
333 immediately following the Routing header. Uses
334 the same values as the IPv4 Protocol field
337 Hdr Ext Len 8-bit unsigned integer. Length of the Routing
338 header in 8-octet units, not including the first
339 8 octets. For the Type 0 Routing header, Hdr
340 Ext Len is equal to two times the number of
341 addresses in the header.
346 Segments Left 8-bit unsigned integer. Number of route
347 segments remaining, i.e., number of explicitly
348 listed intermediate nodes still to be visited
349 before reaching the final destination.
351 Reserved 32-bit reserved field. Initialized to zero for
352 transmission; ignored on reception.
354 Address[1..n] Vector of 128-bit addresses, numbered 1 to n.
357 * This header mapping describes only the fixed part, without
364 inline static TInt MinHeaderLength() {return 8; }
365 inline static TInt MaxHeaderLength() {return 8; }
367 inline TUint8* EndPtr() { return i + HeaderLength(); }
378 inline TInt NextHeader() const { return i[0]; }
379 inline TInt HdrExtLen() const { return i[1]; } // Return raw value
380 inline TInt HeaderLength() const { return (i[1]+1) << 3; } // Return true byte length
381 inline TInt RoutingType() const { return i[2]; }
382 inline TInt SegmentsLeft() const { return i[3]; }
385 inline void SetNextHeader(TInt aNext) { i[0] = (TInt8)aNext; }
386 inline void SetHdrExtLen(TInt aLen) { i[1] = (TUint8)aLen; }
387 inline void SetRoutingType(TInt aType) { i[2] = (TUint8)aType; }
388 inline void SetSegmentsLeft(TInt aValue) { i[3] = (TUint8)aValue; }
394 TUint32 iAlign; // A dummy member to force the 4 byte alignment
402 * IPv6 Option extension headers (Hop-by-Hop, Destination Options).
405 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
406 | Next Header | Hdr Ext Len | |
407 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
413 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
415 Next Header 8-bit selector. Identifies the type of header
416 immediately following the Destination Options
417 header. Uses the same values as the IPv4
418 Protocol field [RFC-1700 et seq.].
420 Hdr Ext Len 8-bit unsigned integer. Length of the
421 Destination Options header in 8-octet units, not
422 including the first 8 octets.
424 Options Variable-length field, of length such that the
425 complete Destination Options header is an
426 integer multiple of 8 octets long. Contains one
427 or more TLV-encoded options, as described in
430 * This mapping describes only the minimal 8 bytes.
436 inline TInt HeaderLength() const { return (i[1]+1) << 3; } // Return true byte length
438 inline static TInt MinHeaderLength() {return 8; }
439 inline static TInt MaxHeaderLength() {return 8; }
441 inline TUint8* EndPtr() { return i + HeaderLength(); }
450 inline TInt NextHeader() const { return i[0]; }
451 inline TInt HdrExtLen() const { return i[1]; } // Return raw value
453 inline void SetNextHeader(TInt aNext) { i[0] = (TInt8)aNext; }
454 inline void SetHdrExtLen(TInt aLen) { i[1] = (TUint8)aLen; }
462 * @name Destination option types.
466 /** One octet padding. */
467 const TUint8 KDstOptionPad1 = 0;
468 /** N octets padding */
469 const TUint8 KDstOptionPadN = 1;
470 /** not used? (MIP6) */
471 const TUint8 KDstOptionBindingAck = 7;
472 /** not used? (MIP6) */
473 const TUint8 KDstOptionBindingRequest = 8;
474 /** not used? (MIP6) */
475 const TUint8 KDstOptionBindingUpdate = 0xC6;
476 /** Home Address option (MIP6) */
477 const TUint8 KDstOptionHomeAddress = 0xC9;
480 class TInet6OptionBase
482 * IPv6 Option value header.
484 * A basic class for handling Type-Length-Value (TLV) options.
487 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
488 | Option Type | Opt Data Len | Option Data
489 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
491 Option Type 8-bit identifier of the type of option.
493 Opt Data Len 8-bit unsigned integer. Length of the Option
494 Data field of this option, in octets.
496 Option Data Variable-length field. Option-Type-specific
499 * Option values are used inside option headers (for example:
500 * Hop-by-Hop options and Destination options).
507 inline static TInt MinHeaderLength() { return 2; }
508 inline static TInt MaxHeaderLength() { return 2; }
510 inline TInt Type() const { return i[0]; }
511 inline TInt HeaderLength() const { return i[1] + 2; }
513 inline void SetType(TInt aType) { i[0] = (TUint8)aType; }
514 inline void SetDataLen(TInt aLen) { i[1] = (TUint8)aLen; }
516 inline TUint8* EndPtr() { return i + HeaderLength(); }
522 class TInet6DstOptionBase
524 * IPv6 Option value header.
527 * Because of the non-standard method naming and
528 * semantics. Use TInet6OptionBase instead.
532 inline static TInt MinHeaderLength() { return 2; }
533 inline static TInt MaxHeaderLength() { return 2; }
535 inline TInt Type() const { return i[0]; }
536 inline TInt HeaderLength() const { return i[1]; }
538 inline void SetType(TInt aType) { i[0] = (TUint8)aType; }
539 inline void SetHeaderLength(TInt aLen) { i[1] = (TUint8)aLen; }
541 inline TUint8* EndPtr() { return i + 2 + HeaderLength(); }
548 class TInet6HeaderFragment
550 * IPv6 Fragment Header.
554 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
555 | Next Header | Reserved | Fragment Offset |Res|M|
556 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
558 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
560 Next Header 8-bit selector. Identifies the initial header
561 type of the Fragmentable Part of the original
562 packet (defined below). Uses the same values as
563 the IPv4 Protocol field [RFC-1700 et seq.].
565 Reserved 8-bit reserved field. Initialized to zero for
566 transmission; ignored on reception.
568 Fragment Offset 13-bit unsigned integer. The offset, in 8-octet
569 units, of the data following this header,
570 relative to the start of the Fragmentable Part
571 of the original packet.
573 Res 2-bit reserved field. Initialized to zero for
574 transmission; ignored on reception.
576 M flag 1 = more fragments; 0 = last fragment.
578 Identification 32 bits. See description below.
590 inline TInt HeaderLength() const
595 inline TUint8* EndPtr() { return i + HeaderLength(); }
597 inline static TInt MinHeaderLength() {return 8; }
598 inline static TInt MaxHeaderLength() {return 8; }
601 // Access, Get Fragmentation header values from the packet
603 inline TInt NextHeader() const { return i[0]; }
605 inline TInt FragmentOffset() const
608 // The Offset is returned as octet count (3 righmost bits are zero)
610 return ((i[2] << 8) + i[3]) & 0xfff8;
613 inline TInt MFlag() const
618 inline TInt32 Id() const
620 return *(TInt32 *)(&i[4]); // *ASSUMES* proper aligment!!!
625 inline void ZeroAll()
627 *((TInt32 *)&i[0]) = 0; // *ASSUMES* proper aligment!!!
628 *((TInt32 *)&i[4]) = 0; // *ASSUMES* proper aligment!!!
630 inline void SetNextHeader(TInt aNext)
632 i[0] = (TUint8)aNext;
634 inline void SetFragmentOffset(TInt aOffset)
637 // The aOffset is assumed to be given in octets. The least significant
638 // 3 bits should be ZERO (bits are just masked away).
640 i[2]=(TUint8)(aOffset >> 8);
641 i[3]=(TUint8)((i[3] & 0x7) | (aOffset & ~0x7));
644 inline void SetMFlag(TInt aFlag)
646 i[3]= (TUint8)((i[3] & ~0x1) | (aFlag & 0x1));
649 inline void SetId(TInt32 aId)
651 *((TInt32 *)&i[4]) = aId; // *ASSUMES* proper aligment!!!
657 TUint32 iAlign; // A dummy member to force the 4 byte alignment
663 * IPsec Authentication Header.
665 * The function parameters and return values are in host order,
666 * except SPI, which is always in network byte order.
668 Extract from RFC-2402
671 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
672 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
673 | Next Header | Payload Len | RESERVED |
674 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
675 | Security Parameters Index (SPI) |
676 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
677 | Sequence Number Field |
678 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
680 + Authentication Data (variable) |
682 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
692 inline static TInt MinHeaderLength() {return 3*4; }
693 inline static TInt MaxHeaderLength() {return 3*4; }
694 inline TUint8 *EndPtr() {return i + HeaderLength();}
696 // Access, get values
698 inline TInt NextHeader() const
703 // PayloadLength returns the raw value
705 inline TInt PayloadLength() const
710 // *NOTE* AH is called IPv6 extension header, but its
711 // length field semantics does not follow the normal
712 // IPv6 extension header logic (it follows the IPv4)
714 inline TInt HeaderLength() const
716 return (i[1]+2) << 2; // IPv4 and IPv6
719 // SPI is returned in network byte order
721 inline TUint32 SPI() const
723 return *((TUint32 *)(i + 4));
725 inline TUint32 Sequence() const
727 return (i[8] << 24) | (i[9] << 16) | (i[10] << 8) | i[11];
730 // The length of the Authentication Data (in octets).
731 // *NOTE* This will include the potential padding! -- msa
732 inline TInt DataLength() const {
733 return HeaderLength() - 12;
737 return TPtr8((TUint8 *)&i[12], DataLength(), DataLength());
742 inline void SetNextHeader(TInt aNext)
744 i[0] = (TUint8)aNext;
746 inline void SetPayloadLength(TInt aByte)
748 i[1] = (TUint8)aByte;
751 // *NOTE* AH is called IPv6 extension header, but its
752 // length field semantics does not follow the normal
753 // IPv6 extension header logic (it follows the IPv4)
754 // As this is bit tricky, a "cooked version" of PayloadLength
755 // setting is also provided (e.g. take in bytes, and compute
756 // the real payload length value) -- msa
757 inline void SetHeaderLength(TInt aLength)
759 i[1] = (TUint8)((aLength >> 2) - 2);
761 inline void SetSPI(TUint32 aSPI)
763 *((TUint32 *)(i + 4)) = aSPI;
765 inline void SetReserved(TInt aValue)
767 i[3] = (TUint8)aValue;
768 i[2] = (TUint8)(aValue >> 8);
770 inline void SetSequence(TUint32 aSeq)
772 i[11] = (TUint8)aSeq;
773 i[10] = (TUint8)(aSeq >> 8);
774 i[9] = (TUint8)(aSeq >> 16);
775 i[8] = (TUint8)(aSeq >> 24);
781 TUint32 iAlign; // A dummy member to force the 4 byte alignment
787 class TInet6HeaderESP
789 * IPsec Encapsulating Security Payload Packet Format.
791 * The function parameters and return values are in host
792 * order (except SPI, which is always in network byte order)
797 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
798 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----
799 | Security Parameters Index (SPI) | ^Auth.
800 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov-
801 | Sequence Number | |erage
802 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ----
803 | Payload Data* (variable) | | ^
806 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov-
807 | | Padding (0-255 bytes) | |erage*
808 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
809 | | Pad Length | Next Header | v v
810 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ------
811 | Authentication Data (variable) |
814 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
816 * This only defines the fixed portion of the ESP, 8 bytes).
825 inline static TInt MinHeaderLength() {return 2*4; }
826 inline static TInt MaxHeaderLength() {return 2*4; }
827 inline TInt HeaderLength() const {return 2*4; }
828 inline TUint8 *EndPtr() {return i + HeaderLength();}
831 // Access, get values
834 // SPI is returned in network byte order
836 inline TUint32 SPI() const
838 return *((TUint32 *)(i + 0));
840 inline TUint32 Sequence() const
842 return (i[4] << 24) | (i[5] << 16) | (i[6] << 8) | i[7];
845 // IV is not exactly part of the header, but provide
846 // a method that returns a Ptr to it (assuming the
847 // IV is accessible directly after the fixed part).
849 inline TPtr8 IV(TInt aLen)
851 return TPtr8((TUint8 *)&i[sizeof(i)], aLen, aLen);
857 inline void SetSPI(TUint32 aSPI)
859 *((TUint32 *)(i + 0)) = aSPI;
861 inline void SetSequence(TUint32 aSeq)
864 i[6] = (TUint8)(aSeq >> 8);
865 i[5] = (TUint8)(aSeq >> 16);
866 i[4] = (TUint8)(aSeq >> 24);
872 TUint32 iAlign; // A dummy member to force the 4 byte alignment