epoc32/include/ip4_hdr.h
branchSymbian2
changeset 2 2fe1408b6811
child 4 837f303aceeb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/epoc32/include/ip4_hdr.h	Tue Mar 16 16:12:26 2010 +0000
@@ -0,0 +1,580 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// 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
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// ip4_hdr.h - IPv4 header structure
+// Defines the basic classes for accessing the header
+// structures within IPv4 packets.
+//
+
+
+
+/**
+ @file ip4_hdr.h
+ @ingroup ip_packet_formats
+ @publishedAll
+ @released
+*/
+
+#ifndef __IP4_HDR_H__
+#define __IP4_HDR_H__
+
+#include "in_hdr.h"
+#include "es_sock.h"		// for ByteOrder only!!!
+
+/**
+* @addtogroup ip_packet_formats
+* @{
+*/
+
+/**
+* @name IP v4 constants 
+* @since v7.0
+* @publishedAll
+* @released
+*/
+///@{
+const TUint8 KInet4IP_DF = 0x40;	///< Don't Fragment flag
+const TUint8 KInet4IP_MF = 0x20;	///< More Fragments flag
+const TInt KInetMinMtu = 68;		///< Minimum MTU as defined in RFC-791 
+///@}
+
+class TInet6HeaderIP4
+/**
+*	Encapsulates an IPv4 IP header. 
+* 
+@verbatim
+  ************************
+  Extract from the RFC-791
+  ************************
+  0                   1                   2                   3
+  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
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |Version|  IHL  |Type of Service|          Total Length         |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |         Identification        |Flags|      Fragment Offset    |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |  Time to Live |    Protocol   |         Header Checksum       |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |                       Source Address                          |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |                    Destination Address                        |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |                    Options                    |    Padding    |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  
+  Version:  4 bits = 4
+  IHL:  4 bits
+
+    Internet Header Length is the length of the internet header in 32
+    bit words, and thus points to the beginning of the data.  Note that
+    the minimum value for a correct header is 5
+
+  Type of Service:  8 bits
+      Bits 0-2:  Precedence.
+      Bit    3:  0 = Normal Delay,      1 = Low Delay.
+      Bits   4:  0 = Normal Throughput, 1 = High Throughput.
+      Bits   5:  0 = Normal Relibility, 1 = High Relibility.
+      Bit  6-7:  Reserved for Future Use.
+
+	  Precedence
+
+          111 - Network Control
+          110 - Internetwork Control
+          101 - CRITIC/ECP
+          100 - Flash Override
+          011 - Flash
+          010 - Immediate
+          001 - Priority
+          000 - Routine
+  Total Length:  16 bits
+    Total Length is the length of the datagram, measured in octets,
+    including internet header and data.
+
+  Identification:  16 bits
+    An identifying value assigned by the sender to aid in assembling the
+    fragments of a datagram.
+
+  Flags:  3 bits
+    Various Control Flags.
+
+      Bit 0: reserved, must be zero
+      Bit 1: (DF) 0 = May Fragment,  1 = Don't Fragment.
+      Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
+
+  Fragment Offset:  13 bits
+
+    This field indicates where in the datagram this fragment belongs.
+    The fragment offset is measured in units of 8 octets (64 bits).  The
+    first fragment has offset zero.
+
+  Time to Live:  8 bits
+  Protocol:  8 bits
+  Header Checksum:  16 bits
+  Source Address:  32 bits
+  Destination Address:  32 bits
+@endverbatim
+
+@publishedAll
+@released
+@since v7.0
+*/
+	{
+public:
+	//
+	// Basic
+	//
+	/**
+	* Gets the minimum header length.	
+	* @return Minimum header length (= 20) 
+	* @since v7.0
+	*/
+	inline static TInt MinHeaderLength() {return 4*5; }
+	/**
+	* Gets the maximum header length.
+	* @return Maximum header length (= 60)
+	* @since v7.0
+	*/
+	inline static TInt MaxHeaderLength() {return 4*15; }
+	/**
+	* Gets a pointer to the byte following the header.
+	* @return Pointer to the byte following the header
+	* @since v7.0
+	*/
+	inline TUint8 *EndPtr() {return i + HeaderLength();}
+
+	enum TOffsets
+		{
+		O_TotalLength = 2,
+		O_FragmentOffset = 6,
+		O_TTL = 8,
+		O_Protocol = 9
+		};
+	inline TInt Version() const
+		/**
+		* Gets the IP version from the header.
+		* @return IP version (should be 4 for IPv4)
+		*/ 
+		{
+		return (i[0] >> 4) & 0xf;
+		}
+	inline TInt HeaderLength() const
+		/**
+		* Gets the header length.
+		* @return Header length in bytes (based on IHL field)
+		*/
+		{
+		return (i[0] & 0x0f) * 4;	// Note: Returns bytes length!
+		}
+	inline TInt TOS() const
+		/**
+		* Gets the TOS from the header.
+		* @return TOS
+		*/
+		{
+		return i[1];
+		}
+	inline TBool EcnIsCongestion()
+		/**
+		* Gets ECN congestion status.
+		*
+		* see RFC-3168 for details.
+		*
+		* @return	True, if CE bit is set on an ECN capable packet.
+		*/
+		{
+		return ((TOS() & 3) == 3);
+		}
+	inline TInt TotalLength() const
+		/**
+		* Gets the Total Length from the header.
+		* @return Total Length (includes IP header and payload)
+		*/
+		{
+		return (i[2] << 8) | i[3];
+		}
+	inline TInt Identification() const
+		/**
+		* Gets the Identification from the header.
+		* @return Identification [0..65535]
+		*/
+		{
+		return (i[4] << 8) | i[5];
+		}
+	inline TInt Flags() const
+		/**
+		* Gets the Flags from the header.
+		* @note returns flags byte as is, may include bits of fragment offset!
+		* @return Flags
+		*/
+		{
+		return i[6];
+		}
+	inline TInt DF() const
+		/**
+		* Gets the DF flag from the header.
+		* @return DF flag (= KInet4IP_DF, if set and zero otherwise)
+		*/
+		{
+		return i[6] & KInet4IP_DF;
+		}
+	inline TInt MF() const
+		/**
+		* Gets the MF flag from the header.
+		* @return MF flag (= KInet4IP_MF, if set and zero otherwise)
+		*/
+		{
+		return i[6] & KInet4IP_MF;
+		}
+	inline TInt FragmentOffset() const
+		/**
+		* Gets the Fragment Offset from the header.
+		* @return Fragment Offset (raw 8 octet units, not a bytes offset!)
+		*/
+		{
+		return ((i[6] & 0x1f) << 8) | i[7];
+		}
+	inline TInt Ttl() const
+		/**
+		* Gets the Time to Live from the header.
+		* @return Time to Live [0..255]
+		*/
+		{
+		return i[8];
+		}
+	inline TInt Protocol() const
+		/**
+		* Gets the Protocol from the header.
+		* @return Protocol [0..255]
+		*/
+		{
+		return i[9];
+		}
+	inline TInt Checksum() const
+		/**
+		* Gets the Header Checksum from the header.
+		* @return Header Checksum (in NETWORK byte order)
+		*/
+		{
+		// Checksum is used in network byte order
+		return *((TUint16 *)&i[10]);
+		}
+	inline TUint32 SrcAddr() const
+		/**
+		* Gets the source address from the header.
+		* @return Source address (in host byte order)
+		*/
+		{
+		return (i[12] << 24) | (i[13] << 16) | (i[14] << 8) | i[15];
+		}
+	inline TUint32 DstAddr() const
+		/**
+		* Gets the destination address from the header.
+		* @return Destination address (in host byte order)
+		*/
+		{
+		return (i[16] << 24) | (i[17] << 16) | (i[18] << 8) | i[19];
+		}
+	inline TUint32 &SrcAddrRef() const
+		/**
+		* Gets a raw reference to the source address in network byte order.
+		* @return Raw reference to the source address
+		*/
+		{
+		return (TUint32 &)i[12];
+		}
+	inline TUint32 &DstAddrRef() const
+		/**
+		* Gets a raw reference to the destination address in network byte order.
+		* @return Raw reference to the destination address
+		*/
+		{
+		return (TUint32 &)i[16];
+		}
+	inline TPtrC8 Options() const
+		/**
+		* Gets the Options from the header (const overload).
+		* @return Options
+		*
+		* @note
+		*	This relies on correct value of IHL! Must not be used with
+		*	corrupt headers (will panic if IHL < 5!).
+		*/
+		{
+		// *NOTE* This includes the padding bytes, or can be empty!
+		return TPtrC8((TUint8 *)&i[20], HeaderLength() - 20);
+		}
+	inline TPtr8 Options()
+		/**
+		* Gets the Options from the header.
+		* @return Options
+		*
+		* @note
+		*	This relies on correct value of IHL! Must not be used with
+		*	corrupt headers (will panic if IHL < 5!).
+		*/
+		{
+		// It is yet unclear what will be the best way to build
+		// the options into the header. For the time being this
+		// method returns a modifiable Ptr8 to the the available
+		// option space. For this to work, the application must
+		// have used the SetHeaderLength() to fix the current
+		// available length.
+		return TPtr8((TUint8 *)&i[20], HeaderLength() - 20);
+		}
+
+	inline void Init(TInt aTOS = 0)
+		/**
+		* Initialises the IPv4 header to basic initial values.
+		*
+		* @li	Version = 4
+		* @li	IHL = 5
+		* @li	Total Length = 20
+		* @li	Identification = 0
+		* @li	Fragment Offset = 0
+		* @li	Flags = 0
+		* @li	TTL = 0
+		* @li	Checksum = 0
+		* @li	TOS = aTOS (optional parameter, default = 0)
+		*
+		* However, address fields are not touched, because
+		* they are most often set separately in any case.
+		*
+		* @param	aTOS	initial value for TOS (= 0)
+		*/
+		{
+		i[0] = 0x45;			// Version=4, IHL=5 (= 20 bytes)
+		i[1] = (TUint8)aTOS;	// TOS
+		i[2] = 0;
+		i[3] = 20;				// Total length = 20
+		*((TInt32 *)&i[4]) = 0;	// Identification = 0, flags=0, Fragment offset = 0;
+		*((TInt32 *)&i[8]) = 0;	// TTL=0,Protocol=0,Checksum=0
+		}
+	//
+	// Build, set IP header field values into the packet
+	//
+
+	inline void SetVersion(TInt aVersion)
+		/**
+		* Sets the IP version in the header.
+		* @param	aVersion the value to be set [0..15]
+		*/
+		{
+		i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0));
+		}
+	inline void SetHeaderLength(TInt aLength)
+		/**
+		* Sets the header length (IHL).
+		*
+		* @param aLength
+		*	the length of the IPv4 header in BYTES. The
+		*	IHL is computed from this, without any sanity
+		*	checks. The valid range is [20..60].
+		*/
+		{
+		i[0] =  (TUint8)((i[0] & 0xf0) | ((aLength >> 2) & 0x0f));
+		}
+	inline void SetTOS(TInt aTos)
+		/**
+		* Sets the TOS in the header.
+		* @param	aTos	The TOS value to set [0..255]
+		*/
+		{
+		i[1] = (TUint8)aTos;
+		}
+	inline void SetTotalLength(TInt aLength)
+		/**
+		* Sets the Total Length in the header.
+		*
+		* @param	aLength the length of combined header and
+		*			payload in bytes (no sanity checks, but the
+		*			value should be in range [20..65535]). Only
+		*			16 least significant bits used.
+		*/
+		{
+		i[3] = (TUint8)aLength;
+		i[2] = (TUint8)(aLength >> 8);
+		}
+	inline void SetIdentification(TInt aId)
+		/**
+		* Sets the Identification in the header.
+		*
+		* @param	aId	the value to be set (only 16 least significant
+		*			bits are used, rest is ignored).
+		*/
+		{
+		i[5] = (TUint8)aId;
+		i[4] = (TUint8)(aId >> 8);
+		}
+
+	inline void SetFlags(TUint8 aFlags)
+		/**
+		* Sets the Flags in the header.
+		*
+		* Flags are assumed to be in the three most significant bits
+		* of aFlags, in their proper positions.
+		* (No individual settings provided, if you need to set a flag
+		* without affecting others, use Flags() to get old values,
+		* update and store the result with SetFlags()).
+		*
+		* @param	aFlags	contains the new flags
+		*/
+		{
+		i[6] = (TUint8)((i[6] & 0x1f) | (aFlags & 0xe0));
+		}
+	inline void SetFragmentOffset(TUint16 aOffset)
+		/**
+		* Sets the Fragment Offset in the header.
+		* @param aOffset Fragment Offset (8 octet units, not in bytes)
+		*/
+		{
+		i[6] = (TUint8)((i[6] & 0xe0) | ((aOffset >> 8) & 0x1f));
+		i[7] = (TUint8)aOffset;
+		}
+	inline void SetTtl(TInt aTTL)
+		/**
+		* Sets the Time to Live in the header.
+		* @param aTTL Time to Live [0..255]
+		*/
+		{
+		i[8] = (TUint8)aTTL;
+		}
+	inline void SetProtocol(TInt aProtocol)
+		/**
+		* Sets the Protocol in the header.
+		* @param aProtocol Protocol [0..255]
+		*/
+		{
+		i[9] = (TUint8)aProtocol;
+		}
+	inline void SetChecksum(TInt aSum)
+		/**
+		* Sets the Header Checksum in the header.
+		* @param aSum Header Checksum [0..65535]
+		*	(16 least significant bits stored
+		*	as is (assumed to be in NETWORK byte order).					
+		*/
+		{
+		// Checksum is used in network byte order
+		*((TUint16 *)&i[10]) = (TUint16)aSum;
+		}
+
+	inline void SetSrcAddr(TUint32 aAddr)
+		/**
+		* Sets the source address in the header.
+		* @param aAddr Source address (IPv4, 32 bit integer in host byte order)
+		*/
+		{
+		i[15] = (TUint8)aAddr;
+		i[14] = (TUint8)(aAddr >> 8);
+		i[13] = (TUint8)(aAddr >> 16);
+		i[12] = (TUint8)(aAddr >> 24);
+		}
+
+	inline void SetDstAddr(TUint32 aAddr)
+		/**
+		* Sets the destination address in the header.
+		* @param aAddr Destination IPv4 address (32 bit integer) in host byte order
+		*/
+		{
+		i[19] = (TUint8)aAddr;
+		i[18] = (TUint8)(aAddr >> 8);
+		i[17] = (TUint8)(aAddr >> 16);
+		i[16] = (TUint8)(aAddr >> 24);
+		}
+
+	//
+	// The old IPv4 stack leaves IP header in packet when passing it upwards,
+	// but this header is swapped into host order. As upper layers really don't
+	// need this stuff much, only few "compatibility" methods is defined here
+	//
+
+	inline TInt HostHeaderLength() const
+		{
+		/**
+		* Gets the Header Length from a header that is in Host byte order.
+		* @return Header Length
+		*
+		* @deprecated There is no reason to use swapped headers
+		*/
+		return (i[3] & 0x0f) * 4;
+		}
+	inline TInt HostProtocol() const
+		/**
+		* Gets the Protocol from a header that is in Host byte order.
+		* @return Protocol
+		* @deprecated There is no reason to use swapped headers
+		*/
+		{
+		return i[10];
+		}
+
+	inline void Swap()
+		/**
+		* Swaps the byte order in the header.
+		* @deprecated There is no reason to use swapped headers
+		*/
+		{
+		*(TUint32 *)(&i[0]) = ByteOrder::Swap32(*(TUint32 *)(&i[0]));
+		*(TUint32 *)(&i[4]) = ByteOrder::Swap32(*(TUint32 *)(&i[4]));
+		*(TUint32 *)(&i[8]) = ByteOrder::Swap32(*(TUint32 *)(&i[8]));
+		*(TUint32 *)(&i[12]) = ByteOrder::Swap32(*(TUint32 *)(&i[12]));
+		*(TUint32 *)(&i[16]) = ByteOrder::Swap32(*(TUint32 *)(&i[16]));
+		}
+				
+private:
+	union
+		{
+		TUint8 i[4*15];	///< This allocates maximum length (60 bytes)
+		TUint32 iAlign;	///< A dummy member to force the 4 byte alignment
+		};
+	};
+
+/**
+* @name IP v4 Option constants
+* @since v7.0
+* @publishedAll
+* @released
+*/
+///@{
+const TUint8 KInet4Option_End			= 0x00;
+const TUint8 KInet4Option_Nop			= 0x01;
+
+const TUint8 KInet4OptionFlag_Copy		= 0x80;
+///@}
+
+//
+//	ICMP v4 constants
+//	=================
+//
+/**
+* @name ICMP v4 constants 
+* @since v7.0
+* @publishedAll
+* @released
+*/
+///@{
+/** Echo Reply. See TInet6HeaderICMP_Echo (IPv4 and IPv6 use the same format). */
+const TUint8 KInet4ICMP_EchoReply		=  0;
+const TUint8 KInet4ICMP_Unreachable		=  3;
+const TUint8 KInet4ICMP_SourceQuench	=  4;
+const TUint8 KInet4ICMP_Redirect		=  5;
+/** Echo Request. See TInet6HeaderICMP_Echo (IPv4 and IPv6 use the same format). */
+const TUint8 KInet4ICMP_Echo			=  8;
+const TUint8 KInet4ICMP_TimeExceeded	= 11;
+const TUint8 KInet4ICMP_ParameterProblem = 12;
+const TUint8 KInet4ICMP_TimeStamp		= 13;
+const TUint8 KInet4ICMP_TimeStampReply	= 14;
+///@}
+
+///@}
+#endif