1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/tcp_hdr.h Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,427 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// 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
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// tcp_hdr.h - TCP protocol header structure
1.18 +// Defines the basic classes for accessing the header structures within TCP packets.
1.19 +//
1.20 +
1.21 +
1.22 +
1.23 +/**
1.24 + @file tcp_hdr.h
1.25 + @ingroup ip_packet_formats
1.26 + @publishedAll
1.27 + @released
1.28 +*/
1.29 +
1.30 +#ifndef __TCP_HDR_H__
1.31 +#define __TCP_HDR_H__
1.32 +
1.33 +#include <e32std.h>
1.34 +#include "in_hdr.h"
1.35 +#include "sbque.h"
1.36 +
1.37 +/**
1.38 +* @addtogroup ip_packet_formats
1.39 +* @{
1.40 +*/
1.41 +
1.42 +//
1.43 +// TInet6HeaderTCP
1.44 +//
1.45 +// *NOTE*
1.46 +// TInet6HeaderTCP declares for maximum length TCP header
1.47 +// (64 bytes). A valid TCP packet can be shorter and failing
1.48 +// to map full 64 bytes from a packet is not an error condition.
1.49 +//
1.50 +
1.51 +/** @name TCP Header length constants
1.52 +* @{
1.53 +*/
1.54 +const TInt KTcpMinHeaderLength = 20;
1.55 +const TInt KTcpMaxHeaderLength = 60;
1.56 +const TInt KTcpMaxOptionLength = 40;
1.57 +/** @} */
1.58 +
1.59 +/** @name TCP control flags
1.60 +* @{
1.61 +*/
1.62 +const TUint8 KTcpCtlFIN = 1;
1.63 +const TUint8 KTcpCtlSYN = 2;
1.64 +const TUint8 KTcpCtlRST = 4;
1.65 +const TUint8 KTcpCtlPSH = 8;
1.66 +const TUint8 KTcpCtlACK = 16;
1.67 +const TUint8 KTcpCtlURG = 32;
1.68 +const TUint8 KTcpCtlECE = 0x40;
1.69 +const TUint8 KTcpCtlCWR = 0x80;
1.70 +/** @} */
1.71 +
1.72 +/** @name TCP options
1.73 +* @{
1.74 +*/
1.75 +const TUint8 KTcpOptEnd = 0;
1.76 +const TUint8 KTcpOptNop = 1;
1.77 +const TUint8 KTcpOptMSS = 2;
1.78 +const TUint8 KTcpOptWScale = 3;
1.79 +const TUint8 KTcpOptSackOk = 4;
1.80 +const TUint8 KTcpOptSack = 5;
1.81 +const TUint8 KTcpOptTimeStamps = 8;
1.82 +const TUint8 KTcpOptCount = 9;
1.83 +
1.84 +const TUint8 KTcpOptMinLen[] = {1, 1, 4, 3, 2, 6, 2, 2, 10};
1.85 +const TUint8 KTcpOptMaxLen[] = {1, 1, 4, 3, 2, 36, 40, 40, 10};
1.86 +const TUint32 KTcpOptAlignFlag = 0x00000001;
1.87 +/** @} */
1.88 +
1.89 +
1.90 +class TTcpOptions
1.91 +/** TCP Options Header.
1.92 +@publishedAll
1.93 +@released
1.94 +*/
1.95 + {
1.96 +public:
1.97 + inline TTcpOptions() { Init(); }
1.98 + IMPORT_C void Init();
1.99 + IMPORT_C TInt Length() const;
1.100 + inline TBool Error() const { return iError; }
1.101 + inline void ClearError() { iError = EFalse; }
1.102 +
1.103 + inline TInt MSS() const { return iMSS; }
1.104 + inline void SetMSS(TInt aMSS) { iMSS = aMSS; }
1.105 + inline void ClearMSS() { iMSS = -1; }
1.106 +
1.107 + inline TBool TimeStamps() const { return iTimeStamps; }
1.108 + inline TBool TimeStamps(TUint32& aTsVal, TUint32& aTsEcr) const
1.109 + {
1.110 + aTsVal = iTsVal;
1.111 + aTsEcr = iTsEcr;
1.112 + return iTimeStamps;
1.113 + }
1.114 + inline void SetTimeStamps(TUint32 aTsVal, TUint32 aTsEcr)
1.115 + {
1.116 + iTsVal = aTsVal;
1.117 + iTsEcr = aTsEcr;
1.118 + iTimeStamps = ETrue;
1.119 + }
1.120 + inline void ClearTimeStamps() { iTimeStamps = EFalse; }
1.121 +
1.122 + inline TBool SackOk() const { return iSackOk; }
1.123 + inline void SetSackOk() { iSackOk = ETrue; }
1.124 + inline void ClearSackOk() { iSackOk = EFalse; }
1.125 + inline void SuppressSack(TBool aBool=ETrue) { iSuppressSack = aBool; }
1.126 + inline SequenceBlockQueue& SackBlocks() { return iBlocks; }
1.127 +
1.128 + inline TInt Unknown() const { return iUnknown; }
1.129 + inline void ClearUnknown() { iUnknown = 0; }
1.130 +
1.131 + /// Query window scale option from TCP header options.
1.132 + /// Wscale == 1 means scale factor 1, i.e. shift count of 0 is used in TCP option.
1.133 + /// Wscale == 0 means that wscale option is not used in TCP header.
1.134 + inline TUint WindowScale() const { return iWscale; }
1.135 +
1.136 + inline void SetWindowScale(TUint8 aWscale) { iWscale = aWscale; }
1.137 +
1.138 + /**
1.139 + If set, each option will be aligned to 32-bit longword boundaries with Nop padding.
1.140 + By default the Nop padding is not applied.
1.141 +
1.142 + @param aAlignNop ETrue if option alignment should be applied.
1.143 + */
1.144 + inline void SetAlignOpt(TBool aAlignOpt)
1.145 + {
1.146 + if(aAlignOpt)
1.147 + iFlags |= KTcpOptAlignFlag;
1.148 + else
1.149 + iFlags &= ~KTcpOptAlignFlag;
1.150 + }
1.151 +
1.152 +private:
1.153 + friend class TInet6HeaderTCP;
1.154 +
1.155 + IMPORT_C TBool ProcessOptions(const TUint8 *aPtr, TUint aLen);
1.156 + IMPORT_C TUint OutputOptions(TUint8 *aPtr, TUint aMaxLen);
1.157 +
1.158 + void CheckOptAlignment(TUint8* aPtr, TUint& aI, TUint aNumBytes);
1.159 +
1.160 + inline TInt AlignedLength(TInt aLength) const
1.161 + /**
1.162 + Calculate the actual space requirement for option with given length.
1.163 +
1.164 + Takes optional 32-bit alignment into account.
1.165 + */
1.166 + { if (iFlags & KTcpOptAlignFlag) return (aLength + 3) & ~3; else return aLength; }
1.167 +
1.168 + TInt iMSS;
1.169 + TInt iUnknown;
1.170 + TUint32 iTsVal;
1.171 + TUint32 iTsEcr;
1.172 + SequenceBlockQueue iBlocks;
1.173 + TBool iError;
1.174 + TBool iTimeStamps;
1.175 + TBool iSackOk;
1.176 + TBool iSuppressSack;
1.177 + TUint iWscale; ///< Window scale option [RFC 1323].
1.178 + TUint32 iFlags; ///< ETrue if options are to be aligned.
1.179 + };
1.180 +
1.181 +
1.182 +
1.183 +class TInet6HeaderTCP
1.184 +/** TCP segment header.
1.185 +@verbatim
1.186 +Extract from RFC-793
1.187 +
1.188 + 0 1 2 3
1.189 + 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
1.190 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.191 + | Source Port | Destination Port |
1.192 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.193 + | Sequence Number |
1.194 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.195 + | Acknowledgment Number |
1.196 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.197 + | Data | |U|A|P|R|S|F| |
1.198 + | Offset| Reserved |R|C|S|S|Y|I| Window |
1.199 + | | |G|K|H|T|N|N| |
1.200 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.201 + | Checksum | Urgent Pointer |
1.202 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.203 + | Options | Padding |
1.204 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.205 + | data |
1.206 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.207 +@endverbatim
1.208 +@publishedAll
1.209 +@released
1.210 +*/
1.211 + {
1.212 +public:
1.213 + //
1.214 + // Basic
1.215 + //
1.216 + inline static TInt MinHeaderLength() {return KTcpMinHeaderLength; }
1.217 + inline static TInt MaxHeaderLength() {return KTcpMaxHeaderLength; }
1.218 + inline TUint8 *EndPtr() {return i + HeaderLength();}
1.219 + //
1.220 + // Access, Get TCP field values from the packet
1.221 + //
1.222 + inline TUint SrcPort() const
1.223 + {
1.224 + return (i[0] << 8) + i[1];
1.225 + }
1.226 + inline TUint DstPort() const
1.227 + {
1.228 + return (i[2] << 8) + i[3];
1.229 + }
1.230 + inline TTcpSeqNum Sequence() const
1.231 + {
1.232 + return (i[4] << 24) | (i[5] << 16) | (i[6] << 8) | i[7];
1.233 + }
1.234 + inline TTcpSeqNum Acknowledgment() const
1.235 + {
1.236 + return (i[8] << 24) | (i[9] << 16) | (i[10] << 8) | i[11];
1.237 + }
1.238 + inline TInt HeaderLength() const
1.239 + {
1.240 + // Return TCP Header Length in bytes (including options and padding)
1.241 + return (i[12] >> 2) & (0xF << 2);
1.242 + }
1.243 + //
1.244 + // A testing method for each individual Control Bit is provided
1.245 + // (It remains to be seen whether this is useful or not). Note
1.246 + // also that the result of the AND is returned, not 0 and 1.
1.247 + //
1.248 + inline TInt FIN() const
1.249 + {
1.250 + return i[13] & KTcpCtlFIN;
1.251 + }
1.252 + inline TInt SYN() const
1.253 + {
1.254 + return i[13] & KTcpCtlSYN;
1.255 + }
1.256 + inline TInt RST() const
1.257 + {
1.258 + return i[13] & KTcpCtlRST;
1.259 + }
1.260 + inline TInt PSH() const
1.261 + {
1.262 + return i[13] & KTcpCtlPSH;
1.263 + }
1.264 + inline TInt ACK() const
1.265 + {
1.266 + return i[13] & KTcpCtlACK;
1.267 + }
1.268 + inline TInt URG() const
1.269 + {
1.270 + return i[13] & KTcpCtlURG;
1.271 + }
1.272 +
1.273 + /// ECN Echo flag [RFC 3168].
1.274 + inline TInt ECE() const
1.275 + {
1.276 + return i[13] & KTcpCtlECE;
1.277 + }
1.278 +
1.279 + /// ECN: Congestion Window Reduced [RFC 3168].
1.280 + inline TInt CWR() const
1.281 + {
1.282 + return i[13] & KTcpCtlCWR;
1.283 + }
1.284 +
1.285 + // A method to access all of the above as is. Note that this
1.286 + // also returns the reserved unspecified bits. Value can be
1.287 + // non-zero, even if none of the above is set. However, it only
1.288 + // returns unspecified bits from the 13th byte, not any from 12th!
1.289 + inline TUint8 Control() const
1.290 + {
1.291 + return i[13];
1.292 + }
1.293 + //
1.294 + inline TUint Window() const
1.295 + {
1.296 + return (i[14] << 8) + i[15];
1.297 + }
1.298 + inline TUint Checksum() const
1.299 + {
1.300 + // Checksum is used in network byte order
1.301 + return *((TUint16 *)&i[16]);
1.302 + }
1.303 + inline TUint Urgent() const
1.304 + {
1.305 + return (i[18] << 8) + i[19];
1.306 + }
1.307 + inline TBool Options(TTcpOptions& aOptions) const
1.308 + {
1.309 + return aOptions.ProcessOptions(i + KTcpMinHeaderLength, HeaderLength() - KTcpMinHeaderLength);
1.310 + }
1.311 + //Backwards compatibility, mainly for IPRotor.
1.312 + inline TPtr8 Options() const
1.313 + {
1.314 + TInt len = HeaderLength() - 20;
1.315 + return TPtr8((TUint8 *)&i[20], len, len);
1.316 + }
1.317 +
1.318 + //
1.319 + // Build, Set TCP field value to the packet
1.320 + //
1.321 + inline void SetSrcPort(TUint aPort)
1.322 + {
1.323 + i[0] = (TUint8)(aPort >> 8);
1.324 + i[1] = (TUint8)aPort;
1.325 + }
1.326 + inline void SetDstPort(TUint aPort)
1.327 + {
1.328 + i[2] = (TUint8)(aPort >> 8);
1.329 + i[3] = (TUint8)aPort;
1.330 + }
1.331 + inline void SetSequence(TTcpSeqNum aSeq)
1.332 + {
1.333 + i[7] = (TUint8)aSeq.Uint32();
1.334 + i[6] = (TUint8)(aSeq.Uint32() >> 8);
1.335 + i[5] = (TUint8)(aSeq.Uint32() >> 16);
1.336 + i[4] = (TUint8)(aSeq.Uint32() >> 24);
1.337 + }
1.338 + inline void SetAcknowledgment(TTcpSeqNum aAck)
1.339 + {
1.340 + i[11] = (TUint8)aAck.Uint32();
1.341 + i[10] = (TUint8)(aAck.Uint32() >> 8);
1.342 + i[9] = (TUint8)(aAck.Uint32() >> 16);
1.343 + i[8] = (TUint8)(aAck.Uint32() >> 24);
1.344 + }
1.345 + inline void SetHeaderLength(TUint aLength)
1.346 + {
1.347 + // *NOTE* A very low level function, no sanity
1.348 + // checks on value, no rounding up. Value is just
1.349 + // truncated and shifted to the proper position
1.350 + // (all other bits of this byte should always
1.351 + // be zero!)
1.352 + i[12] = (TUint8)((aLength >> 2) <<4);
1.353 + }
1.354 + //
1.355 + // A set method for each individual Control Bit is provided
1.356 + // (It remains to be seen whether this is sensible or not).
1.357 + //
1.358 + inline void SetFIN()
1.359 + {
1.360 + i[13] |= KTcpCtlFIN;
1.361 + }
1.362 + inline void SetSYN()
1.363 + {
1.364 + i[13] |= KTcpCtlSYN;
1.365 + }
1.366 + inline void SetRST()
1.367 + {
1.368 + i[13] |= KTcpCtlRST;
1.369 + }
1.370 + inline void SetPSH()
1.371 + {
1.372 + i[13] |= KTcpCtlPSH;
1.373 + }
1.374 + inline void SetACK()
1.375 + {
1.376 + i[13] |= KTcpCtlACK;
1.377 + }
1.378 + inline void SetURG()
1.379 + {
1.380 + i[13] |= KTcpCtlURG;
1.381 + }
1.382 +
1.383 + /// Set ECN Echo flag [RFC 3168].
1.384 + inline void SetECE()
1.385 + {
1.386 + i[13] |= KTcpCtlECE;
1.387 + }
1.388 +
1.389 + /// Set ECN Congestion Window Reduced [RFC 3168].
1.390 + inline void SetCWR()
1.391 + {
1.392 + i[13] |= KTcpCtlCWR;
1.393 + }
1.394 +
1.395 + //
1.396 + // Note: does not touch the unused control bits at 12th byte!!!
1.397 + //
1.398 + inline void SetControl(TUint8 aFlags)
1.399 + {
1.400 + i[13] = aFlags;
1.401 + }
1.402 + //
1.403 + inline void SetWindow(TUint aWin)
1.404 + {
1.405 + i[15] = (TUint8)aWin;
1.406 + i[14] = (TUint8)(aWin >> 8);
1.407 + }
1.408 + inline void SetChecksum(TUint aSum)
1.409 + {
1.410 + // Checksum is used in network byte order
1.411 + *((TUint16 *)&i[16]) = (TUint16)aSum;
1.412 + }
1.413 + inline void SetUrgent(TUint aOff)
1.414 + {
1.415 + i[19] = (TUint8)aOff;
1.416 + i[18] = (TUint8)(aOff >> 8);
1.417 + }
1.418 + inline TInt SetOptions(TTcpOptions& aOptions)
1.419 + {
1.420 + TInt optLen = aOptions.OutputOptions(i + KTcpMinHeaderLength, KTcpMaxOptionLength);
1.421 + SetHeaderLength(KTcpMinHeaderLength + optLen);
1.422 + return optLen;
1.423 + }
1.424 +
1.425 +protected:
1.426 + TUint8 i[KTcpMaxHeaderLength];
1.427 + };
1.428 +
1.429 +/** @} */
1.430 +#endif