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
));
44 NetCopyMem (Buf
, &Data
, sizeof (UINT16
));
54 NetCopyMem (&Value
, Buf
, sizeof (UINT32
));
66 NetCopyMem (Buf
, &Data
, sizeof (UINT32
));
71 Compute the window scale value according to the given
74 @param Tcb Pointer to the TCP_CB of this TCP instance.
76 @retval UINT8 The scale value.
87 ASSERT (Tcb
&& Tcb
->Sk
);
89 BufSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
92 while ((Scale
< TCP_OPTION_MAX_WS
) &&
93 ((UINT32
) (TCP_OPTION_MAX_WIN
<< Scale
) < BufSize
)) {
103 Build the TCP option in three-way handshake.
105 @param Tcb Pointer to the TCP_CB of this TCP instance.
106 @param Nbuf Pointer to the buffer to store the options.
108 @return The total length of the TCP option field.
120 ASSERT (Tcb
&& Nbuf
&& !Nbuf
->Tcp
);
125 // Add timestamp option if not disabled by application
126 // and it is the first SYN segment or the peer has sent
129 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
) &&
130 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
131 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_TS
))) {
133 Data
= NetbufAllocSpace (
135 TCP_OPTION_TS_ALIGNED_LEN
,
140 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
142 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
143 TcpPutUint32 (Data
+ 4, mTcpTick
);
144 TcpPutUint32 (Data
+ 8, 0);
148 // Build window scale option, only when are configured
149 // to send WS option, and either we are doing active
150 // open or we have received WS option from peer.
152 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
) &&
153 (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_ACK
) ||
154 TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RCVD_WS
))) {
156 Data
= NetbufAllocSpace (
158 TCP_OPTION_WS_ALIGNED_LEN
,
164 Len
+= TCP_OPTION_WS_ALIGNED_LEN
;
165 TcpPutUint32 (Data
, TCP_OPTION_WS_FAST
| TcpComputeScale (Tcb
));
171 Data
= NetbufAllocSpace (Nbuf
, TCP_OPTION_MSS_LEN
, 1);
174 Len
+= TCP_OPTION_MSS_LEN
;
175 TcpPutUint32 (Data
, TCP_OPTION_MSS_FAST
| Tcb
->RcvMss
);
182 Build the TCP option in synchronized states.
184 @param Tcb Pointer to the TCP_CB of this TCP instance.
185 @param Nbuf Pointer to the buffer to store the options.
187 @return The total length of the TCP option field.
199 ASSERT (Tcb
&& Nbuf
&& !Nbuf
->Tcp
);
203 // Build Timestamp option
205 if (TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_SND_TS
) &&
206 !TCP_FLG_ON (TCPSEG_NETBUF (Nbuf
)->Flag
, TCP_FLG_RST
)) {
208 Data
= NetbufAllocSpace (
210 TCP_OPTION_TS_ALIGNED_LEN
,
215 Len
+= TCP_OPTION_TS_ALIGNED_LEN
;
217 TcpPutUint32 (Data
, TCP_OPTION_TS_FAST
);
218 TcpPutUint32 (Data
+ 4, mTcpTick
);
219 TcpPutUint32 (Data
+ 8, Tcb
->TsRecent
);
227 Parse the supported options.
229 @param Tcp Pointer to the TCP_CB of this TCP instance.
230 @param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
233 @retval 0 The options are successfully pasrsed.
234 @retval -1 Ilegal option was found.
240 IN TCP_OPTION
*Option
249 ASSERT (Tcp
&& Option
);
253 TotalLen
= (Tcp
->HeadLen
<< 2) - sizeof (TCP_HEAD
);
258 Head
= (UINT8
*) (Tcp
+ 1);
261 // Fast process of timestamp option
263 if ((TotalLen
== TCP_OPTION_TS_ALIGNED_LEN
) &&
264 (TcpGetUint32 (Head
) == TCP_OPTION_TS_FAST
)) {
266 Option
->TSVal
= TcpGetUint32 (Head
+ 4);
267 Option
->TSEcr
= TcpGetUint32 (Head
+ 8);
268 Option
->Flag
= TCP_OPTION_RCVD_TS
;
274 // Slow path to process the options.
278 while (Cur
< TotalLen
) {
285 if ((Len
!= TCP_OPTION_MSS_LEN
) ||
286 (TotalLen
- Cur
< TCP_OPTION_MSS_LEN
)) {
291 Option
->Mss
= TcpGetUint16 (&Head
[Cur
+ 2]);
292 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_MSS
);
294 Cur
+= TCP_OPTION_MSS_LEN
;
300 if ((Len
!= TCP_OPTION_WS_LEN
) ||
301 (TotalLen
- Cur
< TCP_OPTION_WS_LEN
)) {
306 Option
->WndScale
= (UINT8
) NET_MIN (14, Head
[Cur
+ 2]);
307 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_WS
);
309 Cur
+= TCP_OPTION_WS_LEN
;
315 if ((Len
!= TCP_OPTION_TS_LEN
) ||
316 (TotalLen
- Cur
< TCP_OPTION_TS_LEN
)) {
321 Option
->TSVal
= TcpGetUint32 (&Head
[Cur
+ 2]);
322 Option
->TSEcr
= TcpGetUint32 (&Head
[Cur
+ 6]);
323 TCP_SET_FLG (Option
->Flag
, TCP_OPTION_RCVD_TS
);
325 Cur
+= TCP_OPTION_TS_LEN
;
339 if (TotalLen
- Cur
< Len
|| Len
< 2) {
343 Cur
= (UINT8
) (Cur
+ Len
);
354 Check the segment against PAWS.
356 @param Tcb Pointer to the TCP_CB of this TCP instance.
357 @param TSVal The timestamp value.
359 @retval 1 The segment passed the PAWS check.
360 @retval 0 The segment failed to pass the PAWS check.
370 // PAWS as defined in RFC1323, buggy...
372 if (TCP_TIME_LT (TSVal
, Tcb
->TsRecent
) &&
373 TCP_TIME_LT (Tcb
->TsRecentAge
+ TCP_PAWS_24DAY
, mTcpTick
)) {