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_queue.h"
43 #include "mock_event_groups.h"
44
45 #include "FreeRTOSIPConfig.h"
46
47 #include "FreeRTOS_Routing.h"
48
49 #include "catch_assert.h"
50
51 /* =========================== EXTERN VARIABLES =========================== */
52
53 /* Default IPv4 address is 192.168.123.223, which is 0xDF7BA8C0. */
54 #define IPV4_DEFAULT_ADDRESS ( 0xDF7BA8C0 )
55 /* Default IPv4 netmask is 255.255.255.0, which is 0x00FFFFFF. */
56 #define IPV4_DEFAULT_NETMASK ( 0x00FFFFFF )
57 /* Default IPv4 netmask is 192.168.123.254, which is 0xFE7BA8C0. */
58 #define IPV4_DEFAULT_GATEWAY ( 0xFE7BA8C0 )
59 /* Default IPv4 netmask is 192.168.123.1, which is 0x017BA8C0. */
60 #define IPV4_DEFAULT_DNS_SERVER ( 0x017BA8C0 )
61
62 const uint8_t ucDefaultMACAddress_IPv4[ ipMAC_ADDRESS_LENGTH_BYTES ] = { 0xab, 0xcd, 0xef, 0x11, 0x22, 0x33 };
63
64 /* Default IPv6 address is set to 2001::1 */
65 const IPv6_Address_t xDefaultIPAddress_IPv6 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
66 const uint8_t ucDefaultMACAddress_IPv6[ ipMAC_ADDRESS_LENGTH_BYTES ] = { 0x11, 0x22, 0x33, 0xab, 0xcd, 0xef };
67
68 /* ============================ Unity Fixtures ============================ */
69
70 /*! called before each test case */
setUp(void)71 void setUp( void )
72 {
73 pxNetworkEndPoints = NULL;
74 pxNetworkInterfaces = NULL;
75 }
76
77 /* ============================== Test Cases ============================== */
78
79 /**
80 * @brief FreeRTOS_MatchingEndpoint returns the endpoint matched for custom frame type.
81 *
82 * pxNetworkInterfaces is a global variable using in FreeRTOS_Routing as link list head of all interfaces.
83 * pxNetworkEndPoints is a global variable using in FreeRTOS_Routing as link list head of all endpoints.
84 *
85 * Test step:
86 * - Create 1 interface and 1 endpoint.
87 * - Put interface & endpoint into the list.
88 * - Prepare an custom packet with:
89 * - IP address 192.168.123.223.
90 * - MAC address ab:cd:ef:11:22:33.
91 * - Frame type in ethernet header 0xFF.
92 * - Call FreeRTOS_MatchingEndpoint and check if returned endpoint is same.
93 */
test_FreeRTOS_MatchingEndpoint_MatchCustomFrameType()94 void test_FreeRTOS_MatchingEndpoint_MatchCustomFrameType()
95 {
96 NetworkInterface_t xNetworkInterface;
97 NetworkEndPoint_t xEndPoint;
98 NetworkEndPoint_t * pxEndPoint = NULL;
99 uint8_t * pcNetworkBuffer[ sizeof( TCPPacket_t ) + 4 ] __attribute__( ( aligned( 32 ) ) );
100 ProtocolPacket_t * pxProtocolPacket = ( ProtocolPacket_t * ) ( ( uintptr_t ) ( pcNetworkBuffer ) + 2U );
101
102 /* Initialize network interface. */
103 memset( &xNetworkInterface, 0, sizeof( NetworkInterface_t ) );
104 pxNetworkInterfaces = &xNetworkInterface;
105
106 /* Initialize endpoint. */
107 memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) );
108 xEndPoint.ipv4_settings.ulIPAddress = IPV4_DEFAULT_ADDRESS;
109 memcpy( xEndPoint.xMACAddress.ucBytes, ucDefaultMACAddress_IPv4, sizeof( ucDefaultMACAddress_IPv4 ) );
110 xEndPoint.pxNetworkInterface = &xNetworkInterface;
111 pxNetworkEndPoints = &xEndPoint;
112
113 /* Initialize network buffer. */
114 memset( pcNetworkBuffer, 0, sizeof( pcNetworkBuffer ) );
115 /* Ethernet part. */
116 memcpy( pxProtocolPacket->xTCPPacket.xEthernetHeader.xDestinationAddress.ucBytes, ucDefaultMACAddress_IPv4, ipMAC_ADDRESS_LENGTH_BYTES );
117 memcpy( pxProtocolPacket->xTCPPacket.xEthernetHeader.xSourceAddress.ucBytes, ucDefaultMACAddress_IPv4, ipMAC_ADDRESS_LENGTH_BYTES );
118 pxProtocolPacket->xTCPPacket.xEthernetHeader.usFrameType = 0xFF;
119 /* IP part. */
120 pxProtocolPacket->xTCPPacket.xIPHeader.ulSourceIPAddress = IPV4_DEFAULT_ADDRESS;
121 pxProtocolPacket->xTCPPacket.xIPHeader.ulDestinationIPAddress = IPV4_DEFAULT_ADDRESS;
122
123 pxEndPoint = FreeRTOS_MatchingEndpoint( &xNetworkInterface, ( const uint8_t * ) pxProtocolPacket );
124 TEST_ASSERT_EQUAL( &xEndPoint, pxEndPoint );
125 }
126
127 /**
128 * @brief FreeRTOS_MatchingEndpoint returns NULL when receiving IPv6 packet but no IPv6 endpoint in the list.
129 *
130 * pxNetworkInterfaces is a global variable using in FreeRTOS_Routing as link list head of all interfaces.
131 * pxNetworkEndPoints is a global variable using in FreeRTOS_Routing as link list head of all endpoints.
132 *
133 * Test step:
134 * - Create 1 interface and 1 endpoint.
135 * - Put interface & endpoint into the list.
136 * - Assign 192.168.123.223 (IPV4_DEFAULT_ADDRESS) to the endpoint.
137 * - Assign ab:cd:ef:11:22:33 (ucDefaultMACAddress_IPv4) to the endpoint.
138 * - Assign 0xFF as frame type to the endpoint.
139 * - Attach endpoint to interface.
140 * - Call FreeRTOS_MatchingEndpoint and check if returned endpoint is NULL.
141 */
test_FreeRTOS_MatchingEndpoint_IPv6Disabled()142 void test_FreeRTOS_MatchingEndpoint_IPv6Disabled()
143 {
144 NetworkInterface_t xNetworkInterface;
145 NetworkEndPoint_t xEndPoint;
146 NetworkEndPoint_t * pxEndPoint = NULL;
147 uint8_t * pcNetworkBuffer[ sizeof( TCPPacket_IPv6_t ) + 4 ] __attribute__( ( aligned( 32 ) ) );
148 TCPPacket_IPv6_t * pxTCPPacket = ( TCPPacket_IPv6_t * ) ( ( uintptr_t ) ( pcNetworkBuffer ) + 2U );
149
150 /* Initialize network interface. */
151 memset( &xNetworkInterface, 0, sizeof( NetworkInterface_t ) );
152 pxNetworkInterfaces = &xNetworkInterface;
153
154 /* Initialize endpoint. */
155 memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) );
156 xEndPoint.ipv4_settings.ulIPAddress = IPV4_DEFAULT_ADDRESS;
157 memcpy( xEndPoint.xMACAddress.ucBytes, ucDefaultMACAddress_IPv4, sizeof( ucDefaultMACAddress_IPv4 ) );
158 xEndPoint.pxNetworkInterface = &xNetworkInterface;
159 pxNetworkEndPoints = &xEndPoint;
160
161 /* Initialize network buffer. */
162 memset( pcNetworkBuffer, 0, sizeof( pcNetworkBuffer ) );
163 /* Ethernet part. */
164 memcpy( pxTCPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ucDefaultMACAddress_IPv6, ipMAC_ADDRESS_LENGTH_BYTES );
165 memcpy( pxTCPPacket->xEthernetHeader.xSourceAddress.ucBytes, ucDefaultMACAddress_IPv6, ipMAC_ADDRESS_LENGTH_BYTES );
166 pxTCPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE;
167 /* IP part. */
168 memcpy( pxTCPPacket->xIPHeader.xSourceAddress.ucBytes, xDefaultIPAddress_IPv6.ucBytes, ipSIZE_OF_IPv4_ADDRESS );
169 memcpy( pxTCPPacket->xIPHeader.xDestinationAddress.ucBytes, xDefaultIPAddress_IPv6.ucBytes, ipSIZE_OF_IPv4_ADDRESS );
170
171 pxEndPoint = FreeRTOS_MatchingEndpoint( &xNetworkInterface, ( const uint8_t * ) pxTCPPacket );
172 TEST_ASSERT_EQUAL( NULL, pxEndPoint );
173 }
174
175 /**
176 * @brief pcEndpointName can't get IPv6 address in string from endpoint due to IPv6 is disabled.
177 *
178 * pxNetworkInterfaces is a global variable using in FreeRTOS_Routing as link list head of all interfaces.
179 * pxNetworkEndPoints is a global variable using in FreeRTOS_Routing as link list head of all endpoints.
180 *
181 * Test step:
182 * - Create 1 endpoint.
183 * - Set the IP address to 2001::1 (xDefaultIPAddress_IPv6).
184 * - Call pcEndpointName with enough buffer size.
185 * - Check if return buffer string is NULL.
186 */
test_pcEndpointName_IPv6HappyPath()187 void test_pcEndpointName_IPv6HappyPath()
188 {
189 NetworkEndPoint_t xEndPoint;
190 FreeRTOS_Socket_t xSocket;
191 const char cIPString[] = "2001::1";
192 int lNameSize = sizeof( cIPString ) + 1;
193 char cName[ lNameSize ];
194 const char * pcName;
195
196 /* Initialize network endpoint and add it to the list. */
197 memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) );
198 xEndPoint.bits.bIPv6 = pdTRUE;
199
200 memset( &cName, 0, sizeof( cName ) );
201
202 pcName = pcEndpointName( &xEndPoint, cName, lNameSize );
203 TEST_ASSERT_EQUAL_STRING( "NULL", pcName );
204 }
205
206 /**
207 * @brief FreeRTOS_FindGateWay should be able to find the endpoint with valid IPv4 gateway address.
208 *
209 * pxNetworkInterfaces is a global variable using in FreeRTOS_Routing as link list head of all interfaces.
210 * pxNetworkEndPoints is a global variable using in FreeRTOS_Routing as link list head of all endpoints.
211 *
212 * Test step:
213 * - Create 1 IPv4 endpoint and add it to the list.
214 * - Set the gateway address to 192.168.123.254 (IPV4_DEFAULT_GATEWAY).
215 * - Call FreeRTOS_FindGateWay with ipTYPE_IPv4.
216 * - Check if returned endpoint is same.
217 */
test_FreeRTOS_FindGateWay_IPv4HappyPath(void)218 void test_FreeRTOS_FindGateWay_IPv4HappyPath( void )
219 {
220 NetworkEndPoint_t xEndPoint;
221 NetworkEndPoint_t * pxEndPoint = NULL;
222
223 /* Initialize network endpoint and add it to the list. */
224 memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) );
225 xEndPoint.ipv4_settings.ulGatewayAddress = IPV4_DEFAULT_GATEWAY;
226 pxNetworkEndPoints = &xEndPoint;
227
228 pxEndPoint = FreeRTOS_FindGateWay( ipTYPE_IPv4 );
229 TEST_ASSERT_EQUAL( &xEndPoint, pxEndPoint );
230 }
231
232 /**
233 * @brief FreeRTOS_FindGateWay should be able to return NULL if no valid IPv4 gateway address.
234 *
235 * pxNetworkInterfaces is a global variable using in FreeRTOS_Routing as link list head of all interfaces.
236 * pxNetworkEndPoints is a global variable using in FreeRTOS_Routing as link list head of all endpoints.
237 *
238 * Test step:
239 * - Create 1 IPv4 endpoint and add it to the list.
240 * - Set the gateway address to 0 (invalid address).
241 * - Call FreeRTOS_FindGateWay with ipTYPE_IPv4.
242 * - Check if returned endpoint is NULL.
243 */
test_FreeRTOS_FindGateWay_IPv4NotFound(void)244 void test_FreeRTOS_FindGateWay_IPv4NotFound( void )
245 {
246 NetworkEndPoint_t xEndPoint;
247 NetworkEndPoint_t * pxEndPoint = NULL;
248
249 /* Initialize network endpoint and add it to the list. */
250 memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) );
251 pxNetworkEndPoints = &xEndPoint;
252
253 pxEndPoint = FreeRTOS_FindGateWay( ipTYPE_IPv4 );
254 TEST_ASSERT_EQUAL( NULL, pxEndPoint );
255 }
256