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.
31 CopyMem (&Value
, Buf
, sizeof (UINT16
));
42 // Data = HTONS (Data);
43 // CopyMem (Buf, &Data, sizeof (UINT16));
52 CopyMem (&Value
, Buf
, sizeof (UINT32
));
63 CopyMem (Buf
, &Data
, sizeof (UINT32
));
68 Compute the window scale value according to the given
71 @param Tcb Pointer to the TCP_CB of this TCP instance.
73 @retval UINT8 The scale value.
84 ASSERT (Tcb
&& Tcb
->Sk
);
86 BufSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
89 while ((Scale
< TCP_OPTION_MAX_WS
) &&
90 ((UINT32
) (TCP_OPTION_MAX_WIN
<< Scale
) < BufSize
)) {
100 Build the TCP option in three-way handshake.
102 @param Tcb Pointer to the TCP_CB of this TCP instance.
103 @param Nbuf Pointer to the buffer to store the options.
105 @return The total length of the TCP option field.
117 ASSERT (Tcb
&& Nbuf
&& !Nbuf
->Tcp
);
122 // Add timestamp option if not disabled by application
123 // and it is the first SYN segment or the peer has sent
126 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
) &&
127 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
128 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_TS
))) {
130 Data
= NetbufAllocSpace (
132 TCP_OPTION_TS_ALIGNED_LEN
,
137 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
139 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
140 TcpPutUint32 (Data
+ 4, mTcpTick
);
141 TcpPutUint32 (Data
+ 8, 0);
145 // Build window scale option, only when are configured
146 // to send WS option, and either we are doing active
147 // open or we have received WS option from peer.
149 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
) &&
150 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
151 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_WS
))) {
153 Data
= NetbufAllocSpace (
155 TCP_OPTION_WS_ALIGNED_LEN
,
161 Len
+= TCP_OPTION_WS_ALIGNED_LEN
;
162 TcpPutUint32 (Data
, TCP_OPTION_WS_FAST
| TcpComputeScale (Tcb
));
168 Data
= NetbufAllocSpace (Nbuf
, TCP_OPTION_MSS_LEN
, 1);
171 Len
+= TCP_OPTION_MSS_LEN
;
172 TcpPutUint32 (Data
, TCP_OPTION_MSS_FAST
| Tcb
->RcvMss
);
179 Build the TCP option in synchronized states.
181 @param Tcb Pointer to the TCP_CB of this TCP instance.
182 @param Nbuf Pointer to the buffer to store the options.
184 @return The total length of the TCP option field.
196 ASSERT (Tcb
&& Nbuf
&& !Nbuf
->Tcp
);
200 // Build Timestamp option
202 if (TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_SND_TS
) &&
203 !TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_RST
)) {
205 Data
= NetbufAllocSpace (
207 TCP_OPTION_TS_ALIGNED_LEN
,
212 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
214 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
215 TcpPutUint32 (Data
+ 4, mTcpTick
);
216 TcpPutUint32 (Data
+ 8, Tcb
->TsRecent
);
224 Parse the supported options.
226 @param Tcp Pointer to the TCP_CB of this TCP instance.
227 @param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
230 @retval 0 The options are successfully pasrsed.
231 @retval -1 Ilegal option was found.
237 IN TCP_OPTION
*Option
246 ASSERT (Tcp
&& Option
);
250 TotalLen
= (UINT8
) ((Tcp
->HeadLen
<< 2) - sizeof (TCP_HEAD
));
255 Head
= (UINT8
*) (Tcp
+ 1);
258 // Fast process of timestamp option
260 if ((TotalLen
== TCP_OPTION_TS_ALIGNED_LEN
) &&
261 (TcpGetUint32 (Head
) == TCP_OPTION_TS_FAST
)) {
263 Option
->TSVal
= TcpGetUint32 (Head
+ 4);
264 Option
->TSEcr
= TcpGetUint32 (Head
+ 8);
265 Option
->Flag
= TCP_OPTION_RCVD_TS
;
271 // Slow path to process the options.
275 while (Cur
< TotalLen
) {
282 if ((Len
!= TCP_OPTION_MSS_LEN
) ||
283 (TotalLen
- Cur
< TCP_OPTION_MSS_LEN
)) {
288 Option
->Mss
= TcpGetUint16 (&Head
[Cur
+ 2]);
289 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_MSS
);
291 Cur
+= TCP_OPTION_MSS_LEN
;
297 if ((Len
!= TCP_OPTION_WS_LEN
) ||
298 (TotalLen
- Cur
< TCP_OPTION_WS_LEN
)) {
303 Option
->WndScale
= (UINT8
) MIN (14, Head
[Cur
+ 2]);
304 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_WS
);
306 Cur
+= TCP_OPTION_WS_LEN
;
312 if ((Len
!= TCP_OPTION_TS_LEN
) ||
313 (TotalLen
- Cur
< TCP_OPTION_TS_LEN
)) {
318 Option
->TSVal
= TcpGetUint32 (&Head
[Cur
+ 2]);
319 Option
->TSEcr
= TcpGetUint32 (&Head
[Cur
+ 6]);
320 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_TS
);
322 Cur
+= TCP_OPTION_TS_LEN
;
336 if (TotalLen
- Cur
< Len
|| Len
< 2) {
340 Cur
= (UINT8
) (Cur
+ Len
);
351 Check the segment against PAWS.
353 @param Tcb Pointer to the TCP_CB of this TCP instance.
354 @param TSVal The timestamp value.
356 @retval 1 The segment passed the PAWS check.
357 @retval 0 The segment failed to pass the PAWS check.
367 // PAWS as defined in RFC1323, buggy...
369 if (TCP_TIME_LT (TSVal
, Tcb
->TsRecent
) &&
370 TCP_TIME_LT (Tcb
->TsRecentAge
+ TCP_PAWS_24DAY
, mTcpTick
)) {