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 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _nx_tcp_socket_info_get                             PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Yuxin Zhou, Microsoft Corporation                                   */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function retrieves TCP information for the specified TCP       */
44 /*    socket.                                                             */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    socket_ptr                            Pointer to the TCP socket     */
49 /*    tcp_packets_sent                      Destination for number of     */
50 /*                                            packets sent                */
51 /*    tcp_bytes_sent                        Destination for number of     */
52 /*                                            bytes sent                  */
53 /*    tcp_packets_received                  Destination for number of     */
54 /*                                            packets received            */
55 /*    tcp_bytes_received                    Destination for number of     */
56 /*                                            bytes received              */
57 /*    tcp_retransmit_packets                Destination for number of     */
58 /*                                            retransmit packets          */
59 /*    tcp_packets_queued                    Destination for number of     */
60 /*                                            receive packets queued      */
61 /*    tcp_checksum_errors                   Destination for number of     */
62 /*                                            checksum errors             */
63 /*    tcp_socket_state                      Destination for the current   */
64 /*                                            socket state                */
65 /*    tcp_transmit_queue_depth              Destination for number of     */
66 /*                                            sockets still in transmit   */
67 /*                                            queue                       */
68 /*    tcp_transmit_window                   Destination for number of     */
69 /*                                            bytes in transmit window    */
70 /*    tcp_receive_window                    Destination for number of     */
71 /*                                            bytes in receive window     */
72 /*                                                                        */
73 /*  OUTPUT                                                                */
74 /*                                                                        */
75 /*    status                                Completion status             */
76 /*                                                                        */
77 /*  CALLS                                                                 */
78 /*                                                                        */
79 /*    tx_mutex_get                          Obtain protection             */
80 /*    tx_mutex_put                          Release protection            */
81 /*                                                                        */
82 /*  CALLED BY                                                             */
83 /*                                                                        */
84 /*    Application Code                                                    */
85 /*                                                                        */
86 /*  RELEASE HISTORY                                                       */
87 /*                                                                        */
88 /*    DATE              NAME                      DESCRIPTION             */
89 /*                                                                        */
90 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
91 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
92 /*                                            resulting in version 6.1    */
93 /*                                                                        */
94 /**************************************************************************/
_nx_tcp_socket_info_get(NX_TCP_SOCKET * socket_ptr,ULONG * tcp_packets_sent,ULONG * tcp_bytes_sent,ULONG * tcp_packets_received,ULONG * tcp_bytes_received,ULONG * tcp_retransmit_packets,ULONG * tcp_packets_queued,ULONG * tcp_checksum_errors,ULONG * tcp_socket_state,ULONG * tcp_transmit_queue_depth,ULONG * tcp_transmit_window,ULONG * tcp_receive_window)95 UINT  _nx_tcp_socket_info_get(NX_TCP_SOCKET *socket_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
96                               ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
97                               ULONG *tcp_retransmit_packets, ULONG *tcp_packets_queued,
98                               ULONG *tcp_checksum_errors, ULONG *tcp_socket_state,
99                               ULONG *tcp_transmit_queue_depth, ULONG *tcp_transmit_window,
100                               ULONG *tcp_receive_window)
101 {
102 
103 NX_IP *ip_ptr;
104 
105 
106     /* Setup IP pointer.  */
107     ip_ptr =  socket_ptr -> nx_tcp_socket_ip_ptr;
108 
109     /* If trace is enabled, insert this event into the trace buffer.  */
110     NX_TRACE_IN_LINE_INSERT(NX_TRACE_TCP_SOCKET_INFO_GET, ip_ptr, socket_ptr, socket_ptr -> nx_tcp_socket_packets_sent, socket_ptr -> nx_tcp_socket_bytes_received, NX_TRACE_TCP_EVENTS, 0, 0);
111 
112     /* Obtain the IP mutex so we can examine the bound port.  */
113     tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
114 
115     /* Determine if packets sent is wanted.  */
116     if (tcp_packets_sent)
117     {
118 
119         /* Return the number of packets sent by this socket.  */
120         *tcp_packets_sent =  socket_ptr -> nx_tcp_socket_packets_sent;
121     }
122 
123     /* Determine if bytes sent is wanted.  */
124     if (tcp_bytes_sent)
125     {
126 
127         /* Return the number of bytes sent by this socket.  */
128         *tcp_bytes_sent =  socket_ptr -> nx_tcp_socket_bytes_sent;
129     }
130 
131     /* Determine if packets received is wanted.  */
132     if (tcp_packets_received)
133     {
134 
135         /* Return the number of packets received by this socket.  */
136         *tcp_packets_received =  socket_ptr -> nx_tcp_socket_packets_received;
137     }
138 
139     /* Determine if bytes received is wanted.  */
140     if (tcp_bytes_received)
141     {
142 
143         /* Return the number of bytes received by this socket.  */
144         *tcp_bytes_received =  socket_ptr -> nx_tcp_socket_bytes_received;
145     }
146 
147     /* Determine if retransmit packets is wanted.  */
148     if (tcp_retransmit_packets)
149     {
150 
151         /* Return the number of retransmit packets by this socket.  */
152         *tcp_retransmit_packets =  socket_ptr -> nx_tcp_socket_retransmit_packets;
153     }
154 
155     /* Determine if packets queued is wanted.  */
156     if (tcp_packets_queued)
157     {
158 
159         /* Return the number of packets queued by this socket.  */
160         *tcp_packets_queued =  socket_ptr -> nx_tcp_socket_receive_queue_count;
161     }
162 
163     /* Determine if checksum errors is wanted.  */
164     if (tcp_checksum_errors)
165     {
166 
167         /* Return the number of checksum errors by this socket.  */
168         *tcp_checksum_errors =  socket_ptr -> nx_tcp_socket_checksum_errors;
169     }
170 
171     /* Determine if socket state is wanted.  */
172     if (tcp_socket_state)
173     {
174 
175         /* Return the state this socket.  */
176         *tcp_socket_state =  socket_ptr -> nx_tcp_socket_state;
177     }
178 
179     /* Determine if transmit queue depth is wanted.  */
180     if (tcp_transmit_queue_depth)
181     {
182 
183         /* Return the transmit queue depth of this socket.  */
184         *tcp_transmit_queue_depth =  socket_ptr -> nx_tcp_socket_transmit_sent_count;
185     }
186 
187     /* Determine if transmit window size is wanted.  */
188     if (tcp_transmit_window)
189     {
190 
191         /* Return the transmit window size of this socket.  */
192         if (socket_ptr -> nx_tcp_socket_tx_window_advertised > socket_ptr -> nx_tcp_socket_tx_window_congestion)
193         {
194             *tcp_transmit_window = socket_ptr -> nx_tcp_socket_tx_window_congestion;
195         }
196         else
197         {
198             *tcp_transmit_window = socket_ptr -> nx_tcp_socket_tx_window_advertised;
199         }
200         if (*tcp_transmit_window > socket_ptr -> nx_tcp_socket_tx_outstanding_bytes)
201         {
202             *tcp_transmit_window =  *tcp_transmit_window - socket_ptr -> nx_tcp_socket_tx_outstanding_bytes;
203         }
204         else
205         {
206             *tcp_transmit_window = 0;
207         }
208     }
209 
210     /* Determine if receive window size is wanted.  */
211     if (tcp_receive_window)
212     {
213 
214         /* Return the receive window size of this socket.  */
215         *tcp_receive_window =  socket_ptr -> nx_tcp_socket_rx_window_current;
216     }
217 
218     /* Release protection.  */
219     tx_mutex_put(&(ip_ptr -> nx_ip_protection));
220 
221     /* Return successful completion status.  */
222     return(NX_SUCCESS);
223 }
224 
225