3 Copyright (c) 2005 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Routines to process TCP option.
26 Get a UINT16 value from buffer.
28 @param Buf Pointer to input buffer.
30 @return The UINT16 value get from buffer.
39 CopyMem (&Value
, Buf
, sizeof (UINT16
));
44 Get a UINT32 value from buffer.
46 @param Buf Pointer to input buffer.
48 @return The UINT32 value get from buffer.
57 CopyMem (&Value
, Buf
, sizeof (UINT32
));
62 Put a UINT32 value in buffer.
64 @param Buf Pointer to the buffer.
65 @param Data The UINT32 Date to put in buffer
75 CopyMem (Buf
, &Data
, sizeof (UINT32
));
80 Compute the window scale value according to the given buffer size.
82 @param Tcb Pointer to the TCP_CB of this TCP instance.
84 @return The scale value.
95 ASSERT ((Tcb
!= NULL
) && (Tcb
->Sk
!= NULL
));
97 BufSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
100 while ((Scale
< TCP_OPTION_MAX_WS
) &&
101 ((UINT32
) (TCP_OPTION_MAX_WIN
<< Scale
) < BufSize
)) {
111 Build the TCP option in three-way handshake.
113 @param Tcb Pointer to the TCP_CB of this TCP instance.
114 @param Nbuf Pointer to the buffer to store the options.
116 @return The total length of the TCP option field.
128 ASSERT ((Tcb
!= NULL
) && (Nbuf
!= NULL
) && (Nbuf
->Tcp
== NULL
));
133 // Add timestamp option if not disabled by application
134 // and it is the first SYN segment or the peer has sent
137 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
) &&
138 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
139 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_TS
))) {
141 Data
= NetbufAllocSpace (
143 TCP_OPTION_TS_ALIGNED_LEN
,
147 ASSERT (Data
!= NULL
);
148 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
150 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
151 TcpPutUint32 (Data
+ 4, mTcpTick
);
152 TcpPutUint32 (Data
+ 8, 0);
156 // Build window scale option, only when are configured
157 // to send WS option, and either we are doing active
158 // open or we have received WS option from peer.
160 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
) &&
161 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
162 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_WS
))) {
164 Data
= NetbufAllocSpace (
166 TCP_OPTION_WS_ALIGNED_LEN
,
170 ASSERT (Data
!= NULL
);
172 Len
+= TCP_OPTION_WS_ALIGNED_LEN
;
173 TcpPutUint32 (Data
, TCP_OPTION_WS_FAST
| TcpComputeScale (Tcb
));
179 Data
= NetbufAllocSpace (Nbuf
, TCP_OPTION_MSS_LEN
, 1);
180 ASSERT (Data
!= NULL
);
182 Len
+= TCP_OPTION_MSS_LEN
;
183 TcpPutUint32 (Data
, TCP_OPTION_MSS_FAST
| Tcb
->RcvMss
);
190 Build the TCP option in synchronized states.
192 @param Tcb Pointer to the TCP_CB of this TCP instance.
193 @param Nbuf Pointer to the buffer to store the options.
195 @return The total length of the TCP option field.
207 ASSERT ((Tcb
!= NULL
) && (Nbuf
!= NULL
) && (Nbuf
->Tcp
== NULL
));
211 // Build Timestamp option
213 if (TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_SND_TS
) &&
214 !TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_RST
)) {
216 Data
= NetbufAllocSpace (
218 TCP_OPTION_TS_ALIGNED_LEN
,
222 ASSERT (Data
!= NULL
);
223 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
225 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
226 TcpPutUint32 (Data
+ 4, mTcpTick
);
227 TcpPutUint32 (Data
+ 8, Tcb
->TsRecent
);
235 Parse the supported options.
237 @param Tcp Pointer to the TCP_CB of this TCP instance.
238 @param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
241 @retval 0 The options are successfully pasrsed.
242 @retval -1 Ilegal option was found.
248 IN TCP_OPTION
*Option
257 ASSERT ((Tcp
!= NULL
) && (Option
!= NULL
));
261 TotalLen
= (UINT8
) ((Tcp
->HeadLen
<< 2) - sizeof (TCP_HEAD
));
266 Head
= (UINT8
*) (Tcp
+ 1);
269 // Fast process of timestamp option
271 if ((TotalLen
== TCP_OPTION_TS_ALIGNED_LEN
) &&
272 (TcpGetUint32 (Head
) == TCP_OPTION_TS_FAST
)) {
274 Option
->TSVal
= TcpGetUint32 (Head
+ 4);
275 Option
->TSEcr
= TcpGetUint32 (Head
+ 8);
276 Option
->Flag
= TCP_OPTION_RCVD_TS
;
282 // Slow path to process the options.
286 while (Cur
< TotalLen
) {
293 if ((Len
!= TCP_OPTION_MSS_LEN
) ||
294 (TotalLen
- Cur
< TCP_OPTION_MSS_LEN
)) {
299 Option
->Mss
= TcpGetUint16 (&Head
[Cur
+ 2]);
300 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_MSS
);
302 Cur
+= TCP_OPTION_MSS_LEN
;
308 if ((Len
!= TCP_OPTION_WS_LEN
) ||
309 (TotalLen
- Cur
< TCP_OPTION_WS_LEN
)) {
314 Option
->WndScale
= (UINT8
) MIN (14, Head
[Cur
+ 2]);
315 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_WS
);
317 Cur
+= TCP_OPTION_WS_LEN
;
323 if ((Len
!= TCP_OPTION_TS_LEN
) ||
324 (TotalLen
- Cur
< TCP_OPTION_TS_LEN
)) {
329 Option
->TSVal
= TcpGetUint32 (&Head
[Cur
+ 2]);
330 Option
->TSEcr
= TcpGetUint32 (&Head
[Cur
+ 6]);
331 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_TS
);
333 Cur
+= TCP_OPTION_TS_LEN
;
347 if ((TotalLen
- Cur
) < Len
|| Len
< 2) {
351 Cur
= (UINT8
) (Cur
+ Len
);
362 Check the segment against PAWS.
364 @param Tcb Pointer to the TCP_CB of this TCP instance.
365 @param TSVal The timestamp value.
367 @retval 1 The segment passed the PAWS check.
368 @retval 0 The segment failed to pass the PAWS check.
378 // PAWS as defined in RFC1323, buggy...
380 if (TCP_TIME_LT (TSVal
, Tcb
->TsRecent
) &&
381 TCP_TIME_LT (Tcb
->TsRecentAge
+ TCP_PAWS_24DAY
, mTcpTick
)) {