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