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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // ip4_hdr.h - IPv4 header structure
15 // Defines the basic classes for accessing the header
16 // structures within IPv4 packets.
23 @ingroup ip_packet_formats
32 #include "es_sock.h" // for ByteOrder only!!!
35 * @addtogroup ip_packet_formats
40 * @name IP v4 constants
46 const TUint8 KInet4IP_DF = 0x40; ///< Don't Fragment flag
47 const TUint8 KInet4IP_MF = 0x20; ///< More Fragments flag
48 const TInt KInetMinMtu = 68; ///< Minimum MTU as defined in RFC-791
53 * Encapsulates an IPv4 IP header.
56 ************************
57 Extract from the RFC-791
58 ************************
60 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
61 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 |Version| IHL |Type of Service| Total Length |
63 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 | Identification |Flags| Fragment Offset |
65 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 | Time to Live | Protocol | Header Checksum |
67 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 | Destination Address |
71 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78 Internet Header Length is the length of the internet header in 32
79 bit words, and thus points to the beginning of the data. Note that
80 the minimum value for a correct header is 5
82 Type of Service: 8 bits
84 Bit 3: 0 = Normal Delay, 1 = Low Delay.
85 Bits 4: 0 = Normal Throughput, 1 = High Throughput.
86 Bits 5: 0 = Normal Relibility, 1 = High Relibility.
87 Bit 6-7: Reserved for Future Use.
92 110 - Internetwork Control
100 Total Length is the length of the datagram, measured in octets,
101 including internet header and data.
103 Identification: 16 bits
104 An identifying value assigned by the sender to aid in assembling the
105 fragments of a datagram.
108 Various Control Flags.
110 Bit 0: reserved, must be zero
111 Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
112 Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
114 Fragment Offset: 13 bits
116 This field indicates where in the datagram this fragment belongs.
117 The fragment offset is measured in units of 8 octets (64 bits). The
118 first fragment has offset zero.
122 Header Checksum: 16 bits
123 Source Address: 32 bits
124 Destination Address: 32 bits
137 * Gets the minimum header length.
138 * @return Minimum header length (= 20)
141 inline static TInt MinHeaderLength() {return 4*5; }
143 * Gets the maximum header length.
144 * @return Maximum header length (= 60)
147 inline static TInt MaxHeaderLength() {return 4*15; }
149 * Gets a pointer to the byte following the header.
150 * @return Pointer to the byte following the header
153 inline TUint8 *EndPtr() {return i + HeaderLength();}
158 O_FragmentOffset = 6,
162 inline TInt Version() const
164 * Gets the IP version from the header.
165 * @return IP version (should be 4 for IPv4)
168 return (i[0] >> 4) & 0xf;
170 inline TInt HeaderLength() const
172 * Gets the header length.
173 * @return Header length in bytes (based on IHL field)
176 return (i[0] & 0x0f) * 4; // Note: Returns bytes length!
178 inline TInt TOS() const
180 * Gets the TOS from the header.
186 inline TBool EcnIsCongestion()
188 * Gets ECN congestion status.
190 * see RFC-3168 for details.
192 * @return True, if CE bit is set on an ECN capable packet.
195 return ((TOS() & 3) == 3);
197 inline TInt TotalLength() const
199 * Gets the Total Length from the header.
200 * @return Total Length (includes IP header and payload)
203 return (i[2] << 8) | i[3];
205 inline TInt Identification() const
207 * Gets the Identification from the header.
208 * @return Identification [0..65535]
211 return (i[4] << 8) | i[5];
213 inline TInt Flags() const
215 * Gets the Flags from the header.
216 * @note returns flags byte as is, may include bits of fragment offset!
222 inline TInt DF() const
224 * Gets the DF flag from the header.
225 * @return DF flag (= KInet4IP_DF, if set and zero otherwise)
228 return i[6] & KInet4IP_DF;
230 inline TInt MF() const
232 * Gets the MF flag from the header.
233 * @return MF flag (= KInet4IP_MF, if set and zero otherwise)
236 return i[6] & KInet4IP_MF;
238 inline TInt FragmentOffset() const
240 * Gets the Fragment Offset from the header.
241 * @return Fragment Offset (raw 8 octet units, not a bytes offset!)
244 return ((i[6] & 0x1f) << 8) | i[7];
246 inline TInt Ttl() const
248 * Gets the Time to Live from the header.
249 * @return Time to Live [0..255]
254 inline TInt Protocol() const
256 * Gets the Protocol from the header.
257 * @return Protocol [0..255]
262 inline TInt Checksum() const
264 * Gets the Header Checksum from the header.
265 * @return Header Checksum (in NETWORK byte order)
268 // Checksum is used in network byte order
269 return *((TUint16 *)&i[10]);
271 inline TUint32 SrcAddr() const
273 * Gets the source address from the header.
274 * @return Source address (in host byte order)
277 return (i[12] << 24) | (i[13] << 16) | (i[14] << 8) | i[15];
279 inline TUint32 DstAddr() const
281 * Gets the destination address from the header.
282 * @return Destination address (in host byte order)
285 return (i[16] << 24) | (i[17] << 16) | (i[18] << 8) | i[19];
287 inline TUint32 &SrcAddrRef() const
289 * Gets a raw reference to the source address in network byte order.
290 * @return Raw reference to the source address
293 return (TUint32 &)i[12];
295 inline TUint32 &DstAddrRef() const
297 * Gets a raw reference to the destination address in network byte order.
298 * @return Raw reference to the destination address
301 return (TUint32 &)i[16];
303 inline TPtrC8 Options() const
305 * Gets the Options from the header (const overload).
309 * This relies on correct value of IHL! Must not be used with
310 * corrupt headers (will panic if IHL < 5!).
313 // *NOTE* This includes the padding bytes, or can be empty!
314 return TPtrC8((TUint8 *)&i[20], HeaderLength() - 20);
316 inline TPtr8 Options()
318 * Gets the Options from the header.
322 * This relies on correct value of IHL! Must not be used with
323 * corrupt headers (will panic if IHL < 5!).
326 // It is yet unclear what will be the best way to build
327 // the options into the header. For the time being this
328 // method returns a modifiable Ptr8 to the the available
329 // option space. For this to work, the application must
330 // have used the SetHeaderLength() to fix the current
332 return TPtr8((TUint8 *)&i[20], HeaderLength() - 20);
335 inline void Init(TInt aTOS = 0)
337 * Initialises the IPv4 header to basic initial values.
341 * @li Total Length = 20
342 * @li Identification = 0
343 * @li Fragment Offset = 0
347 * @li TOS = aTOS (optional parameter, default = 0)
349 * However, address fields are not touched, because
350 * they are most often set separately in any case.
352 * @param aTOS initial value for TOS (= 0)
355 i[0] = 0x45; // Version=4, IHL=5 (= 20 bytes)
356 i[1] = (TUint8)aTOS; // TOS
358 i[3] = 20; // Total length = 20
359 *((TInt32 *)&i[4]) = 0; // Identification = 0, flags=0, Fragment offset = 0;
360 *((TInt32 *)&i[8]) = 0; // TTL=0,Protocol=0,Checksum=0
363 // Build, set IP header field values into the packet
366 inline void SetVersion(TInt aVersion)
368 * Sets the IP version in the header.
369 * @param aVersion the value to be set [0..15]
372 i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0));
374 inline void SetHeaderLength(TInt aLength)
376 * Sets the header length (IHL).
379 * the length of the IPv4 header in BYTES. The
380 * IHL is computed from this, without any sanity
381 * checks. The valid range is [20..60].
384 i[0] = (TUint8)((i[0] & 0xf0) | ((aLength >> 2) & 0x0f));
386 inline void SetTOS(TInt aTos)
388 * Sets the TOS in the header.
389 * @param aTos The TOS value to set [0..255]
394 inline void SetTotalLength(TInt aLength)
396 * Sets the Total Length in the header.
398 * @param aLength the length of combined header and
399 * payload in bytes (no sanity checks, but the
400 * value should be in range [20..65535]). Only
401 * 16 least significant bits used.
404 i[3] = (TUint8)aLength;
405 i[2] = (TUint8)(aLength >> 8);
407 inline void SetIdentification(TInt aId)
409 * Sets the Identification in the header.
411 * @param aId the value to be set (only 16 least significant
412 * bits are used, rest is ignored).
416 i[4] = (TUint8)(aId >> 8);
419 inline void SetFlags(TUint8 aFlags)
421 * Sets the Flags in the header.
423 * Flags are assumed to be in the three most significant bits
424 * of aFlags, in their proper positions.
425 * (No individual settings provided, if you need to set a flag
426 * without affecting others, use Flags() to get old values,
427 * update and store the result with SetFlags()).
429 * @param aFlags contains the new flags
432 i[6] = (TUint8)((i[6] & 0x1f) | (aFlags & 0xe0));
434 inline void SetFragmentOffset(TUint16 aOffset)
436 * Sets the Fragment Offset in the header.
437 * @param aOffset Fragment Offset (8 octet units, not in bytes)
440 i[6] = (TUint8)((i[6] & 0xe0) | ((aOffset >> 8) & 0x1f));
441 i[7] = (TUint8)aOffset;
443 inline void SetTtl(TInt aTTL)
445 * Sets the Time to Live in the header.
446 * @param aTTL Time to Live [0..255]
451 inline void SetProtocol(TInt aProtocol)
453 * Sets the Protocol in the header.
454 * @param aProtocol Protocol [0..255]
457 i[9] = (TUint8)aProtocol;
459 inline void SetChecksum(TInt aSum)
461 * Sets the Header Checksum in the header.
462 * @param aSum Header Checksum [0..65535]
463 * (16 least significant bits stored
464 * as is (assumed to be in NETWORK byte order).
467 // Checksum is used in network byte order
468 *((TUint16 *)&i[10]) = (TUint16)aSum;
471 inline void SetSrcAddr(TUint32 aAddr)
473 * Sets the source address in the header.
474 * @param aAddr Source address (IPv4, 32 bit integer in host byte order)
477 i[15] = (TUint8)aAddr;
478 i[14] = (TUint8)(aAddr >> 8);
479 i[13] = (TUint8)(aAddr >> 16);
480 i[12] = (TUint8)(aAddr >> 24);
483 inline void SetDstAddr(TUint32 aAddr)
485 * Sets the destination address in the header.
486 * @param aAddr Destination IPv4 address (32 bit integer) in host byte order
489 i[19] = (TUint8)aAddr;
490 i[18] = (TUint8)(aAddr >> 8);
491 i[17] = (TUint8)(aAddr >> 16);
492 i[16] = (TUint8)(aAddr >> 24);
496 // The old IPv4 stack leaves IP header in packet when passing it upwards,
497 // but this header is swapped into host order. As upper layers really don't
498 // need this stuff much, only few "compatibility" methods is defined here
501 inline TInt HostHeaderLength() const
504 * Gets the Header Length from a header that is in Host byte order.
505 * @return Header Length
507 * @deprecated There is no reason to use swapped headers
509 return (i[3] & 0x0f) * 4;
511 inline TInt HostProtocol() const
513 * Gets the Protocol from a header that is in Host byte order.
515 * @deprecated There is no reason to use swapped headers
523 * Swaps the byte order in the header.
524 * @deprecated There is no reason to use swapped headers
527 *(TUint32 *)(&i[0]) = ByteOrder::Swap32(*(TUint32 *)(&i[0]));
528 *(TUint32 *)(&i[4]) = ByteOrder::Swap32(*(TUint32 *)(&i[4]));
529 *(TUint32 *)(&i[8]) = ByteOrder::Swap32(*(TUint32 *)(&i[8]));
530 *(TUint32 *)(&i[12]) = ByteOrder::Swap32(*(TUint32 *)(&i[12]));
531 *(TUint32 *)(&i[16]) = ByteOrder::Swap32(*(TUint32 *)(&i[16]));
537 TUint8 i[4*15]; ///< This allocates maximum length (60 bytes)
538 TUint32 iAlign; ///< A dummy member to force the 4 byte alignment
543 * @name IP v4 Option constants
549 const TUint8 KInet4Option_End = 0x00;
550 const TUint8 KInet4Option_Nop = 0x01;
552 const TUint8 KInet4OptionFlag_Copy = 0x80;
560 * @name ICMP v4 constants
566 /** Echo Reply. See TInet6HeaderICMP_Echo (IPv4 and IPv6 use the same format). */
567 const TUint8 KInet4ICMP_EchoReply = 0;
568 const TUint8 KInet4ICMP_Unreachable = 3;
569 const TUint8 KInet4ICMP_SourceQuench = 4;
570 const TUint8 KInet4ICMP_Redirect = 5;
571 /** Echo Request. See TInet6HeaderICMP_Echo (IPv4 and IPv6 use the same format). */
572 const TUint8 KInet4ICMP_Echo = 8;
573 const TUint8 KInet4ICMP_TimeExceeded = 11;
574 const TUint8 KInet4ICMP_ParameterProblem = 12;
575 const TUint8 KInet4ICMP_TimeStamp = 13;
576 const TUint8 KInet4ICMP_TimeStampReply = 14;