1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // tcp_hdr.h - TCP protocol header structure
15 // Defines the basic classes for accessing the header structures within TCP packets.
22 @ingroup ip_packet_formats
35 * @addtogroup ip_packet_formats
43 // TInet6HeaderTCP declares for maximum length TCP header
44 // (64 bytes). A valid TCP packet can be shorter and failing
45 // to map full 64 bytes from a packet is not an error condition.
48 /** @name TCP Header length constants
51 const TInt KTcpMinHeaderLength = 20;
52 const TInt KTcpMaxHeaderLength = 60;
53 const TInt KTcpMaxOptionLength = 40;
56 /** @name TCP control flags
59 const TUint8 KTcpCtlFIN = 1;
60 const TUint8 KTcpCtlSYN = 2;
61 const TUint8 KTcpCtlRST = 4;
62 const TUint8 KTcpCtlPSH = 8;
63 const TUint8 KTcpCtlACK = 16;
64 const TUint8 KTcpCtlURG = 32;
65 const TUint8 KTcpCtlECE = 0x40;
66 const TUint8 KTcpCtlCWR = 0x80;
72 const TUint8 KTcpOptEnd = 0;
73 const TUint8 KTcpOptNop = 1;
74 const TUint8 KTcpOptMSS = 2;
75 const TUint8 KTcpOptWScale = 3;
76 const TUint8 KTcpOptSackOk = 4;
77 const TUint8 KTcpOptSack = 5;
78 const TUint8 KTcpOptTimeStamps = 8;
79 const TUint8 KTcpOptCount = 9;
81 const TUint8 KTcpOptMinLen[] = {1, 1, 4, 3, 2, 6, 2, 2, 10};
82 const TUint8 KTcpOptMaxLen[] = {1, 1, 4, 3, 2, 36, 40, 40, 10};
83 const TUint32 KTcpOptAlignFlag = 0x00000001;
88 /** TCP Options Header.
94 inline TTcpOptions() { Init(); }
96 IMPORT_C TInt Length() const;
97 inline TBool Error() const { return iError; }
98 inline void ClearError() { iError = EFalse; }
100 inline TInt MSS() const { return iMSS; }
101 inline void SetMSS(TInt aMSS) { iMSS = aMSS; }
102 inline void ClearMSS() { iMSS = -1; }
104 inline TBool TimeStamps() const { return iTimeStamps; }
105 inline TBool TimeStamps(TUint32& aTsVal, TUint32& aTsEcr) const
111 inline void SetTimeStamps(TUint32 aTsVal, TUint32 aTsEcr)
117 inline void ClearTimeStamps() { iTimeStamps = EFalse; }
119 inline TBool SackOk() const { return iSackOk; }
120 inline void SetSackOk() { iSackOk = ETrue; }
121 inline void ClearSackOk() { iSackOk = EFalse; }
122 inline void SuppressSack(TBool aBool=ETrue) { iSuppressSack = aBool; }
123 inline SequenceBlockQueue& SackBlocks() { return iBlocks; }
125 inline TInt Unknown() const { return iUnknown; }
126 inline void ClearUnknown() { iUnknown = 0; }
128 // Query window scale option from TCP header options.
129 // Wscale == 1 means scale factor 1, i.e. shift count of 0 is used in TCP option.
130 // Wscale == 0 means that wscale option is not used in TCP header.
131 inline TUint WindowScale() const { return iWscale; }
133 inline void SetWindowScale(TUint8 aWscale) { iWscale = aWscale; }
136 If set, each option will be aligned to 32-bit longword boundaries with Nop padding.
137 By default the Nop padding is not applied.
139 @param aAlignNop ETrue if option alignment should be applied.
141 inline void SetAlignOpt(TBool aAlignOpt)
144 iFlags |= KTcpOptAlignFlag;
146 iFlags &= ~KTcpOptAlignFlag;
150 friend class TInet6HeaderTCP;
152 IMPORT_C TBool ProcessOptions(const TUint8 *aPtr, TUint aLen);
153 IMPORT_C TUint OutputOptions(TUint8 *aPtr, TUint aMaxLen);
155 void CheckOptAlignment(TUint8* aPtr, TUint& aI, TUint aNumBytes);
157 inline TInt AlignedLength(TInt aLength) const
159 Calculate the actual space requirement for option with given length.
161 Takes optional 32-bit alignment into account.
163 { if (iFlags & KTcpOptAlignFlag) return (aLength + 3) & ~3; else return aLength; }
169 SequenceBlockQueue iBlocks;
174 TUint iWscale; //< Window scale option [RFC 1323].
175 TUint32 iFlags; //< ETrue if options are to be aligned.
180 class TInet6HeaderTCP
181 /** TCP segment header.
186 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
187 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
188 | Source Port | Destination Port |
189 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
191 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192 | Acknowledgment Number |
193 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
194 | Data | |U|A|P|R|S|F| |
195 | Offset| Reserved |R|C|S|S|Y|I| Window |
197 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
198 | Checksum | Urgent Pointer |
199 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
200 | Options | Padding |
201 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
203 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213 inline static TInt MinHeaderLength() {return KTcpMinHeaderLength; }
214 inline static TInt MaxHeaderLength() {return KTcpMaxHeaderLength; }
215 inline TUint8 *EndPtr() {return i + HeaderLength();}
217 // Access, Get TCP field values from the packet
219 inline TUint SrcPort() const
221 return (i[0] << 8) + i[1];
223 inline TUint DstPort() const
225 return (i[2] << 8) + i[3];
227 inline TTcpSeqNum Sequence() const
229 return (i[4] << 24) | (i[5] << 16) | (i[6] << 8) | i[7];
231 inline TTcpSeqNum Acknowledgment() const
233 return (i[8] << 24) | (i[9] << 16) | (i[10] << 8) | i[11];
235 inline TInt HeaderLength() const
237 // Return TCP Header Length in bytes (including options and padding)
238 return (i[12] >> 2) & (0xF << 2);
241 // A testing method for each individual Control Bit is provided
242 // (It remains to be seen whether this is useful or not). Note
243 // also that the result of the AND is returned, not 0 and 1.
245 inline TInt FIN() const
247 return i[13] & KTcpCtlFIN;
249 inline TInt SYN() const
251 return i[13] & KTcpCtlSYN;
253 inline TInt RST() const
255 return i[13] & KTcpCtlRST;
257 inline TInt PSH() const
259 return i[13] & KTcpCtlPSH;
261 inline TInt ACK() const
263 return i[13] & KTcpCtlACK;
265 inline TInt URG() const
267 return i[13] & KTcpCtlURG;
270 // ECN Echo flag [RFC 3168].
271 inline TInt ECE() const
273 return i[13] & KTcpCtlECE;
276 // ECN: Congestion Window Reduced [RFC 3168].
277 inline TInt CWR() const
279 return i[13] & KTcpCtlCWR;
282 // A method to access all of the above as is. Note that this
283 // also returns the reserved unspecified bits. Value can be
284 // non-zero, even if none of the above is set. However, it only
285 // returns unspecified bits from the 13th byte, not any from 12th!
286 inline TUint8 Control() const
291 inline TUint Window() const
293 return (i[14] << 8) + i[15];
295 inline TUint Checksum() const
297 // Checksum is used in network byte order
298 return *((TUint16 *)&i[16]);
300 inline TUint Urgent() const
302 return (i[18] << 8) + i[19];
304 inline TBool Options(TTcpOptions& aOptions) const
306 return aOptions.ProcessOptions(i + KTcpMinHeaderLength, HeaderLength() - KTcpMinHeaderLength);
308 //Backwards compatibility, mainly for IPRotor.
309 inline TPtr8 Options() const
311 TInt len = HeaderLength() - 20;
312 return TPtr8((TUint8 *)&i[20], len, len);
316 // Build, Set TCP field value to the packet
318 inline void SetSrcPort(TUint aPort)
320 i[0] = (TUint8)(aPort >> 8);
321 i[1] = (TUint8)aPort;
323 inline void SetDstPort(TUint aPort)
325 i[2] = (TUint8)(aPort >> 8);
326 i[3] = (TUint8)aPort;
328 inline void SetSequence(TTcpSeqNum aSeq)
330 i[7] = (TUint8)aSeq.Uint32();
331 i[6] = (TUint8)(aSeq.Uint32() >> 8);
332 i[5] = (TUint8)(aSeq.Uint32() >> 16);
333 i[4] = (TUint8)(aSeq.Uint32() >> 24);
335 inline void SetAcknowledgment(TTcpSeqNum aAck)
337 i[11] = (TUint8)aAck.Uint32();
338 i[10] = (TUint8)(aAck.Uint32() >> 8);
339 i[9] = (TUint8)(aAck.Uint32() >> 16);
340 i[8] = (TUint8)(aAck.Uint32() >> 24);
342 inline void SetHeaderLength(TUint aLength)
344 // *NOTE* A very low level function, no sanity
345 // checks on value, no rounding up. Value is just
346 // truncated and shifted to the proper position
347 // (all other bits of this byte should always
349 i[12] = (TUint8)((aLength >> 2) <<4);
352 // A set method for each individual Control Bit is provided
353 // (It remains to be seen whether this is sensible or not).
380 // Set ECN Echo flag [RFC 3168].
386 // Set ECN Congestion Window Reduced [RFC 3168].
393 // Note: does not touch the unused control bits at 12th byte!!!
395 inline void SetControl(TUint8 aFlags)
400 inline void SetWindow(TUint aWin)
402 i[15] = (TUint8)aWin;
403 i[14] = (TUint8)(aWin >> 8);
405 inline void SetChecksum(TUint aSum)
407 // Checksum is used in network byte order
408 *((TUint16 *)&i[16]) = (TUint16)aSum;
410 inline void SetUrgent(TUint aOff)
412 i[19] = (TUint8)aOff;
413 i[18] = (TUint8)(aOff >> 8);
415 inline TInt SetOptions(TTcpOptions& aOptions)
417 TInt optLen = aOptions.OutputOptions(i + KTcpMinHeaderLength, KTcpMaxOptionLength);
418 SetHeaderLength(KTcpMinHeaderLength + optLen);
423 TUint8 i[KTcpMaxHeaderLength];