epoc32/include/ip6_hdr.h
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
parent 2 2fe1408b6811
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     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 "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // ip6_hdr.h - IPv6 header structure
    15 // This module defines the basic classes for accessing the header
    16 // structures within IPv6 packets.
    17 // Defines the IPv6 header structure.
    18 //
    19 
    20 
    21 
    22 /**
    23  @file ip6_hdr.h
    24  @ingroup ip_packet_formats
    25  @publishedAll
    26  @released
    27 */
    28 
    29 #ifndef __IP6_HDR_H__
    30 #define __IP6_HDR_H__
    31 
    32 #include "in_hdr.h"
    33 #include <in_sock.h> // Only for TIp6Addr !
    34 
    35 /**
    36 * @defgroup  ip_packet_formats	IPv4 and IPv6 packet formats and constants
    37 *
    38 * These headers define various constants and special <em>mapping or overlay
    39 * classes</em> to be used in accessing and building the IP packets. The
    40 * mapping classes are not intended to be used in declaring
    41 * variables (although some of them do support that use also).
    42 *
    43 * The normal usage is to typecast a binary buffer
    44 * to a mapping class. For example
    45 * assuming a buf contains a raw IPv6 packet:
    46 *
    47 @code
    48 	TBuf8<2000> buf;
    49 
    50 	TInet6HeaderIP &ip = *(TInet6HeaderIP *)buf.Ptr();
    51 	if (ip.MinHeaderLength() > buf.Length() ||
    52 		ip.HeaderLength() + ip.PayloadLength() > buf.Length())
    53 		{
    54 		// Oops. packet too short!
    55 		}
    56 	else if (ip.Version() == 6)
    57 		{
    58 		// Packet seems to be IPv6 packet.
    59 		}
    60 @endcode
    61 *
    62 * Within the TCP/IP stack, the packets are stored in RMBufChain objects.
    63 * The data is not in a contiguous memory area and accessing the headers is
    64 * more complicated. For that purpose there is a template class TInet6Packet,
    65 * which can use any <em>mapping class</em> as a template parameter and
    66 * provides functions to access the header within the chain. Assuming the
    67 * a RMBufChain object buf contains the packet, equivalent code would be:
    68 *
    69 @code
    70 	RMBufChain buf;
    71 
    72 	TInet6Packet<TInet6HeaderIP> ip(buf);
    73 	if (ip.iHdr == NULL ||
    74 		ip.iHdr->HeaderLength() + ip.iHdr->PayloadLength() > buf.Length())
    75 		{
    76 		// Opps. packet too short!
    77 		}
    78 	else if (ip.iHdr->Version() == 6)
    79 		{
    80 		// Packet seems to be IPv6 packet.
    81 		}
    82 @endcode
    83 * The TInet6Packet template does automatic MinHeaderLength check. The iHdr
    84 * member variable is set only if the mapping succeeds at least for MinHeaderLength
    85 * octets.
    86 *
    87 * All mapping headers must have the following functions defined:
    88 *
    89 * - static function MinHeaderLength returns the minimum header length in octets.
    90 *
    91 * - static function MaxHeaderLength returns the maximum header length in octets (not used much).
    92 *
    93 * - HeaderLength returns the actual length of a header instance in octets.
    94 *	Note that this may return garbage value, if the mapped header is invalid.
    95 *	The return value can be larger than indicated by MinHeaderLength, and
    96 *	as the mapping is only guaranteed up to that size, user must separately
    97 *	verify the accessibility of a full header in such case. 
    98 * @{
    99 * @}
   100 */
   101 
   102 /**
   103 * @addtogroup  ip_packet_formats
   104 * @{
   105 */
   106 
   107 /**
   108 * The IPv6 minimum value for Maximum Transmission Unit (MTU) as defined in RFC 2460. 
   109 * 
   110 * @since v7.0
   111 */
   112 const TInt KInet6MinMtu = 1280;
   113 
   114 //
   115 // TInet6HeaderIP
   116 // **************
   117 //	Methods of manipulating IPv6 IP header.
   118 //
   119 //	This implementation assumes TUint8 is exactly 8 bits (and not
   120 //	9 or more)
   121 class TInet6HeaderIP
   122 /**
   123 * Encapsulates an IPv6 IP header. 
   124 * @verbatim
   125  *************************
   126  Extract from the RFC-2460
   127  *************************
   128 
   129    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   130    |Version| Traffic Class |           Flow Label                  |
   131    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   132    |         Payload Length        |  Next Header  |   Hop Limit   |
   133    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   134    |                                                               |
   135    +                                                               +
   136    |                                                               |
   137    +                         Source Address                        +
   138    |                                                               |
   139    +                                                               +
   140    |                                                               |
   141    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   142    |                                                               |
   143    +                                                               +
   144    |                                                               |
   145    +                      Destination Address                      +
   146    |                                                               |
   147    +                                                               +
   148    |                                                               |
   149    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   150 
   151    Version              4-bit Internet Protocol version number = 6.
   152 
   153    Traffic Class        8-bit traffic class field.  See section 7.
   154 
   155    Flow Label           20-bit flow label.  See section 6.
   156 
   157    Payload Length       16-bit unsigned integer.  Length of the IPv6
   158                         payload, i.e., the rest of the packet following
   159                         this IPv6 header, in octets.  (Note that any
   160                         extension headers [section 4] present are
   161                         considered part of the payload, i.e., included
   162                         in the length count.)
   163 
   164    Next Header          8-bit selector.  Identifies the type of header
   165                         immediately following the IPv6 header.  Uses the
   166                         same values as the IPv4 Protocol field [RFC-1700
   167                         et seq.].
   168 
   169    Hop Limit            8-bit unsigned integer.  Decremented by 1 by
   170                         each node that forwards the packet. The packet
   171                         is discarded if Hop Limit is decremented to
   172                         zero.
   173 
   174    Source Address       128-bit address of the originator of the packet.
   175 
   176    Destination Address  128-bit address of the intended recipient of the
   177                         packet (possibly not the ultimate recipient, if
   178                         a Routing header is present)
   179 @endverbatim
   180 * @publishedAll
   181 * @released
   182 * @since v7.0
   183 */
   184 	{
   185 public:
   186 	enum TOffsets
   187 		{
   188 		O_PayloadLength = 4,
   189 		O_NextHeader = 6,
   190 		O_HopLimit = 7,
   191 		O_SrcAddr = 8,
   192 		O_DstAddr = 24
   193 		};
   194 
   195 	// Basic functions, common to all header classes
   196 	// *********************************************
   197 
   198 	/**
   199 	* Gets the header length.	
   200 	* 
   201 	* Note that the header length is fixed.
   202 	* 
   203 	* @return	Header length.
   204 	*/
   205 	inline TInt HeaderLength() const {return 40;}
   206 	/**
   207 	* Gets the minimum header length.
   208 	* 
   209 	* Note that the header length is fixed.
   210 	* 
   211 	* @return	Minimum header length
   212 	*/
   213 	inline static TInt MinHeaderLength() {return 40; }
   214 	/**
   215 	* Gets the maximum header length.
   216 	* 
   217 	* Note that the header length is fixed.
   218 	* 
   219 	* @return	Maximum header length
   220 	*/
   221 	inline static TInt MaxHeaderLength() {return 40; }
   222 	/**
   223 	* Gets a pointer to the byte following the header.
   224 	* 
   225 	* @return	Pointer to the byte following the header
   226 	*/
   227 	inline TUint8 *EndPtr() {return i + HeaderLength();}
   228 
   229 	// IPv6 specific methods, get IP header field values from the packet
   230 	// *****************************************************************
   231 
   232 	inline TInt Version() const
   233 		/**
   234 		* Gets the IP version from the header.
   235 		*
   236 		* @return	IP version
   237 		*/
   238 		{
   239 		return (i[0] >> 4) & 0xf;
   240 		}
   241 	inline TInt TrafficClass() const
   242 		/**
   243 		* Gets the traffic class from the header.
   244 		*
   245 		* @return	Traffic class
   246 		*/
   247 		{
   248 		return ((i[0] << 4) & 0xf0) | ((i[1] >> 4) & 0x0f);
   249 		}
   250 	inline TInt FlowLabel() const
   251 		/**
   252 		* Gets the flow label from the header.
   253 		* 
   254 		* @return	Flow label (host byte order)
   255 		*/
   256 		{
   257 		return ((i[1] << 16) | (i[2] << 8) | i[3]) & 0xfffff;
   258 		// Could also use any deterministic permutation of the 20 bits,
   259 		// if Flow label can be treated as opaque 20 bits, and not as
   260 		// integer where host/net byte order comes into play --msa
   261 		}
   262 	inline TInt PayloadLength() const
   263 		/**
   264 		* Gets the payload length from the header.
   265 		*
   266 		* @return	Payload length
   267 		*/
   268 		{
   269 		return (i[4] << 8) | i[5];
   270 		}
   271 	inline TInt NextHeader() const
   272 		/**
   273 		* Gets the next header selector from the header.
   274 		*
   275 		* @return	Next header selector (0..255)
   276 		*/
   277 		{
   278 		return i[6];
   279 		}
   280 	inline TInt HopLimit() const
   281 		{
   282 		/**
   283 		* Gets the hop limit from the header.
   284 		*
   285 		* @return	Hop limit (0..255)
   286 		*/
   287 		return i[7];
   288 		}
   289 	//
   290 	// The following return a modifiable reference, so
   291 	// they can be used both for access and build.
   292 	//
   293 	inline TIp6Addr &SrcAddr() const
   294 		/**
   295 		* Gets the source address from the header.
   296 		*
   297 		* @return	Source address
   298 		*/
   299 		{
   300 		return (TIp6Addr &)i[8];
   301 		}
   302 	inline TIp6Addr &DstAddr() const
   303 		/**
   304 		* Gets the destination address from the header.
   305 		*
   306 		* @return	Destination address
   307 		*/
   308 		{
   309 		return (TIp6Addr &)i[24];
   310 		}
   311 
   312 	inline TBool EcnIsCongestion()
   313 		/**
   314 		* Gets ECN congestion status.
   315 		*
   316 		* see RFC-3168 for details.
   317 		*
   318 		* @return	True, if CE bit is set on an ECN capable packet.
   319 		*/
   320 		{
   321 		return ((TrafficClass() & 3) == 3);
   322 		}
   323 
   324 
   325 	// IPv6 specific methods, set IP header field values into the packet
   326 	// *****************************************************************
   327 
   328 	inline void Init()
   329 		/**
   330 		* Initialises the header to basic initial values.
   331 		*
   332 		* @li Version = 6
   333 		* @li Traffic Class = 0
   334 		* @li Flow Label = 0
   335 		* @li Payload Length = 0
   336 		* @li Next Header = 0
   337 		* @li Hop Limit = 0
   338 		*
   339 		* The Source and Destination address fields are not touched.
   340 		*/
   341 		{
   342 		static const union { TUint8 a[4]; TUint32 b;} x = { {6 << 4, 0, 0, 0} };
   343 		(TUint32 &)i[0] = x.b;
   344 		(TUint32 &)i[4] = 0;
   345 		}
   346 
   347 
   348 	inline void SetVersion(TInt aVersion)
   349 		/**
   350 		* Sets the IP version in the header.
   351 		*
   352 		* @param aVersion	IP version (0..15, = 6 for IPv6)
   353 		*/
   354 		{
   355 		i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0));
   356 		}
   357 	inline void SetTrafficClass(TInt aClass)
   358 		/**
   359 		* Sets the traffic class in the header.
   360 		* 
   361 		* @param aClass	Traffic class (0..255)
   362 		*/
   363 		{
   364 		i[0] = (TUint8)((i[0] & 0xf0) | (aClass >> 4) & 0x0f);
   365 		i[1] = (TUint8)((i[1] & 0x0f) | (aClass << 4) & 0xf0);
   366 		}
   367 	inline void SetFlowLabel(TInt aFlow)
   368 		/**
   369 		* Sets the flow label in the header.
   370 		* 
   371 		* @param aFlow	Flow label (20 bit integer in host order)
   372 		*/
   373 		{
   374 		i[1] = (TUint8)((i[1] & 0xf0) | ((aFlow >> 16) & 0x0f));
   375 		i[2] = (TUint8)(aFlow >> 8);
   376 		i[3] = (TUint8)aFlow;
   377 		}
   378 
   379 	inline void SetPayloadLength(TInt aLength)
   380 		/**
   381 		* Sets the payload length in the header.
   382 		* 
   383 		* @param aLength	Payload length
   384 		*/
   385 		{
   386 		i[4] = (TUint8)(aLength >> 8);
   387 		i[5] = (TUint8)aLength;
   388 		}
   389 
   390 	inline void SetNextHeader(TInt aNextHeader)
   391 		/**
   392 		* Sets the next header selector from the header.
   393 		*
   394 		* @param aNextHeader	Next header selector (0..255)
   395 		*/
   396 		{
   397 		i[6] = (TUint8)aNextHeader;
   398 		}
   399 	inline void SetHopLimit(TInt aLimit)
   400 		/**
   401 		* Sets the hop limit in the header.
   402 		*
   403 		* @param aLimit	Hop limit (0..255)
   404 		*/
   405 		{
   406 		i[7] = (TUint8)aLimit;
   407 		}
   408 	inline void SetSrcAddr(const TIp6Addr &anAddr)
   409 		/**
   410 		* Sets the source address in the header.
   411 		* 
   412 		* @param anAddr	Source address
   413 		*/
   414 		{
   415 		(TIp6Addr &)i[8] = anAddr;
   416 		}
   417 	inline void SetDstAddr(const TIp6Addr &anAddr)
   418 		/**
   419 		* Sets the destination address in the header.
   420 		* 
   421 		* @param anAddr	Destination address
   422 		*/
   423 		{
   424 		(TIp6Addr &)i[24] = anAddr;
   425 		}
   426 							
   427 private:
   428 	union
   429 		{
   430 		TUint8 i[40];
   431 		TUint32 iAlign;	// A dummy member to force the 4 byte alignment
   432 		};
   433 	};
   434 
   435 /** @} */
   436 #endif