1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Transmission Control Protocol (TCP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "nx_tcp.h"
29
30 #ifdef NX_ENABLE_TCP_WINDOW_SCALING
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _nx_tcp_window_scaling_option_get PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Yuxin Zhou, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This internal function searches for the Window Scale option. */
45 /* If found, first check the option length, if option length is not */
46 /* valid, it returns NX_FALSE to the caller, else it set the window */
47 /* scale size and returns NX_TRUE to the caller. Otherwise, */
48 /* NX_TRUE is returned. */
49 /* */
50 /* INPUT */
51 /* */
52 /* option_ptr Pointer to option area */
53 /* option_area_size Size of option area */
54 /* window_scale window scale size */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* NX_FALSE TCP option is invalid */
59 /* NX_TRUE TCP option is valid */
60 /* */
61 /* CALLS */
62 /* */
63 /* None */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* _nx_tcp_packet_process TCP packet processing */
68 /* _nx_tcp_server_socket_relisten Socket relisten processing */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
75 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_nx_tcp_window_scaling_option_get(UCHAR * option_ptr,ULONG option_area_size,ULONG * window_scale)79 UINT _nx_tcp_window_scaling_option_get(UCHAR *option_ptr, ULONG option_area_size, ULONG *window_scale)
80 {
81
82 ULONG option_length;
83
84
85 /* Set invalid window scaling, in case the SYN message does not contain Window Scaling feature. */
86 *window_scale = 0xFF;
87
88 /* Loop through the option area looking for the window scaling option. */
89 while (option_area_size >= 3)
90 {
91
92 /* Is the current character the window scaling type? */
93 if (*option_ptr == NX_TCP_RWIN_KIND)
94 {
95
96 /* Yes, we found it! */
97
98 /* Move the pointer forward by one. */
99 option_ptr++;
100
101 /* Check the option length, if option length is not equal to 3, return NX_FALSE. */
102 if (*option_ptr++ != 3)
103 {
104 return(NX_FALSE);
105 }
106
107 /* Get the window scale size. */
108 *window_scale = (ULONG)*option_ptr;
109
110 if (*window_scale > 14)
111 {
112
113 /* Make sure window scale is limited to 14, per RFC 1323 pp.11 */
114 *window_scale = 14;
115 }
116
117 break;
118 }
119
120 /* Otherwise, process relative to the option type. */
121
122 /* Check for end of list. */
123 if (*option_ptr == NX_TCP_EOL_KIND)
124 {
125
126 /* Yes, end of list, get out! */
127 break;
128 }
129
130 /* Check for NOP. */
131 if (*option_ptr == NX_TCP_NOP_KIND)
132 {
133 /* One character option! Skip this option and move to the next entry. */
134 option_ptr++;
135
136 option_area_size--;
137 }
138 else
139 {
140
141 /* Derive the option length. All options *fields* area 32-bits,
142 but the options themselves may be padded by NOP's. Determine
143 the option size based on alignment of the option ptr */
144 option_length = *(option_ptr + 1);
145
146 if (option_length == 0)
147 {
148 /* Illegal option length. */
149 return(NX_FALSE);
150 }
151
152 /* Move the option pointer forward. */
153 option_ptr = option_ptr + option_length;
154
155 /* Determine if this is greater than the option area size. */
156 if (option_length > option_area_size)
157 {
158 return(NX_FALSE);
159 }
160 else
161 {
162 option_area_size = option_area_size - option_length;
163 }
164 }
165 }
166
167 /* Return. */
168 return(NX_TRUE);
169 }
170 #endif /* NX_ENABLE_TCP_WINDOW_SCALING */
171
172