xref: /FreeRTOS-Plus-TCP-v4.0.0/tools/tcp_utilities/tcp_netstat.c (revision 2d3f4daa567ffe71aeda2e0f6d0bc02850db0627)
1 /*
2  * FreeRTOS+TCP <DEVELOPMENT BRANCH>
3  * Copyright (C) 2022 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * http://aws.amazon.com/freertos
25  * http://www.FreeRTOS.org
26  */
27 
28 /* Standard includes. */
29 #include <stdint.h>
30 #include <stdio.h>
31 
32 /* FreeRTOS includes. */
33 #include "FreeRTOS.h"
34 #include "task.h"
35 #include "queue.h"
36 #include "semphr.h"
37 
38 /* FreeRTOS+TCP includes. */
39 #include "FreeRTOS_IP.h"
40 #include "FreeRTOS_Sockets.h"
41 #include "FreeRTOS_IP_Private.h"
42 
43 #include "tcp_netstat.h"
44 
45 extern List_t xBoundUDPSocketsList;
46 
47 #if ( ipconfigUSE_TCP == 1 )
48     extern List_t xBoundTCPSocketsList;
49 #endif /* ipconfigUSE_TCP == 1 */
50 
51 IOCounters_t xInputCounters, xOutputCounters;
52 
vGetMetrics(MetricsType_t * pxMetrics)53 BaseType_t vGetMetrics( MetricsType_t * pxMetrics )
54 {
55     BaseType_t xResult = 0;
56 
57     /* Show a simple listing of all created sockets and their connections */
58     const ListItem_t * pxIterator;
59     uint16_t usLastPort;
60 
61     memset( pxMetrics, 0, sizeof *pxMetrics );
62 
63     pxMetrics->xInput = xInputCounters;
64     pxMetrics->xOutput = xOutputCounters;
65 
66     if( !listLIST_IS_INITIALISED( &xBoundUDPSocketsList ) )
67     {
68         FreeRTOS_printf( ( "PLUS-TCP not initialized\n" ) );
69         xResult = -1;
70     }
71     else
72     {
73         #if ( ipconfigUSE_TCP == 1 )
74             const ListItem_t * pxEndTCP = listGET_END_MARKER( &xBoundTCPSocketsList );
75         #endif
76         const ListItem_t * pxEndUDP = listGET_END_MARKER( &xBoundUDPSocketsList );
77 
78         usLastPort = 0U;
79 
80         #if ( ipconfigUSE_TCP == 1 )
81             {
82                 vTaskSuspendAll();
83                 {
84                     for( pxIterator = listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
85                          pxIterator != pxEndTCP;
86                          pxIterator = listGET_NEXT( pxIterator ) )
87                     {
88                         const FreeRTOS_Socket_t * pxSocket = ( const FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
89 
90                         if( pxMetrics->xTCPPortList.uxCount < nstatMAX_TCP_PORTS )
91                         {
92                             if( usLastPort != pxSocket->usLocalPort )
93                             {
94                                 pxMetrics->xTCPPortList.usTCPPortList[ pxMetrics->xTCPPortList.uxCount ] = pxSocket->usLocalPort;
95                                 pxMetrics->xTCPPortList.uxCount++;
96                                 usLastPort = pxSocket->usLocalPort;
97                             }
98                         }
99 
100                         if( pxMetrics->xTCPSocketList.uxCount < nstatMAX_TCP_PORTS )
101                         {
102                             size_t uxCount = pxMetrics->xTCPSocketList.uxCount;
103 
104                             pxMetrics->xTCPSocketList.xTCPList[ uxCount ].usLocalPort = pxSocket->usLocalPort;
105                             pxMetrics->xTCPSocketList.xTCPList[ uxCount ].ulRemoteIP = pxSocket->u.xTCP.xRemoteIP.ulIP_IPv4;
106                             pxMetrics->xTCPSocketList.xTCPList[ uxCount ].usRemotePort = pxSocket->u.xTCP.usRemotePort;
107                             pxMetrics->xTCPSocketList.uxCount++;
108                         }
109                     }
110                 }
111 
112                 if( xTaskResumeAll() == 0 )
113                 {
114                     taskYIELD();
115                 }
116             }
117         #endif /* ( ipconfigUSE_TCP == 1 ) */
118 
119         vTaskSuspendAll();
120         {
121             for( pxIterator = listGET_HEAD_ENTRY( &xBoundUDPSocketsList );
122                  pxIterator != pxEndUDP;
123                  pxIterator = listGET_NEXT( pxIterator ) )
124             {
125                 const FreeRTOS_Socket_t * pxSocket = ( const FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
126 
127                 if( pxMetrics->xUDPPortList.uxCount < nstatMAX_UDP_PORTS )
128                 {
129                     pxMetrics->xUDPPortList.usUDPPortList[ pxMetrics->xUDPPortList.uxCount ] = pxSocket->usLocalPort;
130                     pxMetrics->xUDPPortList.uxCount++;
131                 }
132 
133                 if( pxMetrics->xUDPSocketList.uxCount < nstatMAX_UDP_PORTS )
134                 {
135                     size_t uxCount = pxMetrics->xUDPSocketList.uxCount;
136                     pxMetrics->xUDPSocketList.xUDPList[ uxCount ].usLocalPort = pxSocket->usLocalPort;
137                     pxMetrics->xUDPSocketList.uxCount++;
138                 }
139             }
140         }
141         ( void ) xTaskResumeAll();
142     }
143 
144     return xResult;
145 }
146 
vShowMetrics(const MetricsType_t * pxMetrics)147 void vShowMetrics( const MetricsType_t * pxMetrics )
148 {
149     size_t uxIndex;
150 
151     FreeRTOS_printf( ( "Bytes in/out:\n" ) );
152     FreeRTOS_printf( ( "    Input  : %5lu packets, %5lu bytes\n",
153                        pxMetrics->xInput.uxPacketCount,
154                        pxMetrics->xInput.uxByteCount ) );
155     FreeRTOS_printf( ( "    Output : %5lu packets, %5lu bytes\n",
156                        pxMetrics->xOutput.uxPacketCount,
157                        pxMetrics->xOutput.uxByteCount ) );
158 
159     #if ( ipconfigUSE_TCP == 1 )
160         {
161             FreeRTOS_printf( ( "TCP ports:\n" ) );
162 
163             for( uxIndex = 0; uxIndex < pxMetrics->xTCPPortList.uxCount; uxIndex++ )
164             {
165                 FreeRTOS_printf( ( "    local port: %u\n",
166                                    pxMetrics->xTCPPortList.usTCPPortList[ uxIndex ] ) );
167             }
168 
169             FreeRTOS_printf( ( "TCP sockets:\n" ) );
170 
171             for( uxIndex = 0; uxIndex < pxMetrics->xTCPSocketList.uxCount; uxIndex++ )
172             {
173                 FreeRTOS_printf( ( "    local port: %u remote IP %xip:%u\n",
174                                    pxMetrics->xTCPSocketList.xTCPList[ uxIndex ].usLocalPort,
175                                    pxMetrics->xTCPSocketList.xTCPList[ uxIndex ].ulRemoteIP,
176                                    pxMetrics->xTCPSocketList.xTCPList[ uxIndex ].usRemotePort ) );
177             }
178         }
179     #endif /* ( ipconfigUSE_TCP == 1 ) */
180 
181     FreeRTOS_printf( ( "UDP ports:\n" ) );
182 
183     for( uxIndex = 0; uxIndex < pxMetrics->xUDPPortList.uxCount; uxIndex++ )
184     {
185         FreeRTOS_printf( ( "    local port: %u\n",
186                            pxMetrics->xUDPPortList.usUDPPortList[ uxIndex ] ) );
187     }
188 
189     FreeRTOS_printf( ( "UDP sockets:\n" ) );
190 
191     for( uxIndex = 0; uxIndex < pxMetrics->xUDPSocketList.uxCount; uxIndex++ )
192     {
193         FreeRTOS_printf( ( "    local port: %u\n",
194                            pxMetrics->xUDPSocketList.xUDPList[ uxIndex ].usLocalPort ) );
195     }
196 }
197