1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/ip6_hdr.h Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,436 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// 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
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// ip6_hdr.h - IPv6 header structure
1.18 +// This module defines the basic classes for accessing the header
1.19 +// structures within IPv6 packets.
1.20 +// Defines the IPv6 header structure.
1.21 +//
1.22 +
1.23 +
1.24 +
1.25 +/**
1.26 + @file ip6_hdr.h
1.27 + @ingroup ip_packet_formats
1.28 + @publishedAll
1.29 + @released
1.30 +*/
1.31 +
1.32 +#ifndef __IP6_HDR_H__
1.33 +#define __IP6_HDR_H__
1.34 +
1.35 +#include "in_hdr.h"
1.36 +#include <in_sock.h> // Only for TIp6Addr !
1.37 +
1.38 +/**
1.39 +* @defgroup ip_packet_formats IPv4 and IPv6 packet formats and constants
1.40 +*
1.41 +* These headers define various constants and special <em>mapping or overlay
1.42 +* classes</em> to be used in accessing and building the IP packets. The
1.43 +* mapping classes are not intended to be used in declaring
1.44 +* variables (although some of them do support that use also).
1.45 +*
1.46 +* The normal usage is to typecast a binary buffer
1.47 +* to a mapping class. For example
1.48 +* assuming a buf contains a raw IPv6 packet:
1.49 +*
1.50 +@code
1.51 + TBuf8<2000> buf;
1.52 +
1.53 + TInet6HeaderIP &ip = *(TInet6HeaderIP *)buf.Ptr();
1.54 + if (ip.MinHeaderLength() > buf.Length() ||
1.55 + ip.HeaderLength() + ip.PayloadLength() > buf.Length())
1.56 + {
1.57 + // Oops. packet too short!
1.58 + }
1.59 + else if (ip.Version() == 6)
1.60 + {
1.61 + // Packet seems to be IPv6 packet.
1.62 + }
1.63 +@endcode
1.64 +*
1.65 +* Within the TCP/IP stack, the packets are stored in RMBufChain objects.
1.66 +* The data is not in a contiguous memory area and accessing the headers is
1.67 +* more complicated. For that purpose there is a template class TInet6Packet,
1.68 +* which can use any <em>mapping class</em> as a template parameter and
1.69 +* provides functions to access the header within the chain. Assuming the
1.70 +* a RMBufChain object buf contains the packet, equivalent code would be:
1.71 +*
1.72 +@code
1.73 + RMBufChain buf;
1.74 +
1.75 + TInet6Packet<TInet6HeaderIP> ip(buf);
1.76 + if (ip.iHdr == NULL ||
1.77 + ip.iHdr->HeaderLength() + ip.iHdr->PayloadLength() > buf.Length())
1.78 + {
1.79 + // Opps. packet too short!
1.80 + }
1.81 + else if (ip.iHdr->Version() == 6)
1.82 + {
1.83 + // Packet seems to be IPv6 packet.
1.84 + }
1.85 +@endcode
1.86 +* The TInet6Packet template does automatic MinHeaderLength check. The iHdr
1.87 +* member variable is set only if the mapping succeeds at least for MinHeaderLength
1.88 +* octets.
1.89 +*
1.90 +* All mapping headers must have the following functions defined:
1.91 +*
1.92 +* - static function MinHeaderLength returns the minimum header length in octets.
1.93 +*
1.94 +* - static function MaxHeaderLength returns the maximum header length in octets (not used much).
1.95 +*
1.96 +* - HeaderLength returns the actual length of a header instance in octets.
1.97 +* Note that this may return garbage value, if the mapped header is invalid.
1.98 +* The return value can be larger than indicated by MinHeaderLength, and
1.99 +* as the mapping is only guaranteed up to that size, user must separately
1.100 +* verify the accessibility of a full header in such case.
1.101 +* @{
1.102 +* @}
1.103 +*/
1.104 +
1.105 +/**
1.106 +* @addtogroup ip_packet_formats
1.107 +* @{
1.108 +*/
1.109 +
1.110 +/**
1.111 +* The IPv6 minimum value for Maximum Transmission Unit (MTU) as defined in RFC 2460.
1.112 +*
1.113 +* @since v7.0
1.114 +*/
1.115 +const TInt KInet6MinMtu = 1280;
1.116 +
1.117 +//
1.118 +// TInet6HeaderIP
1.119 +// **************
1.120 +// Methods of manipulating IPv6 IP header.
1.121 +//
1.122 +// This implementation assumes TUint8 is exactly 8 bits (and not
1.123 +// 9 or more)
1.124 +class TInet6HeaderIP
1.125 +/**
1.126 +* Encapsulates an IPv6 IP header.
1.127 +* @verbatim
1.128 + *************************
1.129 + Extract from the RFC-2460
1.130 + *************************
1.131 +
1.132 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.133 + |Version| Traffic Class | Flow Label |
1.134 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.135 + | Payload Length | Next Header | Hop Limit |
1.136 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.137 + | |
1.138 + + +
1.139 + | |
1.140 + + Source Address +
1.141 + | |
1.142 + + +
1.143 + | |
1.144 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.145 + | |
1.146 + + +
1.147 + | |
1.148 + + Destination Address +
1.149 + | |
1.150 + + +
1.151 + | |
1.152 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.153 +
1.154 + Version 4-bit Internet Protocol version number = 6.
1.155 +
1.156 + Traffic Class 8-bit traffic class field. See section 7.
1.157 +
1.158 + Flow Label 20-bit flow label. See section 6.
1.159 +
1.160 + Payload Length 16-bit unsigned integer. Length of the IPv6
1.161 + payload, i.e., the rest of the packet following
1.162 + this IPv6 header, in octets. (Note that any
1.163 + extension headers [section 4] present are
1.164 + considered part of the payload, i.e., included
1.165 + in the length count.)
1.166 +
1.167 + Next Header 8-bit selector. Identifies the type of header
1.168 + immediately following the IPv6 header. Uses the
1.169 + same values as the IPv4 Protocol field [RFC-1700
1.170 + et seq.].
1.171 +
1.172 + Hop Limit 8-bit unsigned integer. Decremented by 1 by
1.173 + each node that forwards the packet. The packet
1.174 + is discarded if Hop Limit is decremented to
1.175 + zero.
1.176 +
1.177 + Source Address 128-bit address of the originator of the packet.
1.178 +
1.179 + Destination Address 128-bit address of the intended recipient of the
1.180 + packet (possibly not the ultimate recipient, if
1.181 + a Routing header is present)
1.182 +@endverbatim
1.183 +* @publishedAll
1.184 +* @released
1.185 +* @since v7.0
1.186 +*/
1.187 + {
1.188 +public:
1.189 + enum TOffsets
1.190 + {
1.191 + O_PayloadLength = 4,
1.192 + O_NextHeader = 6,
1.193 + O_HopLimit = 7,
1.194 + O_SrcAddr = 8,
1.195 + O_DstAddr = 24
1.196 + };
1.197 +
1.198 + // Basic functions, common to all header classes
1.199 + // *********************************************
1.200 +
1.201 + /**
1.202 + * Gets the header length.
1.203 + *
1.204 + * Note that the header length is fixed.
1.205 + *
1.206 + * @return Header length.
1.207 + */
1.208 + inline TInt HeaderLength() const {return 40;}
1.209 + /**
1.210 + * Gets the minimum header length.
1.211 + *
1.212 + * Note that the header length is fixed.
1.213 + *
1.214 + * @return Minimum header length
1.215 + */
1.216 + inline static TInt MinHeaderLength() {return 40; }
1.217 + /**
1.218 + * Gets the maximum header length.
1.219 + *
1.220 + * Note that the header length is fixed.
1.221 + *
1.222 + * @return Maximum header length
1.223 + */
1.224 + inline static TInt MaxHeaderLength() {return 40; }
1.225 + /**
1.226 + * Gets a pointer to the byte following the header.
1.227 + *
1.228 + * @return Pointer to the byte following the header
1.229 + */
1.230 + inline TUint8 *EndPtr() {return i + HeaderLength();}
1.231 +
1.232 + // IPv6 specific methods, get IP header field values from the packet
1.233 + // *****************************************************************
1.234 +
1.235 + inline TInt Version() const
1.236 + /**
1.237 + * Gets the IP version from the header.
1.238 + *
1.239 + * @return IP version
1.240 + */
1.241 + {
1.242 + return (i[0] >> 4) & 0xf;
1.243 + }
1.244 + inline TInt TrafficClass() const
1.245 + /**
1.246 + * Gets the traffic class from the header.
1.247 + *
1.248 + * @return Traffic class
1.249 + */
1.250 + {
1.251 + return ((i[0] << 4) & 0xf0) | ((i[1] >> 4) & 0x0f);
1.252 + }
1.253 + inline TInt FlowLabel() const
1.254 + /**
1.255 + * Gets the flow label from the header.
1.256 + *
1.257 + * @return Flow label (host byte order)
1.258 + */
1.259 + {
1.260 + return ((i[1] << 16) | (i[2] << 8) | i[3]) & 0xfffff;
1.261 + // Could also use any deterministic permutation of the 20 bits,
1.262 + // if Flow label can be treated as opaque 20 bits, and not as
1.263 + // integer where host/net byte order comes into play --msa
1.264 + }
1.265 + inline TInt PayloadLength() const
1.266 + /**
1.267 + * Gets the payload length from the header.
1.268 + *
1.269 + * @return Payload length
1.270 + */
1.271 + {
1.272 + return (i[4] << 8) | i[5];
1.273 + }
1.274 + inline TInt NextHeader() const
1.275 + /**
1.276 + * Gets the next header selector from the header.
1.277 + *
1.278 + * @return Next header selector (0..255)
1.279 + */
1.280 + {
1.281 + return i[6];
1.282 + }
1.283 + inline TInt HopLimit() const
1.284 + {
1.285 + /**
1.286 + * Gets the hop limit from the header.
1.287 + *
1.288 + * @return Hop limit (0..255)
1.289 + */
1.290 + return i[7];
1.291 + }
1.292 + //
1.293 + // The following return a modifiable reference, so
1.294 + // they can be used both for access and build.
1.295 + //
1.296 + inline TIp6Addr &SrcAddr() const
1.297 + /**
1.298 + * Gets the source address from the header.
1.299 + *
1.300 + * @return Source address
1.301 + */
1.302 + {
1.303 + return (TIp6Addr &)i[8];
1.304 + }
1.305 + inline TIp6Addr &DstAddr() const
1.306 + /**
1.307 + * Gets the destination address from the header.
1.308 + *
1.309 + * @return Destination address
1.310 + */
1.311 + {
1.312 + return (TIp6Addr &)i[24];
1.313 + }
1.314 +
1.315 + inline TBool EcnIsCongestion()
1.316 + /**
1.317 + * Gets ECN congestion status.
1.318 + *
1.319 + * see RFC-3168 for details.
1.320 + *
1.321 + * @return True, if CE bit is set on an ECN capable packet.
1.322 + */
1.323 + {
1.324 + return ((TrafficClass() & 3) == 3);
1.325 + }
1.326 +
1.327 +
1.328 + // IPv6 specific methods, set IP header field values into the packet
1.329 + // *****************************************************************
1.330 +
1.331 + inline void Init()
1.332 + /**
1.333 + * Initialises the header to basic initial values.
1.334 + *
1.335 + * @li Version = 6
1.336 + * @li Traffic Class = 0
1.337 + * @li Flow Label = 0
1.338 + * @li Payload Length = 0
1.339 + * @li Next Header = 0
1.340 + * @li Hop Limit = 0
1.341 + *
1.342 + * The Source and Destination address fields are not touched.
1.343 + */
1.344 + {
1.345 + static const union { TUint8 a[4]; TUint32 b;} x = { {6 << 4, 0, 0, 0} };
1.346 + (TUint32 &)i[0] = x.b;
1.347 + (TUint32 &)i[4] = 0;
1.348 + }
1.349 +
1.350 +
1.351 + inline void SetVersion(TInt aVersion)
1.352 + /**
1.353 + * Sets the IP version in the header.
1.354 + *
1.355 + * @param aVersion IP version (0..15, = 6 for IPv6)
1.356 + */
1.357 + {
1.358 + i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0));
1.359 + }
1.360 + inline void SetTrafficClass(TInt aClass)
1.361 + /**
1.362 + * Sets the traffic class in the header.
1.363 + *
1.364 + * @param aClass Traffic class (0..255)
1.365 + */
1.366 + {
1.367 + i[0] = (TUint8)((i[0] & 0xf0) | (aClass >> 4) & 0x0f);
1.368 + i[1] = (TUint8)((i[1] & 0x0f) | (aClass << 4) & 0xf0);
1.369 + }
1.370 + inline void SetFlowLabel(TInt aFlow)
1.371 + /**
1.372 + * Sets the flow label in the header.
1.373 + *
1.374 + * @param aFlow Flow label (20 bit integer in host order)
1.375 + */
1.376 + {
1.377 + i[1] = (TUint8)((i[1] & 0xf0) | ((aFlow >> 16) & 0x0f));
1.378 + i[2] = (TUint8)(aFlow >> 8);
1.379 + i[3] = (TUint8)aFlow;
1.380 + }
1.381 +
1.382 + inline void SetPayloadLength(TInt aLength)
1.383 + /**
1.384 + * Sets the payload length in the header.
1.385 + *
1.386 + * @param aLength Payload length
1.387 + */
1.388 + {
1.389 + i[4] = (TUint8)(aLength >> 8);
1.390 + i[5] = (TUint8)aLength;
1.391 + }
1.392 +
1.393 + inline void SetNextHeader(TInt aNextHeader)
1.394 + /**
1.395 + * Sets the next header selector from the header.
1.396 + *
1.397 + * @param aNextHeader Next header selector (0..255)
1.398 + */
1.399 + {
1.400 + i[6] = (TUint8)aNextHeader;
1.401 + }
1.402 + inline void SetHopLimit(TInt aLimit)
1.403 + /**
1.404 + * Sets the hop limit in the header.
1.405 + *
1.406 + * @param aLimit Hop limit (0..255)
1.407 + */
1.408 + {
1.409 + i[7] = (TUint8)aLimit;
1.410 + }
1.411 + inline void SetSrcAddr(const TIp6Addr &anAddr)
1.412 + /**
1.413 + * Sets the source address in the header.
1.414 + *
1.415 + * @param anAddr Source address
1.416 + */
1.417 + {
1.418 + (TIp6Addr &)i[8] = anAddr;
1.419 + }
1.420 + inline void SetDstAddr(const TIp6Addr &anAddr)
1.421 + /**
1.422 + * Sets the destination address in the header.
1.423 + *
1.424 + * @param anAddr Destination address
1.425 + */
1.426 + {
1.427 + (TIp6Addr &)i[24] = anAddr;
1.428 + }
1.429 +
1.430 +private:
1.431 + union
1.432 + {
1.433 + TUint8 i[40];
1.434 + TUint32 iAlign; // A dummy member to force the 4 byte alignment
1.435 + };
1.436 + };
1.437 +
1.438 +/** @} */
1.439 +#endif