epoc32/include/ip6_hdr.h
branchSymbian2
changeset 2 2fe1408b6811
child 4 837f303aceeb
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     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".
       
     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