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: // ip6_hdr.h - IPv6 header structure williamr@2: // This module defines the basic classes for accessing the header williamr@2: // structures within IPv6 packets. williamr@2: // Defines the IPv6 header structure. williamr@2: // williamr@2: williamr@2: williamr@2: williamr@2: /** williamr@2: @file ip6_hdr.h williamr@2: @ingroup ip_packet_formats williamr@2: @publishedAll williamr@2: @released williamr@2: */ williamr@2: williamr@2: #ifndef __IP6_HDR_H__ williamr@2: #define __IP6_HDR_H__ williamr@2: williamr@2: #include "in_hdr.h" williamr@2: #include // Only for TIp6Addr ! williamr@2: williamr@2: /** williamr@2: * @defgroup ip_packet_formats IPv4 and IPv6 packet formats and constants williamr@2: * williamr@2: * These headers define various constants and special mapping or overlay williamr@2: * classes to be used in accessing and building the IP packets. The williamr@2: * mapping classes are not intended to be used in declaring williamr@2: * variables (although some of them do support that use also). williamr@2: * williamr@2: * The normal usage is to typecast a binary buffer williamr@2: * to a mapping class. For example williamr@2: * assuming a buf contains a raw IPv6 packet: williamr@2: * williamr@2: @code williamr@2: TBuf8<2000> buf; williamr@2: williamr@2: TInet6HeaderIP &ip = *(TInet6HeaderIP *)buf.Ptr(); williamr@2: if (ip.MinHeaderLength() > buf.Length() || williamr@2: ip.HeaderLength() + ip.PayloadLength() > buf.Length()) williamr@2: { williamr@2: // Oops. packet too short! williamr@2: } williamr@2: else if (ip.Version() == 6) williamr@2: { williamr@2: // Packet seems to be IPv6 packet. williamr@2: } williamr@2: @endcode williamr@2: * williamr@2: * Within the TCP/IP stack, the packets are stored in RMBufChain objects. williamr@2: * The data is not in a contiguous memory area and accessing the headers is williamr@2: * more complicated. For that purpose there is a template class TInet6Packet, williamr@2: * which can use any mapping class as a template parameter and williamr@2: * provides functions to access the header within the chain. Assuming the williamr@2: * a RMBufChain object buf contains the packet, equivalent code would be: williamr@2: * williamr@2: @code williamr@2: RMBufChain buf; williamr@2: williamr@2: TInet6Packet ip(buf); williamr@2: if (ip.iHdr == NULL || williamr@2: ip.iHdr->HeaderLength() + ip.iHdr->PayloadLength() > buf.Length()) williamr@2: { williamr@2: // Opps. packet too short! williamr@2: } williamr@2: else if (ip.iHdr->Version() == 6) williamr@2: { williamr@2: // Packet seems to be IPv6 packet. williamr@2: } williamr@2: @endcode williamr@2: * The TInet6Packet template does automatic MinHeaderLength check. The iHdr williamr@2: * member variable is set only if the mapping succeeds at least for MinHeaderLength williamr@2: * octets. williamr@2: * williamr@2: * All mapping headers must have the following functions defined: williamr@2: * williamr@2: * - static function MinHeaderLength returns the minimum header length in octets. williamr@2: * williamr@2: * - static function MaxHeaderLength returns the maximum header length in octets (not used much). williamr@2: * williamr@2: * - HeaderLength returns the actual length of a header instance in octets. williamr@2: * Note that this may return garbage value, if the mapped header is invalid. williamr@2: * The return value can be larger than indicated by MinHeaderLength, and williamr@2: * as the mapping is only guaranteed up to that size, user must separately williamr@2: * verify the accessibility of a full header in such case. williamr@2: * @{ williamr@2: * @} williamr@2: */ williamr@2: williamr@2: /** williamr@2: * @addtogroup ip_packet_formats williamr@2: * @{ williamr@2: */ williamr@2: williamr@2: /** williamr@2: * The IPv6 minimum value for Maximum Transmission Unit (MTU) as defined in RFC 2460. williamr@2: * williamr@2: * @since v7.0 williamr@2: */ williamr@2: const TInt KInet6MinMtu = 1280; williamr@2: williamr@2: // williamr@2: // TInet6HeaderIP williamr@2: // ************** williamr@2: // Methods of manipulating IPv6 IP header. williamr@2: // williamr@2: // This implementation assumes TUint8 is exactly 8 bits (and not williamr@2: // 9 or more) williamr@2: class TInet6HeaderIP williamr@2: /** williamr@2: * Encapsulates an IPv6 IP header. williamr@2: * @verbatim williamr@2: ************************* williamr@2: Extract from the RFC-2460 williamr@2: ************************* williamr@2: williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: |Version| Traffic Class | Flow Label | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | Payload Length | Next Header | Hop Limit | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: + Source Address + williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: + Destination Address + williamr@2: | | williamr@2: + + williamr@2: | | williamr@2: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ williamr@2: williamr@2: Version 4-bit Internet Protocol version number = 6. williamr@2: williamr@2: Traffic Class 8-bit traffic class field. See section 7. williamr@2: williamr@2: Flow Label 20-bit flow label. See section 6. williamr@2: williamr@2: Payload Length 16-bit unsigned integer. Length of the IPv6 williamr@2: payload, i.e., the rest of the packet following williamr@2: this IPv6 header, in octets. (Note that any williamr@2: extension headers [section 4] present are williamr@2: considered part of the payload, i.e., included williamr@2: in the length count.) williamr@2: williamr@2: Next Header 8-bit selector. Identifies the type of header williamr@2: immediately following the IPv6 header. Uses the williamr@2: same values as the IPv4 Protocol field [RFC-1700 williamr@2: et seq.]. williamr@2: williamr@2: Hop Limit 8-bit unsigned integer. Decremented by 1 by williamr@2: each node that forwards the packet. The packet williamr@2: is discarded if Hop Limit is decremented to williamr@2: zero. williamr@2: williamr@2: Source Address 128-bit address of the originator of the packet. williamr@2: williamr@2: Destination Address 128-bit address of the intended recipient of the williamr@2: packet (possibly not the ultimate recipient, if williamr@2: a Routing header is present) williamr@2: @endverbatim williamr@2: * @publishedAll williamr@2: * @released williamr@2: * @since v7.0 williamr@2: */ williamr@2: { williamr@2: public: williamr@2: enum TOffsets williamr@2: { williamr@2: O_PayloadLength = 4, williamr@2: O_NextHeader = 6, williamr@2: O_HopLimit = 7, williamr@2: O_SrcAddr = 8, williamr@2: O_DstAddr = 24 williamr@2: }; williamr@2: williamr@2: // Basic functions, common to all header classes williamr@2: // ********************************************* williamr@2: williamr@2: /** williamr@2: * Gets the header length. williamr@2: * williamr@2: * Note that the header length is fixed. williamr@2: * williamr@2: * @return Header length. williamr@2: */ williamr@2: inline TInt HeaderLength() const {return 40;} williamr@2: /** williamr@2: * Gets the minimum header length. williamr@2: * williamr@2: * Note that the header length is fixed. williamr@2: * williamr@2: * @return Minimum header length williamr@2: */ williamr@2: inline static TInt MinHeaderLength() {return 40; } williamr@2: /** williamr@2: * Gets the maximum header length. williamr@2: * williamr@2: * Note that the header length is fixed. williamr@2: * williamr@2: * @return Maximum header length williamr@2: */ williamr@2: inline static TInt MaxHeaderLength() {return 40; } williamr@2: /** williamr@2: * Gets a pointer to the byte following the header. williamr@2: * williamr@2: * @return Pointer to the byte following the header williamr@2: */ williamr@2: inline TUint8 *EndPtr() {return i + HeaderLength();} williamr@2: williamr@2: // IPv6 specific methods, get IP header field values from the packet williamr@2: // ***************************************************************** williamr@2: williamr@2: inline TInt Version() const williamr@2: /** williamr@2: * Gets the IP version from the header. williamr@2: * williamr@2: * @return IP version williamr@2: */ williamr@2: { williamr@2: return (i[0] >> 4) & 0xf; williamr@2: } williamr@2: inline TInt TrafficClass() const williamr@2: /** williamr@2: * Gets the traffic class from the header. williamr@2: * williamr@2: * @return Traffic class williamr@2: */ williamr@2: { williamr@2: return ((i[0] << 4) & 0xf0) | ((i[1] >> 4) & 0x0f); williamr@2: } williamr@2: inline TInt FlowLabel() const williamr@2: /** williamr@2: * Gets the flow label from the header. williamr@2: * williamr@2: * @return Flow label (host byte order) williamr@2: */ williamr@2: { williamr@2: return ((i[1] << 16) | (i[2] << 8) | i[3]) & 0xfffff; williamr@2: // Could also use any deterministic permutation of the 20 bits, williamr@2: // if Flow label can be treated as opaque 20 bits, and not as williamr@2: // integer where host/net byte order comes into play --msa williamr@2: } williamr@2: inline TInt PayloadLength() const williamr@2: /** williamr@2: * Gets the payload length from the header. williamr@2: * williamr@2: * @return Payload length williamr@2: */ williamr@2: { williamr@2: return (i[4] << 8) | i[5]; williamr@2: } williamr@2: inline TInt NextHeader() const williamr@2: /** williamr@2: * Gets the next header selector from the header. williamr@2: * williamr@2: * @return Next header selector (0..255) williamr@2: */ williamr@2: { williamr@2: return i[6]; williamr@2: } williamr@2: inline TInt HopLimit() const williamr@2: { williamr@2: /** williamr@2: * Gets the hop limit from the header. williamr@2: * williamr@2: * @return Hop limit (0..255) williamr@2: */ williamr@2: return i[7]; williamr@2: } williamr@2: // williamr@2: // The following return a modifiable reference, so williamr@2: // they can be used both for access and build. williamr@2: // williamr@2: inline TIp6Addr &SrcAddr() const williamr@2: /** williamr@2: * Gets the source address from the header. williamr@2: * williamr@2: * @return Source address williamr@2: */ williamr@2: { williamr@2: return (TIp6Addr &)i[8]; williamr@2: } williamr@2: inline TIp6Addr &DstAddr() const williamr@2: /** williamr@2: * Gets the destination address from the header. williamr@2: * williamr@2: * @return Destination address williamr@2: */ williamr@2: { williamr@2: return (TIp6Addr &)i[24]; williamr@2: } williamr@2: williamr@2: inline TBool EcnIsCongestion() williamr@2: /** williamr@2: * Gets ECN congestion status. williamr@2: * williamr@2: * see RFC-3168 for details. williamr@2: * williamr@2: * @return True, if CE bit is set on an ECN capable packet. williamr@2: */ williamr@2: { williamr@2: return ((TrafficClass() & 3) == 3); williamr@2: } williamr@2: williamr@2: williamr@2: // IPv6 specific methods, set IP header field values into the packet williamr@2: // ***************************************************************** williamr@2: williamr@2: inline void Init() williamr@2: /** williamr@2: * Initialises the header to basic initial values. williamr@2: * williamr@2: * @li Version = 6 williamr@2: * @li Traffic Class = 0 williamr@2: * @li Flow Label = 0 williamr@2: * @li Payload Length = 0 williamr@2: * @li Next Header = 0 williamr@2: * @li Hop Limit = 0 williamr@2: * williamr@2: * The Source and Destination address fields are not touched. williamr@2: */ williamr@2: { williamr@2: static const union { TUint8 a[4]; TUint32 b;} x = { {6 << 4, 0, 0, 0} }; williamr@2: (TUint32 &)i[0] = x.b; williamr@2: (TUint32 &)i[4] = 0; williamr@2: } williamr@2: williamr@2: williamr@2: inline void SetVersion(TInt aVersion) williamr@2: /** williamr@2: * Sets the IP version in the header. williamr@2: * williamr@2: * @param aVersion IP version (0..15, = 6 for IPv6) williamr@2: */ williamr@2: { williamr@2: i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0)); williamr@2: } williamr@2: inline void SetTrafficClass(TInt aClass) williamr@2: /** williamr@2: * Sets the traffic class in the header. williamr@2: * williamr@2: * @param aClass Traffic class (0..255) williamr@2: */ williamr@2: { williamr@2: i[0] = (TUint8)((i[0] & 0xf0) | (aClass >> 4) & 0x0f); williamr@2: i[1] = (TUint8)((i[1] & 0x0f) | (aClass << 4) & 0xf0); williamr@2: } williamr@2: inline void SetFlowLabel(TInt aFlow) williamr@2: /** williamr@2: * Sets the flow label in the header. williamr@2: * williamr@2: * @param aFlow Flow label (20 bit integer in host order) williamr@2: */ williamr@2: { williamr@2: i[1] = (TUint8)((i[1] & 0xf0) | ((aFlow >> 16) & 0x0f)); williamr@2: i[2] = (TUint8)(aFlow >> 8); williamr@2: i[3] = (TUint8)aFlow; williamr@2: } williamr@2: williamr@2: inline void SetPayloadLength(TInt aLength) williamr@2: /** williamr@2: * Sets the payload length in the header. williamr@2: * williamr@2: * @param aLength Payload length williamr@2: */ williamr@2: { williamr@2: i[4] = (TUint8)(aLength >> 8); williamr@2: i[5] = (TUint8)aLength; williamr@2: } williamr@2: williamr@2: inline void SetNextHeader(TInt aNextHeader) williamr@2: /** williamr@2: * Sets the next header selector from the header. williamr@2: * williamr@2: * @param aNextHeader Next header selector (0..255) williamr@2: */ williamr@2: { williamr@2: i[6] = (TUint8)aNextHeader; williamr@2: } williamr@2: inline void SetHopLimit(TInt aLimit) williamr@2: /** williamr@2: * Sets the hop limit in the header. williamr@2: * williamr@2: * @param aLimit Hop limit (0..255) williamr@2: */ williamr@2: { williamr@2: i[7] = (TUint8)aLimit; williamr@2: } williamr@2: inline void SetSrcAddr(const TIp6Addr &anAddr) williamr@2: /** williamr@2: * Sets the source address in the header. williamr@2: * williamr@2: * @param anAddr Source address williamr@2: */ williamr@2: { williamr@2: (TIp6Addr &)i[8] = anAddr; williamr@2: } williamr@2: inline void SetDstAddr(const TIp6Addr &anAddr) williamr@2: /** williamr@2: * Sets the destination address in the header. williamr@2: * williamr@2: * @param anAddr Destination address williamr@2: */ williamr@2: { williamr@2: (TIp6Addr &)i[24] = anAddr; williamr@2: } williamr@2: williamr@2: private: williamr@2: union williamr@2: { williamr@2: TUint8 i[40]; williamr@2: TUint32 iAlign; // A dummy member to force the 4 byte alignment williamr@2: }; williamr@2: }; williamr@2: williamr@2: /** @} */ williamr@2: #endif