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.
32 NetCopyMem (&Value
, Buf
, sizeof (UINT16
));
43 NetCopyMem (Buf
, &Data
, sizeof (UINT16
));
53 NetCopyMem (&Value
, Buf
, sizeof (UINT32
));
65 NetCopyMem (Buf
, &Data
, sizeof (UINT32
));
70 Compute the window scale value according to the given
73 @param Tcb Pointer to the TCP_CB of this TCP instance.
75 @retval UINT8 The scale value.
86 ASSERT (Tcb
&& Tcb
->Sk
);
88 BufSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
91 while ((Scale
< TCP_OPTION_MAX_WS
) &&
92 ((UINT32
) (TCP_OPTION_MAX_WIN
<< Scale
) < BufSize
)) {
102 Build the TCP option in three-way handshake.
104 @param Tcb Pointer to the TCP_CB of this TCP instance.
105 @param Nbuf Pointer to the buffer to store the options.
107 @return The total length of the TCP option field.
119 ASSERT (Tcb
&& Nbuf
&& !Nbuf
->Tcp
);
124 // Add timestamp option if not disabled by application
125 // and it is the first SYN segment or the peer has sent
128 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
) &&
129 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
130 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_TS
))) {
132 Data
= NetbufAllocSpace (
134 TCP_OPTION_TS_ALIGNED_LEN
,
139 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
141 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
142 TcpPutUint32 (Data
+ 4, mTcpTick
);
143 TcpPutUint32 (Data
+ 8, 0);
147 // Build window scale option, only when are configured
148 // to send WS option, and either we are doing active
149 // open or we have received WS option from peer.
151 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
) &&
152 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
153 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_WS
))) {
155 Data
= NetbufAllocSpace (
157 TCP_OPTION_WS_ALIGNED_LEN
,
163 Len
+= TCP_OPTION_WS_ALIGNED_LEN
;
164 TcpPutUint32 (Data
, TCP_OPTION_WS_FAST
| TcpComputeScale (Tcb
));
170 Data
= NetbufAllocSpace (Nbuf
, TCP_OPTION_MSS_LEN
, 1);
173 Len
+= TCP_OPTION_MSS_LEN
;
174 TcpPutUint32 (Data
, TCP_OPTION_MSS_FAST
| Tcb
->RcvMss
);
181 Build the TCP option in synchronized states.
183 @param Tcb Pointer to the TCP_CB of this TCP instance.
184 @param Nbuf Pointer to the buffer to store the options.
186 @return The total length of the TCP option field.
198 ASSERT (Tcb
&& Nbuf
&& !Nbuf
->Tcp
);
202 // Build Timestamp option
204 if (TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_SND_TS
) &&
205 !TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_RST
)) {
207 Data
= NetbufAllocSpace (
209 TCP_OPTION_TS_ALIGNED_LEN
,
214 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
216 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
217 TcpPutUint32 (Data
+ 4, mTcpTick
);
218 TcpPutUint32 (Data
+ 8, Tcb
->TsRecent
);
226 Parse the supported options.
228 @param Tcp Pointer to the TCP_CB of this TCP instance.
229 @param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
232 @retval 0 The options are successfully pasrsed.
233 @retval -1 Ilegal option was found.
239 IN TCP_OPTION
*Option
248 ASSERT (Tcp
&& Option
);
252 TotalLen
= (UINT8
) ((Tcp
->HeadLen
<< 2) - sizeof (TCP_HEAD
));
257 Head
= (UINT8
*) (Tcp
+ 1);
260 // Fast process of timestamp option
262 if ((TotalLen
== TCP_OPTION_TS_ALIGNED_LEN
) &&
263 (TcpGetUint32 (Head
) == TCP_OPTION_TS_FAST
)) {
265 Option
->TSVal
= TcpGetUint32 (Head
+ 4);
266 Option
->TSEcr
= TcpGetUint32 (Head
+ 8);
267 Option
->Flag
= TCP_OPTION_RCVD_TS
;
273 // Slow path to process the options.
277 while (Cur
< TotalLen
) {
284 if ((Len
!= TCP_OPTION_MSS_LEN
) ||
285 (TotalLen
- Cur
< TCP_OPTION_MSS_LEN
)) {
290 Option
->Mss
= TcpGetUint16 (&Head
[Cur
+ 2]);
291 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_MSS
);
293 Cur
+= TCP_OPTION_MSS_LEN
;
299 if ((Len
!= TCP_OPTION_WS_LEN
) ||
300 (TotalLen
- Cur
< TCP_OPTION_WS_LEN
)) {
305 Option
->WndScale
= (UINT8
) NET_MIN (14, Head
[Cur
+ 2]);
306 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_WS
);
308 Cur
+= TCP_OPTION_WS_LEN
;
314 if ((Len
!= TCP_OPTION_TS_LEN
) ||
315 (TotalLen
- Cur
< TCP_OPTION_TS_LEN
)) {
320 Option
->TSVal
= TcpGetUint32 (&Head
[Cur
+ 2]);
321 Option
->TSEcr
= TcpGetUint32 (&Head
[Cur
+ 6]);
322 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_TS
);
324 Cur
+= TCP_OPTION_TS_LEN
;
338 if (TotalLen
- Cur
< Len
|| Len
< 2) {
342 Cur
= (UINT8
) (Cur
+ Len
);
353 Check the segment against PAWS.
355 @param Tcb Pointer to the TCP_CB of this TCP instance.
356 @param TSVal The timestamp value.
358 @retval 1 The segment passed the PAWS check.
359 @retval 0 The segment failed to pass the PAWS check.
369 // PAWS as defined in RFC1323, buggy...
371 if (TCP_TIME_LT (TSVal
, Tcb
->TsRecent
) &&
372 TCP_TIME_LT (Tcb
->TsRecentAge
+ TCP_PAWS_24DAY
, mTcpTick
)) {