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
29 /* Include Unity header */
30 #include "unity.h"
31
32 /* Include standard libraries */
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdint.h>
36
37 #include "mock_task.h"
38 #include "mock_list.h"
39
40 /* This must come after list.h is included (in this case, indirectly
41 * by mock_list.h). */
42 #include "mock_FreeRTOS_UDP_IP_list_macros.h"
43 #include "mock_queue.h"
44 #include "mock_event_groups.h"
45
46 #include "mock_FreeRTOS_IP.h"
47 #include "mock_FreeRTOS_IP_Utils.h"
48 #include "mock_FreeRTOS_Sockets.h"
49 #include "mock_FreeRTOS_ARP.h"
50 #include "mock_NetworkBufferManagement.h"
51 #include "mock_NetworkInterface.h"
52 #include "mock_FreeRTOS_DHCP.h"
53 #include "mock_FreeRTOS_DNS.h"
54
55 #include "catch_assert.h"
56
57 #include "FreeRTOSIPConfig.h"
58
59 /* =========================== EXTERN VARIABLES =========================== */
60
61 /* The maximum segment size used by TCP, it is the maximum size of
62 * the TCP payload per packet.
63 * For IPv4: when MTU equals 1500, the MSS equals 1460.
64 * It is recommended to use the default value defined here.
65 *
66 * In FreeRTOS_TCP_IP.c, there is a local macro called 'tcpREDUCED_MSS_THROUGH_INTERNET'.
67 * When a TCP connection is made outside the local network, the MSS
68 * will be reduced to 'tcpREDUCED_MSS_THROUGH_INTERNET' before the connection
69 * is made.
70 */
71 #ifndef ipconfigTCP_MSS
72 #define ipconfigTCP_MSS ( ipconfigNETWORK_MTU - ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
73 #endif
74
75 void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
76 BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t * pxNetworkBuffer,
77 uint16_t usPort,
78 BaseType_t * pxIsWaitingForARPResolution );
79
80 /* ============================== Test Cases ============================== */
81
82 /**
83 * @brief Input with null network buffer pointer.
84 */
test_vProcessGeneratedUDPPacket_NullNetworkBuffer(void)85 void test_vProcessGeneratedUDPPacket_NullNetworkBuffer( void )
86 {
87 vProcessGeneratedUDPPacket( NULL );
88 }
89
90 /**
91 * @brief Pass IPv4 packet to IPv4 API to handle.
92 */
test_vProcessGeneratedUDPPacket_IPv4Packet(void)93 void test_vProcessGeneratedUDPPacket_IPv4Packet( void )
94 {
95 uint8_t pucLocalEthernetBuffer[ ipconfigTCP_MSS ];
96 NetworkBufferDescriptor_t xLocalNetworkBuffer;
97
98 xLocalNetworkBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
99
100 UDPPacket_t * pxUDPPacket = ( ( UDPPacket_t * ) pucLocalEthernetBuffer );
101
102 /* Cleanup the ethernet buffer. */
103 memset( pucLocalEthernetBuffer, 0, ipconfigTCP_MSS );
104 pxUDPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
105
106 vProcessGeneratedUDPPacket_IPv4_Expect( &xLocalNetworkBuffer );
107
108 vProcessGeneratedUDPPacket( &xLocalNetworkBuffer );
109 }
110
111 /**
112 * @brief Pass IPv6 packet to IPv6 API to handle.
113 */
test_vProcessGeneratedUDPPacket_IPv6Packet(void)114 void test_vProcessGeneratedUDPPacket_IPv6Packet( void )
115 {
116 uint8_t pucLocalEthernetBuffer[ ipconfigTCP_MSS ];
117 NetworkBufferDescriptor_t xLocalNetworkBuffer;
118
119 xLocalNetworkBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
120
121 UDPPacket_t * pxUDPPacket = ( ( UDPPacket_t * ) pucLocalEthernetBuffer );
122
123 /* Cleanup the ethernet buffer. */
124 memset( pucLocalEthernetBuffer, 0, ipconfigTCP_MSS );
125 pxUDPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE;
126
127 vProcessGeneratedUDPPacket_IPv6_Expect( &xLocalNetworkBuffer );
128
129 vProcessGeneratedUDPPacket( &xLocalNetworkBuffer );
130 }
131
132 /**
133 * @brief Do nothing if it's an unknown packet.
134 */
test_vProcessGeneratedUDPPacket_UnknownPacket(void)135 void test_vProcessGeneratedUDPPacket_UnknownPacket( void )
136 {
137 uint8_t pucLocalEthernetBuffer[ ipconfigTCP_MSS ];
138 NetworkBufferDescriptor_t xLocalNetworkBuffer;
139
140 xLocalNetworkBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
141
142 UDPPacket_t * pxUDPPacket = ( ( UDPPacket_t * ) pucLocalEthernetBuffer );
143
144 /* Cleanup the ethernet buffer. */
145 memset( pucLocalEthernetBuffer, 0, ipconfigTCP_MSS );
146 pxUDPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE + 1;
147
148 vProcessGeneratedUDPPacket( &xLocalNetworkBuffer );
149 }
150
151 /**
152 * @brief Input with null network buffer pointer.
153 */
test_xProcessReceivedUDPPacket_NullNetworkBuffer(void)154 void test_xProcessReceivedUDPPacket_NullNetworkBuffer( void )
155 {
156 uint16_t usPort = 0x1234;
157 BaseType_t xIsWaitingForARPResolution = 0;
158
159 catch_assert( xProcessReceivedUDPPacket( NULL, usPort, &xIsWaitingForARPResolution ) );
160 }
161
162 /**
163 * @brief Input with null buffer pointer in network buffer.
164 */
test_xProcessReceivedUDPPacket_NullBuffer(void)165 void test_xProcessReceivedUDPPacket_NullBuffer( void )
166 {
167 uint16_t usPort = 0x1234;
168 BaseType_t xIsWaitingForARPResolution = 0;
169 NetworkBufferDescriptor_t xNetworkBuffer;
170
171 memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
172 xNetworkBuffer.pucEthernetBuffer = NULL;
173
174 catch_assert( xProcessReceivedUDPPacket( &xNetworkBuffer, usPort, &xIsWaitingForARPResolution ) );
175 }
176
177 /**
178 * @brief Pass IPv4 packet to IPv4 API to handle.
179 */
test_xProcessReceivedUDPPacket_IPv4Packet(void)180 void test_xProcessReceivedUDPPacket_IPv4Packet( void )
181 {
182 BaseType_t xReturn;
183 uint8_t pucLocalEthernetBuffer[ ipconfigTCP_MSS ];
184 uint16_t usPort = 0x1234;
185 BaseType_t xIsWaitingForARPResolution = 0;
186 NetworkBufferDescriptor_t xNetworkBuffer;
187 UDPPacket_t * pxUDPPacket = ( ( UDPPacket_t * ) pucLocalEthernetBuffer );
188
189 memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
190 xNetworkBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
191
192 /* Cleanup the ethernet buffer. */
193 memset( pucLocalEthernetBuffer, 0, ipconfigTCP_MSS );
194 pxUDPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
195
196 xProcessReceivedUDPPacket_IPv4_ExpectAndReturn( &xNetworkBuffer, usPort, &xIsWaitingForARPResolution, pdPASS );
197
198 xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort, &xIsWaitingForARPResolution );
199
200 TEST_ASSERT_EQUAL( pdPASS, xReturn );
201 }
202
203 /**
204 * @brief Pass IPv6 packet to IPv6 API to handle.
205 */
test_xProcessReceivedUDPPacket_IPv6Packet(void)206 void test_xProcessReceivedUDPPacket_IPv6Packet( void )
207 {
208 BaseType_t xReturn;
209 uint8_t pucLocalEthernetBuffer[ ipconfigTCP_MSS ];
210 uint16_t usPort = 0x1234;
211 BaseType_t xIsWaitingForARPResolution = 0;
212 NetworkBufferDescriptor_t xNetworkBuffer;
213 UDPPacket_t * pxUDPPacket = ( ( UDPPacket_t * ) pucLocalEthernetBuffer );
214
215 memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
216 xNetworkBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
217
218 /* Cleanup the ethernet buffer. */
219 memset( pucLocalEthernetBuffer, 0, ipconfigTCP_MSS );
220 pxUDPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE;
221
222 xProcessReceivedUDPPacket_IPv6_ExpectAndReturn( &xNetworkBuffer, usPort, &xIsWaitingForARPResolution, pdPASS );
223
224 xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort, &xIsWaitingForARPResolution );
225
226 TEST_ASSERT_EQUAL( pdPASS, xReturn );
227 }
228
229 /**
230 * @brief Return fail for unknown packet.
231 */
test_xProcessReceivedUDPPacket_UnknownPacket(void)232 void test_xProcessReceivedUDPPacket_UnknownPacket( void )
233 {
234 BaseType_t xReturn;
235 uint8_t pucLocalEthernetBuffer[ ipconfigTCP_MSS ];
236 uint16_t usPort = 0x1234;
237 BaseType_t xIsWaitingForARPResolution = 0;
238 NetworkBufferDescriptor_t xNetworkBuffer;
239 UDPPacket_t * pxUDPPacket = ( ( UDPPacket_t * ) pucLocalEthernetBuffer );
240
241 memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
242 xNetworkBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
243
244 /* Cleanup the ethernet buffer. */
245 memset( pucLocalEthernetBuffer, 0, ipconfigTCP_MSS );
246 pxUDPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE + 1;
247
248 xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort, &xIsWaitingForARPResolution );
249
250 TEST_ASSERT_EQUAL( pdFAIL, xReturn );
251 }
252