diff -r 666f914201fb -r 2fe1408b6811 epoc32/include/tcp_hdr.h --- /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 +#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