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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
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.
24 @ingroup ip_packet_formats
33 #include <in_sock.h> // Only for TIp6Addr !
36 * @defgroup ip_packet_formats IPv4 and IPv6 packet formats and constants
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).
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:
50 TInet6HeaderIP &ip = *(TInet6HeaderIP *)buf.Ptr();
51 if (ip.MinHeaderLength() > buf.Length() ||
52 ip.HeaderLength() + ip.PayloadLength() > buf.Length())
54 // Oops. packet too short!
56 else if (ip.Version() == 6)
58 // Packet seems to be IPv6 packet.
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:
72 TInet6Packet<TInet6HeaderIP> ip(buf);
73 if (ip.iHdr == NULL ||
74 ip.iHdr->HeaderLength() + ip.iHdr->PayloadLength() > buf.Length())
76 // Opps. packet too short!
78 else if (ip.iHdr->Version() == 6)
80 // Packet seems to be IPv6 packet.
83 * The TInet6Packet template does automatic MinHeaderLength check. The iHdr
84 * member variable is set only if the mapping succeeds at least for MinHeaderLength
87 * All mapping headers must have the following functions defined:
89 * - static function MinHeaderLength returns the minimum header length in octets.
91 * - static function MaxHeaderLength returns the maximum header length in octets (not used much).
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.
103 * @addtogroup ip_packet_formats
108 * The IPv6 minimum value for Maximum Transmission Unit (MTU) as defined in RFC 2460.
112 const TInt KInet6MinMtu = 1280;
117 // Methods of manipulating IPv6 IP header.
119 // This implementation assumes TUint8 is exactly 8 bits (and not
123 * Encapsulates an IPv6 IP header.
125 *************************
126 Extract from the RFC-2460
127 *************************
129 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130 |Version| Traffic Class | Flow Label |
131 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132 | Payload Length | Next Header | Hop Limit |
133 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
141 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145 + Destination Address +
149 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151 Version 4-bit Internet Protocol version number = 6.
153 Traffic Class 8-bit traffic class field. See section 7.
155 Flow Label 20-bit flow label. See section 6.
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.)
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
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
174 Source Address 128-bit address of the originator of the packet.
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)
195 // Basic functions, common to all header classes
196 // *********************************************
199 * Gets the header length.
201 * Note that the header length is fixed.
203 * @return Header length.
205 inline TInt HeaderLength() const {return 40;}
207 * Gets the minimum header length.
209 * Note that the header length is fixed.
211 * @return Minimum header length
213 inline static TInt MinHeaderLength() {return 40; }
215 * Gets the maximum header length.
217 * Note that the header length is fixed.
219 * @return Maximum header length
221 inline static TInt MaxHeaderLength() {return 40; }
223 * Gets a pointer to the byte following the header.
225 * @return Pointer to the byte following the header
227 inline TUint8 *EndPtr() {return i + HeaderLength();}
229 // IPv6 specific methods, get IP header field values from the packet
230 // *****************************************************************
232 inline TInt Version() const
234 * Gets the IP version from the header.
239 return (i[0] >> 4) & 0xf;
241 inline TInt TrafficClass() const
243 * Gets the traffic class from the header.
245 * @return Traffic class
248 return ((i[0] << 4) & 0xf0) | ((i[1] >> 4) & 0x0f);
250 inline TInt FlowLabel() const
252 * Gets the flow label from the header.
254 * @return Flow label (host byte order)
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
262 inline TInt PayloadLength() const
264 * Gets the payload length from the header.
266 * @return Payload length
269 return (i[4] << 8) | i[5];
271 inline TInt NextHeader() const
273 * Gets the next header selector from the header.
275 * @return Next header selector (0..255)
280 inline TInt HopLimit() const
283 * Gets the hop limit from the header.
285 * @return Hop limit (0..255)
290 // The following return a modifiable reference, so
291 // they can be used both for access and build.
293 inline TIp6Addr &SrcAddr() const
295 * Gets the source address from the header.
297 * @return Source address
300 return (TIp6Addr &)i[8];
302 inline TIp6Addr &DstAddr() const
304 * Gets the destination address from the header.
306 * @return Destination address
309 return (TIp6Addr &)i[24];
312 inline TBool EcnIsCongestion()
314 * Gets ECN congestion status.
316 * see RFC-3168 for details.
318 * @return True, if CE bit is set on an ECN capable packet.
321 return ((TrafficClass() & 3) == 3);
325 // IPv6 specific methods, set IP header field values into the packet
326 // *****************************************************************
330 * Initialises the header to basic initial values.
333 * @li Traffic Class = 0
335 * @li Payload Length = 0
336 * @li Next Header = 0
339 * The Source and Destination address fields are not touched.
342 static const union { TUint8 a[4]; TUint32 b;} x = { {6 << 4, 0, 0, 0} };
343 (TUint32 &)i[0] = x.b;
348 inline void SetVersion(TInt aVersion)
350 * Sets the IP version in the header.
352 * @param aVersion IP version (0..15, = 6 for IPv6)
355 i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0));
357 inline void SetTrafficClass(TInt aClass)
359 * Sets the traffic class in the header.
361 * @param aClass Traffic class (0..255)
364 i[0] = (TUint8)((i[0] & 0xf0) | (aClass >> 4) & 0x0f);
365 i[1] = (TUint8)((i[1] & 0x0f) | (aClass << 4) & 0xf0);
367 inline void SetFlowLabel(TInt aFlow)
369 * Sets the flow label in the header.
371 * @param aFlow Flow label (20 bit integer in host order)
374 i[1] = (TUint8)((i[1] & 0xf0) | ((aFlow >> 16) & 0x0f));
375 i[2] = (TUint8)(aFlow >> 8);
376 i[3] = (TUint8)aFlow;
379 inline void SetPayloadLength(TInt aLength)
381 * Sets the payload length in the header.
383 * @param aLength Payload length
386 i[4] = (TUint8)(aLength >> 8);
387 i[5] = (TUint8)aLength;
390 inline void SetNextHeader(TInt aNextHeader)
392 * Sets the next header selector from the header.
394 * @param aNextHeader Next header selector (0..255)
397 i[6] = (TUint8)aNextHeader;
399 inline void SetHopLimit(TInt aLimit)
401 * Sets the hop limit in the header.
403 * @param aLimit Hop limit (0..255)
406 i[7] = (TUint8)aLimit;
408 inline void SetSrcAddr(const TIp6Addr &anAddr)
410 * Sets the source address in the header.
412 * @param anAddr Source address
415 (TIp6Addr &)i[8] = anAddr;
417 inline void SetDstAddr(const TIp6Addr &anAddr)
419 * Sets the destination address in the header.
421 * @param anAddr Destination address
424 (TIp6Addr &)i[24] = anAddr;
431 TUint32 iAlign; // A dummy member to force the 4 byte alignment