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