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