--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/epoc32/include/tcp_hdr.h Tue Mar 16 16:12:26 2010 +0000
@@ -0,0 +1,427 @@
+// 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:
+// tcp_hdr.h - TCP protocol header structure
+// Defines the basic classes for accessing the header structures within TCP packets.
+//
+
+
+
+/**
+ @file tcp_hdr.h
+ @ingroup ip_packet_formats
+ @publishedAll
+ @released
+*/
+
+#ifndef __TCP_HDR_H__
+#define __TCP_HDR_H__
+
+#include <e32std.h>
+#include "in_hdr.h"
+#include "sbque.h"
+
+/**
+* @addtogroup ip_packet_formats
+* @{
+*/
+
+//
+// TInet6HeaderTCP
+//
+// *NOTE*
+// TInet6HeaderTCP declares for maximum length TCP header
+// (64 bytes). A valid TCP packet can be shorter and failing
+// to map full 64 bytes from a packet is not an error condition.
+//
+
+/** @name TCP Header length constants
+* @{
+*/
+const TInt KTcpMinHeaderLength = 20;
+const TInt KTcpMaxHeaderLength = 60;
+const TInt KTcpMaxOptionLength = 40;
+/** @} */
+
+/** @name TCP control flags
+* @{
+*/
+const TUint8 KTcpCtlFIN = 1;
+const TUint8 KTcpCtlSYN = 2;
+const TUint8 KTcpCtlRST = 4;
+const TUint8 KTcpCtlPSH = 8;
+const TUint8 KTcpCtlACK = 16;
+const TUint8 KTcpCtlURG = 32;
+const TUint8 KTcpCtlECE = 0x40;
+const TUint8 KTcpCtlCWR = 0x80;
+/** @} */
+
+/** @name TCP options
+* @{
+*/
+const TUint8 KTcpOptEnd = 0;
+const TUint8 KTcpOptNop = 1;
+const TUint8 KTcpOptMSS = 2;
+const TUint8 KTcpOptWScale = 3;
+const TUint8 KTcpOptSackOk = 4;
+const TUint8 KTcpOptSack = 5;
+const TUint8 KTcpOptTimeStamps = 8;
+const TUint8 KTcpOptCount = 9;
+
+const TUint8 KTcpOptMinLen[] = {1, 1, 4, 3, 2, 6, 2, 2, 10};
+const TUint8 KTcpOptMaxLen[] = {1, 1, 4, 3, 2, 36, 40, 40, 10};
+const TUint32 KTcpOptAlignFlag = 0x00000001;
+/** @} */
+
+
+class TTcpOptions
+/** TCP Options Header.
+@publishedAll
+@released
+*/
+ {
+public:
+ inline TTcpOptions() { Init(); }
+ IMPORT_C void Init();
+ IMPORT_C TInt Length() const;
+ inline TBool Error() const { return iError; }
+ inline void ClearError() { iError = EFalse; }
+
+ inline TInt MSS() const { return iMSS; }
+ inline void SetMSS(TInt aMSS) { iMSS = aMSS; }
+ inline void ClearMSS() { iMSS = -1; }
+
+ inline TBool TimeStamps() const { return iTimeStamps; }
+ inline TBool TimeStamps(TUint32& aTsVal, TUint32& aTsEcr) const
+ {
+ aTsVal = iTsVal;
+ aTsEcr = iTsEcr;
+ return iTimeStamps;
+ }
+ inline void SetTimeStamps(TUint32 aTsVal, TUint32 aTsEcr)
+ {
+ iTsVal = aTsVal;
+ iTsEcr = aTsEcr;
+ iTimeStamps = ETrue;
+ }
+ inline void ClearTimeStamps() { iTimeStamps = EFalse; }
+
+ inline TBool SackOk() const { return iSackOk; }
+ inline void SetSackOk() { iSackOk = ETrue; }
+ inline void ClearSackOk() { iSackOk = EFalse; }
+ inline void SuppressSack(TBool aBool=ETrue) { iSuppressSack = aBool; }
+ inline SequenceBlockQueue& SackBlocks() { return iBlocks; }
+
+ inline TInt Unknown() const { return iUnknown; }
+ inline void ClearUnknown() { iUnknown = 0; }
+
+ /// Query window scale option from TCP header options.
+ /// Wscale == 1 means scale factor 1, i.e. shift count of 0 is used in TCP option.
+ /// Wscale == 0 means that wscale option is not used in TCP header.
+ inline TUint WindowScale() const { return iWscale; }
+
+ inline void SetWindowScale(TUint8 aWscale) { iWscale = aWscale; }
+
+ /**
+ If set, each option will be aligned to 32-bit longword boundaries with Nop padding.
+ By default the Nop padding is not applied.
+
+ @param aAlignNop ETrue if option alignment should be applied.
+ */
+ inline void SetAlignOpt(TBool aAlignOpt)
+ {
+ if(aAlignOpt)
+ iFlags |= KTcpOptAlignFlag;
+ else
+ iFlags &= ~KTcpOptAlignFlag;
+ }
+
+private:
+ friend class TInet6HeaderTCP;
+
+ IMPORT_C TBool ProcessOptions(const TUint8 *aPtr, TUint aLen);
+ IMPORT_C TUint OutputOptions(TUint8 *aPtr, TUint aMaxLen);
+
+ void CheckOptAlignment(TUint8* aPtr, TUint& aI, TUint aNumBytes);
+
+ inline TInt AlignedLength(TInt aLength) const
+ /**
+ Calculate the actual space requirement for option with given length.
+
+ Takes optional 32-bit alignment into account.
+ */
+ { if (iFlags & KTcpOptAlignFlag) return (aLength + 3) & ~3; else return aLength; }
+
+ TInt iMSS;
+ TInt iUnknown;
+ TUint32 iTsVal;
+ TUint32 iTsEcr;
+ SequenceBlockQueue iBlocks;
+ TBool iError;
+ TBool iTimeStamps;
+ TBool iSackOk;
+ TBool iSuppressSack;
+ TUint iWscale; ///< Window scale option [RFC 1323].
+ TUint32 iFlags; ///< ETrue if options are to be aligned.
+ };
+
+
+
+class TInet6HeaderTCP
+/** TCP segment header.
+@verbatim
+Extract from RFC-793
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Source Port | Destination Port |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Sequence Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Acknowledgment Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data | |U|A|P|R|S|F| |
+ | Offset| Reserved |R|C|S|S|Y|I| Window |
+ | | |G|K|H|T|N|N| |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Checksum | Urgent Pointer |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Options | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | data |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+@endverbatim
+@publishedAll
+@released
+*/
+ {
+public:
+ //
+ // Basic
+ //
+ inline static TInt MinHeaderLength() {return KTcpMinHeaderLength; }
+ inline static TInt MaxHeaderLength() {return KTcpMaxHeaderLength; }
+ inline TUint8 *EndPtr() {return i + HeaderLength();}
+ //
+ // Access, Get TCP field values from the packet
+ //
+ inline TUint SrcPort() const
+ {
+ return (i[0] << 8) + i[1];
+ }
+ inline TUint DstPort() const
+ {
+ return (i[2] << 8) + i[3];
+ }
+ inline TTcpSeqNum Sequence() const
+ {
+ return (i[4] << 24) | (i[5] << 16) | (i[6] << 8) | i[7];
+ }
+ inline TTcpSeqNum Acknowledgment() const
+ {
+ return (i[8] << 24) | (i[9] << 16) | (i[10] << 8) | i[11];
+ }
+ inline TInt HeaderLength() const
+ {
+ // Return TCP Header Length in bytes (including options and padding)
+ return (i[12] >> 2) & (0xF << 2);
+ }
+ //
+ // A testing method for each individual Control Bit is provided
+ // (It remains to be seen whether this is useful or not). Note
+ // also that the result of the AND is returned, not 0 and 1.
+ //
+ inline TInt FIN() const
+ {
+ return i[13] & KTcpCtlFIN;
+ }
+ inline TInt SYN() const
+ {
+ return i[13] & KTcpCtlSYN;
+ }
+ inline TInt RST() const
+ {
+ return i[13] & KTcpCtlRST;
+ }
+ inline TInt PSH() const
+ {
+ return i[13] & KTcpCtlPSH;
+ }
+ inline TInt ACK() const
+ {
+ return i[13] & KTcpCtlACK;
+ }
+ inline TInt URG() const
+ {
+ return i[13] & KTcpCtlURG;
+ }
+
+ /// ECN Echo flag [RFC 3168].
+ inline TInt ECE() const
+ {
+ return i[13] & KTcpCtlECE;
+ }
+
+ /// ECN: Congestion Window Reduced [RFC 3168].
+ inline TInt CWR() const
+ {
+ return i[13] & KTcpCtlCWR;
+ }
+
+ // A method to access all of the above as is. Note that this
+ // also returns the reserved unspecified bits. Value can be
+ // non-zero, even if none of the above is set. However, it only
+ // returns unspecified bits from the 13th byte, not any from 12th!
+ inline TUint8 Control() const
+ {
+ return i[13];
+ }
+ //
+ inline TUint Window() const
+ {
+ return (i[14] << 8) + i[15];
+ }
+ inline TUint Checksum() const
+ {
+ // Checksum is used in network byte order
+ return *((TUint16 *)&i[16]);
+ }
+ inline TUint Urgent() const
+ {
+ return (i[18] << 8) + i[19];
+ }
+ inline TBool Options(TTcpOptions& aOptions) const
+ {
+ return aOptions.ProcessOptions(i + KTcpMinHeaderLength, HeaderLength() - KTcpMinHeaderLength);
+ }
+ //Backwards compatibility, mainly for IPRotor.
+ inline TPtr8 Options() const
+ {
+ TInt len = HeaderLength() - 20;
+ return TPtr8((TUint8 *)&i[20], len, len);
+ }
+
+ //
+ // Build, Set TCP field value to the packet
+ //
+ inline void SetSrcPort(TUint aPort)
+ {
+ i[0] = (TUint8)(aPort >> 8);
+ i[1] = (TUint8)aPort;
+ }
+ inline void SetDstPort(TUint aPort)
+ {
+ i[2] = (TUint8)(aPort >> 8);
+ i[3] = (TUint8)aPort;
+ }
+ inline void SetSequence(TTcpSeqNum aSeq)
+ {
+ i[7] = (TUint8)aSeq.Uint32();
+ i[6] = (TUint8)(aSeq.Uint32() >> 8);
+ i[5] = (TUint8)(aSeq.Uint32() >> 16);
+ i[4] = (TUint8)(aSeq.Uint32() >> 24);
+ }
+ inline void SetAcknowledgment(TTcpSeqNum aAck)
+ {
+ i[11] = (TUint8)aAck.Uint32();
+ i[10] = (TUint8)(aAck.Uint32() >> 8);
+ i[9] = (TUint8)(aAck.Uint32() >> 16);
+ i[8] = (TUint8)(aAck.Uint32() >> 24);
+ }
+ inline void SetHeaderLength(TUint aLength)
+ {
+ // *NOTE* A very low level function, no sanity
+ // checks on value, no rounding up. Value is just
+ // truncated and shifted to the proper position
+ // (all other bits of this byte should always
+ // be zero!)
+ i[12] = (TUint8)((aLength >> 2) <<4);
+ }
+ //
+ // A set method for each individual Control Bit is provided
+ // (It remains to be seen whether this is sensible or not).
+ //
+ inline void SetFIN()
+ {
+ i[13] |= KTcpCtlFIN;
+ }
+ inline void SetSYN()
+ {
+ i[13] |= KTcpCtlSYN;
+ }
+ inline void SetRST()
+ {
+ i[13] |= KTcpCtlRST;
+ }
+ inline void SetPSH()
+ {
+ i[13] |= KTcpCtlPSH;
+ }
+ inline void SetACK()
+ {
+ i[13] |= KTcpCtlACK;
+ }
+ inline void SetURG()
+ {
+ i[13] |= KTcpCtlURG;
+ }
+
+ /// Set ECN Echo flag [RFC 3168].
+ inline void SetECE()
+ {
+ i[13] |= KTcpCtlECE;
+ }
+
+ /// Set ECN Congestion Window Reduced [RFC 3168].
+ inline void SetCWR()
+ {
+ i[13] |= KTcpCtlCWR;
+ }
+
+ //
+ // Note: does not touch the unused control bits at 12th byte!!!
+ //
+ inline void SetControl(TUint8 aFlags)
+ {
+ i[13] = aFlags;
+ }
+ //
+ inline void SetWindow(TUint aWin)
+ {
+ i[15] = (TUint8)aWin;
+ i[14] = (TUint8)(aWin >> 8);
+ }
+ inline void SetChecksum(TUint aSum)
+ {
+ // Checksum is used in network byte order
+ *((TUint16 *)&i[16]) = (TUint16)aSum;
+ }
+ inline void SetUrgent(TUint aOff)
+ {
+ i[19] = (TUint8)aOff;
+ i[18] = (TUint8)(aOff >> 8);
+ }
+ inline TInt SetOptions(TTcpOptions& aOptions)
+ {
+ TInt optLen = aOptions.OutputOptions(i + KTcpMinHeaderLength, KTcpMaxOptionLength);
+ SetHeaderLength(KTcpMinHeaderLength + optLen);
+ return optLen;
+ }
+
+protected:
+ TUint8 i[KTcpMaxHeaderLength];
+ };
+
+/** @} */
+#endif