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