--- /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