williamr@2: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@2: // All rights reserved. williamr@2: // This component and the accompanying materials are made available williamr@2: // 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 williamr@2: // which accompanies this distribution, and is available williamr@2: // at the URL "http://www.symbianfoundation.org/legal/licencesv10.html". williamr@2: // williamr@2: // Initial Contributors: williamr@2: // Nokia Corporation - initial contribution. williamr@2: // williamr@2: // Contributors: williamr@2: // williamr@2: // Description: williamr@2: // ext_hdr.h - IPv6 extension headers williamr@2: // Defines the basic classes for accessing the extension williamr@2: // header structures within IPv6 packets. williamr@2: // All return types codified as TInt (Native form and signed) williamr@2: // williamr@2: williamr@2: williamr@2: williamr@2: /** williamr@2: @file ext_hdr.h williamr@2: @ingroup ip_packet_formats williamr@2: @publishedAll williamr@2: @released williamr@2: */ williamr@2: williamr@2: #ifndef __EXT_HDR_H__ williamr@2: #define __EXT_HDR_H__ williamr@2: williamr@2: #include williamr@2: #include "in_hdr.h" williamr@2: williamr@2: /** williamr@2: * @addtogroup ip_packet_formats williamr@2: * @{ williamr@2: */ williamr@2: williamr@2: /** williamr@2: * @name Additional protocol numbers williamr@2: * williamr@2: * @{ williamr@2: */ williamr@2: /** Hop-by-Hop Extension Header. See TInet6HeaderHopByHop. */ williamr@2: const TUint KProtocolInet6HopOptions = 0; williamr@2: /** Tunneled IPv4. The next header is TInet6HeaderIP4. */ williamr@2: const TUint KProtocolInetIpip = 4; williamr@2: /** Routing Header. See TInet6HeaderRouting. */ williamr@2: const TUint KProtocolInet6RoutingHeader = 43; williamr@2: /** IPv6 Fragment Header. See TInet6HeaderFragment. */ williamr@2: const TUint KProtocolInet6Fragment = 44; williamr@2: /** IPsec ESP header. See TInet6HeaderESP. */ williamr@2: const TUint KProtocolInetEsp = 50; williamr@2: /** IPsec AH header. See TInet6HeaderAH. */ williamr@2: const TUint KProtocolInetAh = 51; williamr@2: /** No Next Header. */ williamr@2: const TUint KProtocolInet6NoNextHeader = 59; williamr@2: /** Destination Options Extension Header. See TInet6Options. */ williamr@2: const TUint KProtocolInet6DestinationOptions = 60; williamr@2: /* @} */ williamr@2: williamr@2: // williamr@2: // TInet6HeaderExtension williamr@2: // ********************* williamr@2: class TInet6HeaderExtension williamr@2: /** williamr@2: * Basic part of normal IPv6 extension headers. williamr@2: * williamr@2: * This is simple class to be used in scanning the extension headers williamr@2: * which are known to follow the following format: williamr@2: * williamr@2: * - 1st octet = Next Header field williamr@2: * williamr@2: * - 2nd octet = Length of the extension header (= (x+1)*8 octets) williamr@2: * williamr@2: * @note williamr@2: * Extension headers do not need to follow this format. Unknown williamr@2: * headers cannot be skipped over by just assuming this format! williamr@2: * williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline static TInt MinHeaderLength() {return 8; } williamr@2: inline static TInt MaxHeaderLength() {return 8; } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength(); } williamr@2: inline TInt NextHeader() const { return i[0]; } williamr@2: inline TInt HdrExtLen() const { return i[1]; } // Return raw value williamr@2: inline TInt HeaderLength() const { return (i[1]+1) << 3; } // Return true byte length williamr@2: private: williamr@2: union williamr@2: { williamr@2: TUint8 i[8]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: williamr@2: class TInet6HeaderHBH williamr@2: /** williamr@2: * IPv6 Hop-by-hop options header. williamr@2: @verbatim williamr@2: From RFC 2460 williamr@2: williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Next Header | Hdr Ext Len | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + williamr@2: | | williamr@2: . . williamr@2: . Options . williamr@2: . . williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: williamr@2: Next Header 8-bit selector. Identifies the type of header williamr@2: immediately following the Hop-by-Hop Options williamr@2: header. Uses the same values as the IPv4 williamr@2: Protocol field [RFC-1700 et seq.]. williamr@2: williamr@2: Hdr Ext Len 8-bit unsigned integer. Length of the Hop-by- williamr@2: Hop Options header in 8-octet units, not williamr@2: including the first 8 octets. williamr@2: williamr@2: Options Variable-length field, of length such that the williamr@2: complete Hop-by-Hop Options header is an integer williamr@2: multiple of 8 octets long. Contains one or more williamr@2: TLV-encoded options, as described in section williamr@2: 4.2. williamr@2: williamr@2: And Options is: williamr@2: williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - williamr@2: | Option Type | Opt Data Len | Option Data williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - williamr@2: williamr@2: Option Type 8-bit identifier of the type of option. williamr@2: williamr@2: Opt Data Len 8-bit unsigned integer. Length of the Option williamr@2: Data field of this option, in octets. williamr@2: williamr@2: Option Data Variable-length field. Option-Type-specific williamr@2: data. williamr@2: @endverbatim williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline TInt HeaderLength() const williamr@2: { williamr@2: return (i[1]+1) << 3; // Return length in octets. williamr@2: } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength(); } williamr@2: williamr@2: inline static TInt MinHeaderLength() {return 8; } williamr@2: inline static TInt MaxHeaderLength() {return 8; } williamr@2: williamr@2: // williamr@2: // Access, Get Hop By Hop header values from the packet williamr@2: // williamr@2: inline TInt NextHeader() const williamr@2: { williamr@2: return i[0]; williamr@2: } williamr@2: williamr@2: //From Options williamr@2: inline TInt OptionType() const williamr@2: /** @return The type of the first option */ williamr@2: { williamr@2: return i[2]; williamr@2: } williamr@2: inline TInt OptionDataLen() const williamr@2: /** @return The data length of the first option */ williamr@2: { williamr@2: return i[3]; williamr@2: } williamr@2: williamr@2: // williamr@2: // Access, SET Hop By Hop header values williamr@2: // williamr@2: inline void SetHdrExtLen(TInt aLength) williamr@2: { williamr@2: i[1]=(TUint8)aLength; williamr@2: } williamr@2: williamr@2: inline void SetNextHeader(TInt aNext) williamr@2: { williamr@2: i[0]=(TUint8)aNext; williamr@2: } williamr@2: williamr@2: //From Options williamr@2: inline void SetOptionType(TInt aType) williamr@2: /** Sets type of the first option.*/ williamr@2: { williamr@2: i[2]=(TUint8)aType; williamr@2: } williamr@2: williamr@2: inline void SetOptionDataLen(TInt aLength) williamr@2: /** Sets data length of the first option.*/ williamr@2: { williamr@2: i[3]=(TUint8)aLength; williamr@2: } williamr@2: williamr@2: private: williamr@2: union williamr@2: { williamr@2: TUint8 i[8]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: williamr@2: class TInet6HeaderHopByHop williamr@2: /** williamr@2: * IPv6 Hop-by-hop options header. williamr@2: * @publishedAll williamr@2: * @deprecated williamr@2: * Because of the non-standard method naming and williamr@2: * semantics. Use TInet6HeaderHBH instead. williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline TInt HeaderLength() const williamr@2: { williamr@2: return i[1]; williamr@2: } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength() * 8 + MinHeaderLength(); } williamr@2: williamr@2: inline static TInt MinHeaderLength() {return 8; } williamr@2: inline static TInt MaxHeaderLength() {return 8; } williamr@2: williamr@2: // williamr@2: // Access, Get Hop By Hop header values from the packet williamr@2: // williamr@2: inline TInt NextHeader() const williamr@2: /** @return The length in 8-byte units! (non-standard, should be bytes!) */ williamr@2: { williamr@2: return i[0]; williamr@2: } williamr@2: williamr@2: //From Options williamr@2: inline TInt OptionType() const williamr@2: /** @return The type of the first option */ williamr@2: { williamr@2: return i[2]; williamr@2: } williamr@2: inline TInt OptionDataLen() const williamr@2: /** @return The data length of the first option */ williamr@2: { williamr@2: return i[3]; williamr@2: } williamr@2: williamr@2: // williamr@2: // Access, SET Hop By Hop header values williamr@2: // williamr@2: inline void SetHeaderLength(TInt aLength) williamr@2: { williamr@2: i[1]=(TUint8)aLength; williamr@2: } williamr@2: williamr@2: inline void SetNextHeader(TInt aNext) williamr@2: { williamr@2: i[0]=(TUint8)aNext; williamr@2: } williamr@2: williamr@2: //From Options williamr@2: inline void SetOptionType(TInt aType) williamr@2: /** Sets type of the first option.*/ williamr@2: { williamr@2: i[2]=(TUint8)aType; williamr@2: } williamr@2: williamr@2: inline void SetOptionDataLen(TInt aLength) williamr@2: /** Sets data length of the first option.*/ williamr@2: { williamr@2: i[3]=(TUint8)aLength; williamr@2: } williamr@2: williamr@2: private: williamr@2: union williamr@2: { williamr@2: TUint8 i[8]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: class TInet6HeaderRouting williamr@2: /** williamr@2: * IPv6 Routing Header. williamr@2: * The Type 0 Routing header has the following format: williamr@2: @verbatim williamr@2: williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Next Header | Hdr Ext Len | Routing Type=0| Segments Left | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Reserved | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: + Address[1] + williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: + Address[2] + williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: . . . williamr@2: . . . williamr@2: . . . williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: + Address[n] + williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: williamr@2: Next Header 8-bit selector. Identifies the type of header williamr@2: immediately following the Routing header. Uses williamr@2: the same values as the IPv4 Protocol field williamr@2: [RFC-1700 et seq.]. williamr@2: williamr@2: Hdr Ext Len 8-bit unsigned integer. Length of the Routing williamr@2: header in 8-octet units, not including the first williamr@2: 8 octets. For the Type 0 Routing header, Hdr williamr@2: Ext Len is equal to two times the number of williamr@2: addresses in the header. williamr@2: williamr@2: Routing Type 0. williamr@2: williamr@2: williamr@2: Segments Left 8-bit unsigned integer. Number of route williamr@2: segments remaining, i.e., number of explicitly williamr@2: listed intermediate nodes still to be visited williamr@2: before reaching the final destination. williamr@2: williamr@2: Reserved 32-bit reserved field. Initialized to zero for williamr@2: transmission; ignored on reception. williamr@2: williamr@2: Address[1..n] Vector of 128-bit addresses, numbered 1 to n. williamr@2: williamr@2: @endverbatim williamr@2: * This header mapping describes only the fixed part, without williamr@2: * any addresses. williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline static TInt MinHeaderLength() {return 8; } williamr@2: inline static TInt MaxHeaderLength() {return 8; } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength(); } williamr@2: williamr@2: enum TOffsets williamr@2: { williamr@2: O_NextHeader, williamr@2: O_HdrExtLen, williamr@2: O_RoutingType, williamr@2: O_SegmentsLeft, williamr@2: O_Address = 8 williamr@2: }; williamr@2: williamr@2: inline TInt NextHeader() const { return i[0]; } williamr@2: inline TInt HdrExtLen() const { return i[1]; } // Return raw value williamr@2: inline TInt HeaderLength() const { return (i[1]+1) << 3; } // Return true byte length williamr@2: inline TInt RoutingType() const { return i[2]; } williamr@2: inline TInt SegmentsLeft() const { return i[3]; } williamr@2: williamr@2: //SET williamr@2: inline void SetNextHeader(TInt aNext) { i[0] = (TInt8)aNext; } williamr@2: inline void SetHdrExtLen(TInt aLen) { i[1] = (TUint8)aLen; } williamr@2: inline void SetRoutingType(TInt aType) { i[2] = (TUint8)aType; } williamr@2: inline void SetSegmentsLeft(TInt aValue) { i[3] = (TUint8)aValue; } williamr@2: williamr@2: private: williamr@2: union williamr@2: { williamr@2: TUint8 i[8]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: williamr@2: williamr@2: class TInet6Options williamr@2: /** williamr@2: * IPv6 Option extension headers (Hop-by-Hop, Destination Options). williamr@2: * williamr@2: @verbatim williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Next Header | Hdr Ext Len | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + williamr@2: | | williamr@2: . . williamr@2: . Options . williamr@2: . . williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: williamr@2: Next Header 8-bit selector. Identifies the type of header williamr@2: immediately following the Destination Options williamr@2: header. Uses the same values as the IPv4 williamr@2: Protocol field [RFC-1700 et seq.]. williamr@2: williamr@2: Hdr Ext Len 8-bit unsigned integer. Length of the williamr@2: Destination Options header in 8-octet units, not williamr@2: including the first 8 octets. williamr@2: williamr@2: Options Variable-length field, of length such that the williamr@2: complete Destination Options header is an williamr@2: integer multiple of 8 octets long. Contains one williamr@2: or more TLV-encoded options, as described in williamr@2: section 4.2. williamr@2: @endverbatim williamr@2: * This mapping describes only the minimal 8 bytes. williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline TInt HeaderLength() const { return (i[1]+1) << 3; } // Return true byte length williamr@2: williamr@2: inline static TInt MinHeaderLength() {return 8; } williamr@2: inline static TInt MaxHeaderLength() {return 8; } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength(); } williamr@2: williamr@2: enum TOffsets williamr@2: { williamr@2: O_NextHeader, williamr@2: O_HdrExtLen, williamr@2: O_Options williamr@2: }; williamr@2: williamr@2: inline TInt NextHeader() const { return i[0]; } williamr@2: inline TInt HdrExtLen() const { return i[1]; } // Return raw value williamr@2: williamr@2: inline void SetNextHeader(TInt aNext) { i[0] = (TInt8)aNext; } williamr@2: inline void SetHdrExtLen(TInt aLen) { i[1] = (TUint8)aLen; } williamr@2: williamr@2: private: williamr@2: TUint8 i[8]; williamr@2: }; williamr@2: williamr@2: williamr@2: /** williamr@2: * @name Destination option types. williamr@2: * williamr@2: * @{ williamr@2: */ williamr@2: /** One octet padding. */ williamr@2: const TUint8 KDstOptionPad1 = 0; williamr@2: /** N octets padding */ williamr@2: const TUint8 KDstOptionPadN = 1; williamr@2: /** not used? (MIP6) */ williamr@2: const TUint8 KDstOptionBindingAck = 7; williamr@2: /** not used? (MIP6) */ williamr@2: const TUint8 KDstOptionBindingRequest = 8; williamr@2: /** not used? (MIP6) */ williamr@2: const TUint8 KDstOptionBindingUpdate = 0xC6; williamr@2: /** Home Address option (MIP6) */ williamr@2: const TUint8 KDstOptionHomeAddress = 0xC9; williamr@2: /** @} */ williamr@2: williamr@2: class TInet6OptionBase williamr@2: /** williamr@2: * IPv6 Option value header. williamr@2: * williamr@2: * A basic class for handling Type-Length-Value (TLV) options. williamr@2: * williamr@2: @verbatim williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - williamr@2: | Option Type | Opt Data Len | Option Data williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - williamr@2: williamr@2: Option Type 8-bit identifier of the type of option. williamr@2: williamr@2: Opt Data Len 8-bit unsigned integer. Length of the Option williamr@2: Data field of this option, in octets. williamr@2: williamr@2: Option Data Variable-length field. Option-Type-specific williamr@2: data. williamr@2: @endverbatim williamr@2: * Option values are used inside option headers (for example: williamr@2: * Hop-by-Hop options and Destination options). williamr@2: * williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline static TInt MinHeaderLength() { return 2; } williamr@2: inline static TInt MaxHeaderLength() { return 2; } williamr@2: williamr@2: inline TInt Type() const { return i[0]; } williamr@2: inline TInt HeaderLength() const { return i[1] + 2; } williamr@2: williamr@2: inline void SetType(TInt aType) { i[0] = (TUint8)aType; } williamr@2: inline void SetDataLen(TInt aLen) { i[1] = (TUint8)aLen; } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength(); } williamr@2: williamr@2: private: williamr@2: TUint8 i[2]; williamr@2: }; williamr@2: williamr@2: class TInet6DstOptionBase williamr@2: /** williamr@2: * IPv6 Option value header. williamr@2: * @publishedAll williamr@2: * @deprecated williamr@2: * Because of the non-standard method naming and williamr@2: * semantics. Use TInet6OptionBase instead. williamr@2: */ williamr@2: { williamr@2: public: williamr@2: inline static TInt MinHeaderLength() { return 2; } williamr@2: inline static TInt MaxHeaderLength() { return 2; } williamr@2: williamr@2: inline TInt Type() const { return i[0]; } williamr@2: inline TInt HeaderLength() const { return i[1]; } williamr@2: williamr@2: inline void SetType(TInt aType) { i[0] = (TUint8)aType; } williamr@2: inline void SetHeaderLength(TInt aLen) { i[1] = (TUint8)aLen; } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + 2 + HeaderLength(); } williamr@2: williamr@2: private: williamr@2: TUint8 i[2]; williamr@2: }; williamr@2: williamr@2: williamr@2: class TInet6HeaderFragment williamr@2: /** williamr@2: * IPv6 Fragment Header. williamr@2: @verbatim williamr@2: RFC2460 williamr@2: williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Next Header | Reserved | Fragment Offset |Res|M| williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Identification | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: williamr@2: Next Header 8-bit selector. Identifies the initial header williamr@2: type of the Fragmentable Part of the original williamr@2: packet (defined below). Uses the same values as williamr@2: the IPv4 Protocol field [RFC-1700 et seq.]. williamr@2: williamr@2: Reserved 8-bit reserved field. Initialized to zero for williamr@2: transmission; ignored on reception. williamr@2: williamr@2: Fragment Offset 13-bit unsigned integer. The offset, in 8-octet williamr@2: units, of the data following this header, williamr@2: relative to the start of the Fragmentable Part williamr@2: of the original packet. williamr@2: williamr@2: Res 2-bit reserved field. Initialized to zero for williamr@2: transmission; ignored on reception. williamr@2: williamr@2: M flag 1 = more fragments; 0 = last fragment. williamr@2: williamr@2: Identification 32 bits. See description below. williamr@2: @endverbatim williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: enum TOffsets williamr@2: { williamr@2: O_FragmentOffset = 2 williamr@2: }; williamr@2: williamr@2: inline TInt HeaderLength() const williamr@2: { williamr@2: return 8; williamr@2: } williamr@2: williamr@2: inline TUint8* EndPtr() { return i + HeaderLength(); } williamr@2: williamr@2: inline static TInt MinHeaderLength() {return 8; } williamr@2: inline static TInt MaxHeaderLength() {return 8; } williamr@2: williamr@2: // williamr@2: // Access, Get Fragmentation header values from the packet williamr@2: // williamr@2: inline TInt NextHeader() const { return i[0]; } williamr@2: williamr@2: inline TInt FragmentOffset() const williamr@2: { williamr@2: // williamr@2: // The Offset is returned as octet count (3 righmost bits are zero) williamr@2: // williamr@2: return ((i[2] << 8) + i[3]) & 0xfff8; williamr@2: } williamr@2: williamr@2: inline TInt MFlag() const williamr@2: { williamr@2: return i[3] & 0x01; williamr@2: } williamr@2: williamr@2: inline TInt32 Id() const williamr@2: { williamr@2: return *(TInt32 *)(&i[4]); // *ASSUMES* proper aligment!!! williamr@2: } williamr@2: // williamr@2: // Building methods williamr@2: // williamr@2: inline void ZeroAll() williamr@2: { williamr@2: *((TInt32 *)&i[0]) = 0; // *ASSUMES* proper aligment!!! williamr@2: *((TInt32 *)&i[4]) = 0; // *ASSUMES* proper aligment!!! williamr@2: } williamr@2: inline void SetNextHeader(TInt aNext) williamr@2: { williamr@2: i[0] = (TUint8)aNext; williamr@2: } williamr@2: inline void SetFragmentOffset(TInt aOffset) williamr@2: { williamr@2: // williamr@2: // The aOffset is assumed to be given in octets. The least significant williamr@2: // 3 bits should be ZERO (bits are just masked away). williamr@2: // williamr@2: i[2]=(TUint8)(aOffset >> 8); williamr@2: i[3]=(TUint8)((i[3] & 0x7) | (aOffset & ~0x7)); williamr@2: } williamr@2: williamr@2: inline void SetMFlag(TInt aFlag) williamr@2: { williamr@2: i[3]= (TUint8)((i[3] & ~0x1) | (aFlag & 0x1)); williamr@2: } williamr@2: williamr@2: inline void SetId(TInt32 aId) williamr@2: { williamr@2: *((TInt32 *)&i[4]) = aId; // *ASSUMES* proper aligment!!! williamr@2: } williamr@2: private: williamr@2: union williamr@2: { williamr@2: TUint8 i[8]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: class TInet6HeaderAH williamr@2: /** williamr@2: * IPsec Authentication Header. williamr@2: * williamr@2: * The function parameters and return values are in host order, williamr@2: * except SPI, which is always in network byte order. williamr@2: @verbatim williamr@2: Extract from RFC-2402 williamr@2: williamr@2: 0 1 2 3 williamr@2: 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 williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Next Header | Payload Len | RESERVED | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Security Parameters Index (SPI) | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Sequence Number Field | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | | williamr@2: + Authentication Data (variable) | williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: @endverbatim williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: // williamr@2: // Basic williamr@2: // williamr@2: inline static TInt MinHeaderLength() {return 3*4; } williamr@2: inline static TInt MaxHeaderLength() {return 3*4; } williamr@2: inline TUint8 *EndPtr() {return i + HeaderLength();} williamr@2: // williamr@2: // Access, get values williamr@2: // williamr@2: inline TInt NextHeader() const williamr@2: { williamr@2: return i[0]; williamr@2: } williamr@2: // williamr@2: // PayloadLength returns the raw value williamr@2: // williamr@2: inline TInt PayloadLength() const williamr@2: { williamr@2: return i[1]; williamr@2: } williamr@2: // williamr@2: // *NOTE* AH is called IPv6 extension header, but its williamr@2: // length field semantics does not follow the normal williamr@2: // IPv6 extension header logic (it follows the IPv4) williamr@2: // williamr@2: inline TInt HeaderLength() const williamr@2: { williamr@2: return (i[1]+2) << 2; // IPv4 and IPv6 williamr@2: } williamr@2: // williamr@2: // SPI is returned in network byte order williamr@2: // williamr@2: inline TUint32 SPI() const williamr@2: { williamr@2: return *((TUint32 *)(i + 4)); williamr@2: } williamr@2: inline TUint32 Sequence() const williamr@2: { williamr@2: return (i[8] << 24) | (i[9] << 16) | (i[10] << 8) | i[11]; williamr@2: } williamr@2: williamr@2: // The length of the Authentication Data (in octets). williamr@2: // *NOTE* This will include the potential padding! -- msa williamr@2: inline TInt DataLength() const { williamr@2: return HeaderLength() - 12; williamr@2: } williamr@2: inline TPtr8 ICV() williamr@2: { williamr@2: return TPtr8((TUint8 *)&i[12], DataLength(), DataLength()); williamr@2: } williamr@2: // williamr@2: // Build williamr@2: // williamr@2: inline void SetNextHeader(TInt aNext) williamr@2: { williamr@2: i[0] = (TUint8)aNext; williamr@2: } williamr@2: inline void SetPayloadLength(TInt aByte) williamr@2: { williamr@2: i[1] = (TUint8)aByte; williamr@2: } williamr@2: // williamr@2: // *NOTE* AH is called IPv6 extension header, but its williamr@2: // length field semantics does not follow the normal williamr@2: // IPv6 extension header logic (it follows the IPv4) williamr@2: // As this is bit tricky, a "cooked version" of PayloadLength williamr@2: // setting is also provided (e.g. take in bytes, and compute williamr@2: // the real payload length value) -- msa williamr@2: inline void SetHeaderLength(TInt aLength) williamr@2: { williamr@2: i[1] = (TUint8)((aLength >> 2) - 2); williamr@2: } williamr@2: inline void SetSPI(TUint32 aSPI) williamr@2: { williamr@2: *((TUint32 *)(i + 4)) = aSPI; williamr@2: } williamr@2: inline void SetReserved(TInt aValue) williamr@2: { williamr@2: i[3] = (TUint8)aValue; williamr@2: i[2] = (TUint8)(aValue >> 8); williamr@2: } williamr@2: inline void SetSequence(TUint32 aSeq) williamr@2: { williamr@2: i[11] = (TUint8)aSeq; williamr@2: i[10] = (TUint8)(aSeq >> 8); williamr@2: i[9] = (TUint8)(aSeq >> 16); williamr@2: i[8] = (TUint8)(aSeq >> 24); williamr@2: } williamr@2: protected: williamr@2: union williamr@2: { williamr@2: TUint8 i[3*4]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: williamr@2: williamr@2: class TInet6HeaderESP williamr@2: /** williamr@2: * IPsec Encapsulating Security Payload Packet Format. williamr@2: * williamr@2: * The function parameters and return values are in host williamr@2: * order (except SPI, which is always in network byte order) williamr@2: * williamr@2: @verbatim williamr@2: RFC-2406 williamr@2: 0 1 2 3 williamr@2: 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 williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---- williamr@2: | Security Parameters Index (SPI) | ^Auth. williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov- williamr@2: | Sequence Number | |erage williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ---- williamr@2: | Payload Data* (variable) | | ^ williamr@2: ~ ~ | | williamr@2: | | |Conf. williamr@2: + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov- williamr@2: | | Padding (0-255 bytes) | |erage* williamr@2: +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | williamr@2: | | Pad Length | Next Header | v v williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ------ williamr@2: | Authentication Data (variable) | williamr@2: ~ ~ williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: @endverbatim williamr@2: * This only defines the fixed portion of the ESP, 8 bytes). williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: // williamr@2: // Basic williamr@2: // williamr@2: inline static TInt MinHeaderLength() {return 2*4; } williamr@2: inline static TInt MaxHeaderLength() {return 2*4; } williamr@2: inline TInt HeaderLength() const {return 2*4; } williamr@2: inline TUint8 *EndPtr() {return i + HeaderLength();} williamr@2: williamr@2: // williamr@2: // Access, get values williamr@2: // williamr@2: // williamr@2: // SPI is returned in network byte order williamr@2: // williamr@2: inline TUint32 SPI() const williamr@2: { williamr@2: return *((TUint32 *)(i + 0)); williamr@2: } williamr@2: inline TUint32 Sequence() const williamr@2: { williamr@2: return (i[4] << 24) | (i[5] << 16) | (i[6] << 8) | i[7]; williamr@2: } williamr@2: // williamr@2: // IV is not exactly part of the header, but provide williamr@2: // a method that returns a Ptr to it (assuming the williamr@2: // IV is accessible directly after the fixed part). williamr@2: // williamr@2: inline TPtr8 IV(TInt aLen) williamr@2: { williamr@2: return TPtr8((TUint8 *)&i[sizeof(i)], aLen, aLen); williamr@2: } williamr@2: williamr@2: // williamr@2: // Build williamr@2: // williamr@2: inline void SetSPI(TUint32 aSPI) williamr@2: { williamr@2: *((TUint32 *)(i + 0)) = aSPI; williamr@2: } williamr@2: inline void SetSequence(TUint32 aSeq) williamr@2: { williamr@2: i[7] = (TUint8)aSeq; williamr@2: i[6] = (TUint8)(aSeq >> 8); williamr@2: i[5] = (TUint8)(aSeq >> 16); williamr@2: i[4] = (TUint8)(aSeq >> 24); williamr@2: } williamr@2: protected: williamr@2: union williamr@2: { williamr@2: TUint8 i[2*4]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: /** @} */ williamr@2: #endif