xref: /FreeRTOS-Plus-TCP-v4.0.0/test/unit-test/FreeRTOS_ND/FreeRTOS_ND_utest.c (revision c64bef1957a72e35be2f6584dafea00df0ed6f03)
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 #include "FreeRTOS.h"
37 
38 #include "mock_task.h"
39 #include "mock_list.h"
40 
41 /* This must come after list.h is included (in this case, indirectly
42  * by mock_list.h). */
43 #include "mock_queue.h"
44 #include "mock_event_groups.h"
45 
46 #include "mock_FreeRTOS_ARP.h"
47 #include "mock_FreeRTOS_IP.h"
48 #include "mock_FreeRTOS_IPv6.h"
49 #include "mock_FreeRTOS_IP_Private.h"
50 #include "mock_FreeRTOS_IP_Timers.h"
51 #include "mock_FreeRTOS_IP_Utils.h"
52 #include "mock_FreeRTOS_IPv6_Utils.h"
53 #include "mock_FreeRTOS_Routing.h"
54 #include "mock_NetworkBufferManagement.h"
55 
56 #include "catch_assert.h"
57 #include "FreeRTOS_ND_stubs.c"
58 #include "FreeRTOS_ND.h"
59 
60 /* ===========================  EXTERN VARIABLES  =========================== */
61 
62 extern const char * pcMessageType( BaseType_t xType );
63 
64 /*  The ND cache. */
65 extern NDCacheRow_t xNDCache[ ipconfigND_CACHE_ENTRIES ];
66 
67 /* Setting IPv6 address as "fe80::7009" */
68 static const IPv6_Address_t xDefaultIPAddress =
69 {
70     0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x09
72 };
73 
74 /* IPv6 multi-cast address is ff02::. */
75 static const IPv6_Address_t xMultiCastIPAddress =
76 {
77     0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
79 };
80 
81 /* Setting eIPv6_SiteLocal IPv6 address as "feC0::7009" */
82 static const IPv6_Address_t xSiteLocalIPAddress =
83 {
84     0xfe, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x09
86 };
87 
88 /* Setting IPv6 Gateway address as "fe80::1" */
89 static const IPv6_Address_t xGatewayIPAddress =
90 {
91     0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
93 };
94 
95 /* IPv6 default MAC address. */
96 static const MACAddress_t xDefaultMACAddress = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
97 
98 #define xHeaderSize                                   ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( ICMPHeader_IPv6_t ) )
99 
100 /** @brief When ucAge becomes 3 or less, it is time for a new
101  * neighbour solicitation.
102  */
103 #define ndMAX_CACHE_AGE_BEFORE_NEW_ND_SOLICITATION    ( 3U )
104 
105 /* =============================== Test Cases =============================== */
106 
107 /**
108  * @brief This function find the MAC-address of a multicast IPv6 address
109  *        with a valid endpoint.
110  */
test_eNDGetCacheEntry_MulticastEndPoint(void)111 void test_eNDGetCacheEntry_MulticastEndPoint( void )
112 {
113     eARPLookupResult_t eResult;
114     MACAddress_t xMACAddress;
115     IPv6_Address_t xIPAddress;
116     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
117 
118     ( void ) memcpy( xIPAddress.ucBytes, xMultiCastIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
119 
120     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdTRUE );
121     vSetMultiCastIPv6MacAddress_ExpectAnyArgs();
122 
123     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( NULL );
124 
125     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
126 
127     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
128 }
129 
130 /**
131  * @brief This function find the MAC-address of a multicast IPv6 address
132  *        with a valid endpoint.
133  */
test_eNDGetCacheEntry_Multicast_ValidEndPoint(void)134 void test_eNDGetCacheEntry_Multicast_ValidEndPoint( void )
135 {
136     NetworkEndPoint_t xEndPoint1, xEndPoint2, xEndPoint3, * pxEndPoint = &xEndPoint1;
137     eARPLookupResult_t eResult;
138     MACAddress_t xMACAddress;
139     IPv6_Address_t xIPAddress;
140 
141     xEndPoint1.bits.bIPv6 = 0;
142     xEndPoint2.bits.bIPv6 = 1;
143     xEndPoint3.bits.bIPv6 = 1;
144     ( void ) memcpy( xIPAddress.ucBytes, xMultiCastIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
145 
146     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdTRUE );
147     vSetMultiCastIPv6MacAddress_ExpectAnyArgs();
148 
149     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( &xEndPoint1 );
150     FreeRTOS_NextEndPoint_ExpectAnyArgsAndReturn( &xEndPoint2 );
151     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Unknown );
152     FreeRTOS_NextEndPoint_ExpectAnyArgsAndReturn( &xEndPoint3 );
153     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
154 
155     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
156 
157     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
158 }
159 
160 /**
161  * @brief This function find the MAC-address of a multicast IPv6 address
162  *        with a NULL endpoint.
163  */
test_eNDGetCacheEntry_Multicast_InvalidEndPoint(void)164 void test_eNDGetCacheEntry_Multicast_InvalidEndPoint( void )
165 {
166     NetworkEndPoint_t ** ppxEndPoint = NULL;
167     eARPLookupResult_t eResult;
168     MACAddress_t xMACAddress;
169     IPv6_Address_t xIPAddress;
170 
171     ( void ) memcpy( xIPAddress.ucBytes, xMultiCastIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
172 
173     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdTRUE );
174     vSetMultiCastIPv6MacAddress_ExpectAnyArgs();
175 
176     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, ppxEndPoint );
177 
178     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
179 }
180 
181 /**
182  * @brief This function find the MAC-address of an IPv6 address which is
183  *        not multi cast address, but the entry is present on the ND Cache,
184  *        with an invalid EndPoint.
185  */
test_eNDGetCacheEntry_NDCacheLookupHit_InvalidEndPoint(void)186 void test_eNDGetCacheEntry_NDCacheLookupHit_InvalidEndPoint( void )
187 {
188     MACAddress_t xMACAddress;
189     IPv6_Address_t xIPAddress;
190     NetworkEndPoint_t ** ppxEndPoint = NULL;
191     eARPLookupResult_t eResult;
192     BaseType_t xUseEntry = 0;
193 
194     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
195 
196     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
197     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
198     ( void ) memcpy( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
199     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
200     xNDCache[ xUseEntry ].ucAge = 1;
201     xNDCache[ xUseEntry ].ucValid = 1;
202 
203     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, ppxEndPoint );
204 
205     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
206     TEST_ASSERT_EQUAL_MEMORY( xMACAddress.ucBytes, xNDCache[ xUseEntry ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
207 }
208 
209 /**
210  * @brief This function find the MAC-address of an IPv6 address which is
211  *        not multi cast address, but the entry is present on the ND Cache,
212  *        with an valid EndPoint. The endpoint gets updated based on the
213  *        endpoint in ND Cache.
214  */
test_eNDGetCacheEntry_NDCacheLookupHit_ValidEndPoint(void)215 void test_eNDGetCacheEntry_NDCacheLookupHit_ValidEndPoint( void )
216 {
217     MACAddress_t xMACAddress;
218     IPv6_Address_t xIPAddress;
219     NetworkEndPoint_t * pxEndPoint, xEndPoint1, xEndPoint2;
220     eARPLookupResult_t eResult;
221     BaseType_t xUseEntry = 0;
222 
223     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
224 
225     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
226     ( void ) memset( &xEndPoint2, 0, sizeof( NetworkEndPoint_t ) );
227     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
228     ( void ) memcpy( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
229     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
230 
231     xNDCache[ xUseEntry ].ucAge = 1;
232     xNDCache[ xUseEntry ].ucValid = 1;
233     xNDCache[ xUseEntry ].pxEndPoint = &xEndPoint2;
234     pxEndPoint = &xEndPoint1;
235 
236     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
237 
238     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
239     TEST_ASSERT_EQUAL_MEMORY( xMACAddress.ucBytes, xNDCache[ xUseEntry ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
240     TEST_ASSERT_EQUAL_MEMORY( pxEndPoint, &xEndPoint2, sizeof( NetworkEndPoint_t ) );
241 }
242 
243 /**
244  * @brief This function find the MAC-address of an IPv6 address which is
245  *        not multi cast address, ND cache lookup fails with invalid Endpoint.
246  */
test_eNDGetCacheEntry_NDCacheLookupMiss_InvalidEntry(void)247 void test_eNDGetCacheEntry_NDCacheLookupMiss_InvalidEntry( void )
248 {
249     NetworkEndPoint_t * pxEndPoint, xEndPoint;
250     eARPLookupResult_t eResult;
251     BaseType_t xUseEntry = 0;
252     MACAddress_t xMACAddress;
253     IPv6_Address_t xIPAddress;
254 
255     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
256 
257     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
258     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
259     xNDCache[ xUseEntry ].ucValid = 0; /*Invalid Cache entry needs to be skipped */
260     pxEndPoint = &xEndPoint;
261 
262     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
263     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( pxEndPoint );
264 
265     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
266 
267     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
268 }
269 
270 /**
271  * @brief This function find the MAC-address of an IPv6 address which is
272  *        not multi cast address, ND cache lookup fails with invalid entry.
273  */
test_eNDGetCacheEntry_NDCacheLookupMiss_InvalidEntry2(void)274 void test_eNDGetCacheEntry_NDCacheLookupMiss_InvalidEntry2( void )
275 {
276     NetworkEndPoint_t ** ppxEndPoint = NULL, xEndPoint;
277     eARPLookupResult_t eResult;
278     BaseType_t xUseEntry = 0;
279     MACAddress_t xMACAddress;
280     IPv6_Address_t xIPAddress;
281 
282     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
283 
284     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
285     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
286     xNDCache[ xUseEntry ].ucValid = 0; /*Invalid Cache entry needs to be skipped */
287 
288     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
289     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( &xEndPoint );
290 
291     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, ppxEndPoint );
292 
293     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
294 }
295 
296 /**
297  * @brief This function find the MAC-address of an IPv6 address which is
298  *        not multi cast address & ND cache lookup fails as Entry is valid
299  *        but the MAC-address doesn't match.
300  */
test_eNDGetCacheEntry_NDCacheLookupMiss_NoEntry(void)301 void test_eNDGetCacheEntry_NDCacheLookupMiss_NoEntry( void )
302 {
303     NetworkEndPoint_t * pxEndPoint, xEndPoint;
304     eARPLookupResult_t eResult;
305     BaseType_t xUseEntry = 0;
306     MACAddress_t xMACAddress;
307     IPv6_Address_t xIPAddress;
308 
309     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
310 
311     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
312     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
313     xNDCache[ xUseEntry ].ucValid = 1; /*Valid Cache entry needs to be skipped */
314     pxEndPoint = &xEndPoint;
315 
316     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
317     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( pxEndPoint );
318 
319     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
320 
321     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
322 }
323 
324 /**
325  * @brief This function find the MAC-address of an IPv6 address which is
326  *        not multi cast address & ND cache lookup fails to find a valid
327  *        Endpoint as well as no Endpoint of type eIPv6_LinkLocal.
328  */
test_eNDGetCacheEntry_NDCacheLookupMiss_NoLinkLocal(void)329 void test_eNDGetCacheEntry_NDCacheLookupMiss_NoLinkLocal( void )
330 {
331     NetworkEndPoint_t * pxEndPoint, xEndPoint;
332     eARPLookupResult_t eResult;
333     BaseType_t xUseEntry = 0;
334     MACAddress_t xMACAddress;
335     IPv6_Address_t xIPAddress;
336 
337     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
338 
339     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
340     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
341     xNDCache[ xUseEntry ].ucValid = 1; /*Valid Cache entry needs to be skipped */
342     pxEndPoint = &xEndPoint;
343 
344     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
345     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
346 
347     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
348     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
349     FreeRTOS_NextEndPoint_ExpectAnyArgsAndReturn( NULL );
350 
351     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
352 
353     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
354 }
355 
356 /**
357  * @brief This function find the MAC-address of an IPv6 address which is
358  *        not multi cast address & ND cache lookup fails to find a valid
359  *        Endpoint but was able to find of type eIPv6_LinkLocal.
360  */
test_eNDGetCacheEntry_NDCacheLookupMiss_LinkLocal(void)361 void test_eNDGetCacheEntry_NDCacheLookupMiss_LinkLocal( void )
362 {
363     NetworkEndPoint_t * pxEndPoint, xEndPoint;
364     eARPLookupResult_t eResult;
365     BaseType_t xUseEntry = 0;
366     MACAddress_t xMACAddress;
367     IPv6_Address_t xIPAddress;
368 
369     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
370 
371     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
372     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
373     pxEndPoint = &xEndPoint;
374 
375     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
376     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
377 
378     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
379     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_LinkLocal );
380 
381     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
382 
383     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
384 }
385 
386 /**
387  * @brief This function find the MAC-address of an IPv6 address when
388  *        there is a Cache miss but gateway has an entry in the cache.
389  */
test_eNDGetCacheEntry_NDCacheLookupHit_Gateway(void)390 void test_eNDGetCacheEntry_NDCacheLookupHit_Gateway( void )
391 {
392     MACAddress_t xMACAddress;
393     IPv6_Address_t xIPAddress;
394     NetworkEndPoint_t * pxEndPoint, xEndPoint1, xEndPoint2;
395     eARPLookupResult_t eResult;
396     BaseType_t xUseEntry = 0;
397 
398     pxEndPoint = &xEndPoint2;
399     ( void ) memcpy( xEndPoint1.ipv6_settings.xGatewayAddress.ucBytes, xGatewayIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
400     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
401     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xGatewayIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
402     ( void ) memcpy( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
403     xNDCache[ xUseEntry ].ucValid = 1; /*Valid Cache entry needs to be skipped */
404     ( void ) memcpy( xIPAddress.ucBytes, xSiteLocalIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
405 
406     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
407 
408     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_SiteLocal );
409     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
410 
411     FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( &xEndPoint1 );
412 
413     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
414 
415     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
416     TEST_ASSERT_EQUAL_MEMORY( xMACAddress.ucBytes, xNDCache[ xUseEntry ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
417 }
418 
419 /**
420  * @brief This function can't find the MAC-address of an IPv6 address when
421  *        there is a Cache miss and gateway has no entry in the cache.
422  */
test_eNDGetCacheEntry_NDCacheLookupMiss_Gateway(void)423 void test_eNDGetCacheEntry_NDCacheLookupMiss_Gateway( void )
424 {
425     MACAddress_t xMACAddress;
426     IPv6_Address_t xIPAddress;
427     NetworkEndPoint_t * pxEndPoint, xEndPoint1, xEndPoint2;
428     eARPLookupResult_t eResult;
429     BaseType_t xUseEntry = 0;
430 
431     pxEndPoint = &xEndPoint2;
432     ( void ) memset( &xEndPoint1, 0, sizeof( NetworkEndPoint_t ) );
433     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
434     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xGatewayIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
435     ( void ) memcpy( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
436     xNDCache[ xUseEntry ].ucValid = 1; /*Valid Cache entry needs to be skipped */
437     ( void ) memcpy( xIPAddress.ucBytes, xSiteLocalIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
438 
439     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
440 
441     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_SiteLocal );
442     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
443 
444     FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( &xEndPoint1 );
445 
446     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
447 
448     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
449 }
450 
451 /**
452  * @brief This function can't find the MAC-address of an IPv6 address when
453  *        there is a Cache miss and gateway has no entry in the cache.
454  */
test_eNDGetCacheEntry_NDCacheLookupMiss_NoEP(void)455 void test_eNDGetCacheEntry_NDCacheLookupMiss_NoEP( void )
456 {
457     MACAddress_t xMACAddress;
458     IPv6_Address_t xIPAddress;
459     NetworkEndPoint_t * pxEndPoint, xEndPoint;
460     eARPLookupResult_t eResult;
461     BaseType_t xUseEntry = 0;
462 
463     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
464     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
465     xNDCache[ xUseEntry ].ucValid = 1; /*Valid Cache entry needs to be skipped */
466     pxEndPoint = &xEndPoint;
467 
468     xIsIPv6AllowedMulticast_ExpectAnyArgsAndReturn( pdFALSE );
469 
470     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_SiteLocal );
471     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
472 
473     FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( NULL );
474 
475     eResult = eNDGetCacheEntry( &xIPAddress, &xMACAddress, &pxEndPoint );
476 
477     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
478 }
479 
480 /**
481  * @brief This function verified that the ip address was not found on ND cache
482  *        and there was no free space to store the New Entry, hence the
483  *        IP-address, MAC-address and an end-point combination was not stored.
484  */
test_vNDRefreshCacheEntry_NoMatchingEntryCacheFull(void)485 void test_vNDRefreshCacheEntry_NoMatchingEntryCacheFull( void )
486 {
487     MACAddress_t xMACAddress;
488     IPv6_Address_t xIPAddress;
489     NetworkEndPoint_t xEndPoint;
490     int i;
491 
492     ( void ) memset( xIPAddress.ucBytes, 0, ipSIZE_OF_IPv6_ADDRESS );
493     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
494 
495     /* Filling the ND cache with non matching IP/MAC combination */
496     for( i = 0; i < ipconfigND_CACHE_ENTRIES; i++ )
497     {
498         ( void ) memcpy( xNDCache[ i ].xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
499         xNDCache[ i ].ucAge = 255;
500         xNDCache[ i ].ucValid = pdTRUE;
501     }
502 
503     /* Pass a NULL IP address which will not match.*/
504     vNDRefreshCacheEntry( &xMACAddress, &xIPAddress, &xEndPoint );
505 }
506 
507 /**
508  * @brief This function verified that the ip address was not found on ND cache
509  *        and there was space to store the New Entry, hence the IP-address,
510  *        MAC-address and an end-point combination was stored in that location.
511  */
test_vNDRefreshCacheEntry_NoMatchingEntryAdd(void)512 void test_vNDRefreshCacheEntry_NoMatchingEntryAdd( void )
513 {
514     MACAddress_t xMACAddress;
515     IPv6_Address_t xIPAddress;
516     NetworkEndPoint_t xEndPoint;
517     BaseType_t xUseEntry = 0;
518 
519     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
520     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
521     ( void ) memcpy( xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
522 
523     /* Since no matching entry will be found, 0th entry will be updated to have the below details. */
524     vNDRefreshCacheEntry( &xMACAddress, &xIPAddress, &xEndPoint );
525 
526     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, ( uint8_t ) ipconfigMAX_ARP_AGE );
527     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucValid, pdTRUE );
528     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
529     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xMACAddress.ucBytes, sizeof( MACAddress_t ) );
530     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].pxEndPoint, &xEndPoint, sizeof( NetworkEndPoint_t ) );
531 }
532 
533 /**
534  * @brief This function verified that the ip address was found on ND cache
535  *        and the entry was refreshed at the same location.
536  */
test_vNDRefreshCacheEntry_MatchingEntryRefresh(void)537 void test_vNDRefreshCacheEntry_MatchingEntryRefresh( void )
538 {
539     MACAddress_t xMACAddress;
540     IPv6_Address_t xIPAddress;
541     NetworkEndPoint_t xEndPoint;
542     BaseType_t xUseEntry = 1;
543 
544     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
545     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
546     ( void ) memcpy( xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
547     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
548     xNDCache[ xUseEntry ].ucValid = pdTRUE;
549 
550     /* Since a matching entry is found at xUseEntry = 1st location, the entry will be refreshed.*/
551     vNDRefreshCacheEntry( &xMACAddress, &xIPAddress, &xEndPoint );
552 
553     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, ( uint8_t ) ipconfigMAX_ARP_AGE );
554     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xMACAddress.ucBytes, sizeof( MACAddress_t ) );
555     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].pxEndPoint, &xEndPoint, sizeof( NetworkEndPoint_t ) );
556 }
557 
558 /**
559  * @brief This function verifies all invalid cache entry condition.
560  */
test_vNDAgeCache_InvalidCache(void)561 void test_vNDAgeCache_InvalidCache( void )
562 {
563     int i;
564 
565     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
566 
567     /* Invalidate all cache entry. */
568     for( i = 0; i < ipconfigND_CACHE_ENTRIES; i++ )
569     {
570         xNDCache[ i ].ucAge = 0;
571     }
572 
573     vNDAgeCache();
574 }
575 
576 /**
577  * @brief This function wipes out the entries from ND cache
578  *        when the age reaches 0.
579  */
test_vNDAgeCache_AgeZero(void)580 void test_vNDAgeCache_AgeZero( void )
581 {
582     MACAddress_t xMACAddress;
583     IPv6_Address_t xIPAddress;
584     NetworkEndPoint_t xEndPoint;
585     BaseType_t xUseEntry = 1, i;
586 
587     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
588 
589     /* Invalidate all cache entry. */
590     for( i = 0; i < ipconfigND_CACHE_ENTRIES; i++ )
591     {
592         xNDCache[ i ].ucAge = 0;
593     }
594 
595     xNDCache[ xUseEntry ].ucAge = 1;
596     xNDCache[ xUseEntry ].ucValid = 1;
597     ( void ) memset( &xMACAddress, 0, sizeof( MACAddress_t ) );
598     ( void ) memset( &xIPAddress, 0, ipSIZE_OF_IPv6_ADDRESS );
599 
600     ( void ) memcpy( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
601     ( void ) memcpy( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
602 
603     vNDAgeCache();
604 
605     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].xIPAddress.ucBytes, xIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
606     TEST_ASSERT_EQUAL_MEMORY( xNDCache[ xUseEntry ].xMACAddress.ucBytes, xMACAddress.ucBytes, sizeof( MACAddress_t ) );
607     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, 0 );
608     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucValid, 0 );
609 }
610 
611 /**
612  * @brief This function checks the case when the entry is not yet valid,
613  *        then it is waiting an ND advertisement.
614  */
test_vNDAgeCache_InvalidEntry(void)615 void test_vNDAgeCache_InvalidEntry( void )
616 {
617     BaseType_t xUseEntry = 1;
618 
619     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
620 
621     /*Update Entry one as invalid ucValid = 0 */
622     xNDCache[ xUseEntry ].ucAge = 10;
623     xNDCache[ xUseEntry ].ucValid = 0;
624 
625     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
626 
627     vNDAgeCache();
628 }
629 
630 /**
631  * @brief This function checks the case when the entry age is
632  *        less than ndMAX_CACHE_AGE_BEFORE_NEW_ND_SOLICITATION.
633  *        This entry will get removed soon.
634  */
test_vNDAgeCache_ValidEntry(void)635 void test_vNDAgeCache_ValidEntry( void )
636 {
637     BaseType_t xUseEntry = 1;
638 
639     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
640 
641     /*Update Entry one as invalid ucValid = 0 */
642     xNDCache[ xUseEntry ].ucAge = ndMAX_CACHE_AGE_BEFORE_NEW_ND_SOLICITATION;
643     xNDCache[ xUseEntry ].ucValid = 1;
644 
645     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
646 
647     vNDAgeCache();
648 }
649 
650 /**
651  * @brief This function checks the case when The age has just ticked down,
652  *        with nothing to do.
653  */
test_vNDAgeCache_ValidEntryDecrement(void)654 void test_vNDAgeCache_ValidEntryDecrement( void )
655 {
656     MACAddress_t xMACAddress;
657     IPv6_Address_t xIPAddress;
658     NetworkEndPoint_t xEndPoint1, xEndPoint2;
659     BaseType_t xUseEntry = 1, xAgeDefault = 10;
660 
661     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
662 
663     /*Update Entry one as Valid entry */
664     xNDCache[ xUseEntry ].ucAge = xAgeDefault;
665     xNDCache[ xUseEntry ].ucValid = 1;
666 
667     vNDAgeCache();
668 
669     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, xAgeDefault - 1 );
670 }
671 
672 /**
673  * @brief This function handles Sending out an NEIGHBOR SOLICITATION request
674  *        for the IPv6 address, and fails as Endpoint is NULL.
675  */
676 
test_vNDAgeCache_NSNullEP(void)677 void test_vNDAgeCache_NSNullEP( void )
678 {
679     MACAddress_t xMACAddress;
680     IPv6_Address_t xIPAddress;
681     NetworkEndPoint_t xEndPoint, * pxEndPoint = NULL;
682     BaseType_t xUseEntry = 1, xAgeDefault = 10;
683     NetworkBufferDescriptor_t xNetworkBuffer;
684 
685     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
686 
687     /*Update Entry one as Valid entry */
688     xNDCache[ xUseEntry ].ucAge = xAgeDefault;
689     xNDCache[ xUseEntry ].ucValid = 0;
690     xNDCache[ xUseEntry ].pxEndPoint = NULL;
691 
692     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( &xNetworkBuffer );
693 
694     vNDAgeCache();
695 
696     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, xAgeDefault - 1 );
697 }
698 
699 /**
700  * @brief This function handles Sending out an NEIGHBOR SOLICITATION request
701  *        for the IPv6 address, and fails as pxDescriptor is NULL.
702  */
703 
test_vNDAgeCache_NSIncorrectDataLen(void)704 void test_vNDAgeCache_NSIncorrectDataLen( void )
705 {
706     MACAddress_t xMACAddress;
707     IPv6_Address_t xIPAddress;
708     NetworkEndPoint_t xEndPoint;
709     BaseType_t xUseEntry = 1, xAgeDefault = 10;
710     NetworkBufferDescriptor_t xNetworkBuffer;
711 
712     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
713 
714     xNetworkBuffer.xDataLength = xHeaderSize - 1;
715     /*Update Entry one as Valid entry */
716     xNDCache[ xUseEntry ].ucAge = xAgeDefault;
717     xNDCache[ xUseEntry ].ucValid = 0;
718     xNDCache[ xUseEntry ].pxEndPoint = &xEndPoint;
719     xEndPoint.bits.bIPv6 = 1;
720 
721     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( &xNetworkBuffer );
722 
723     pxDuplicateNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
724 
725     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
726 
727     vNDAgeCache();
728 
729     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, xAgeDefault - 1 );
730 }
731 
732 /**
733  * @brief This function handles Reducing the age counter in each entry within the ND cache.
734  *        Just before getting to zero, 3 times a neighbour solicitation will be sent. It also takes
735  *        care of Sending out an ND request for the IPv6 address contained in pxNetworkBuffer, and
736  *        add an entry into the ND table that indicates that an ND reply is
737  *        outstanding so re-transmissions can be generated.
738  */
739 
test_vNDAgeCache_NSHappyPath(void)740 void test_vNDAgeCache_NSHappyPath( void )
741 {
742     MACAddress_t xMACAddress;
743     IPv6_Address_t xIPAddress;
744     NetworkEndPoint_t xEndPoint;
745     BaseType_t xUseEntry = 1, xAgeDefault = 10;
746     NetworkBufferDescriptor_t xNetworkBuffer;
747     ICMPPacket_IPv6_t xICMPPacket, * pxICMPPacket = &xICMPPacket;
748     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = &( pxICMPPacket->xICMPHeaderIPv6 );
749     uint32_t ulPayloadLength = 32U;
750 
751     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
752 
753     /*Update Entry one as Valid entry */
754     xNDCache[ xUseEntry ].ucAge = xAgeDefault;
755     xNDCache[ xUseEntry ].ucValid = 0;
756     xNDCache[ xUseEntry ].pxEndPoint = &xEndPoint;
757     xEndPoint.bits.bIPv6 = 1;
758     xNetworkBuffer.xDataLength = xHeaderSize;
759     xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
760 
761     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( &xNetworkBuffer );
762     usGenerateProtocolChecksum_IgnoreAndReturn( ipCORRECT_CRC );
763     vReturnEthernetFrame_ExpectAnyArgs();
764 
765     vNDAgeCache();
766 
767     TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, xAgeDefault - 1 );
768     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucVersionTrafficClass, 0x60 );
769     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.usPayloadLength, FreeRTOS_htons( ulPayloadLength ) );
770     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucNextHeader, ipPROTOCOL_ICMP_IPv6 );
771     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucHopLimit, 255 );
772     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucTypeOfMessage, ipICMP_NEIGHBOR_SOLICITATION_IPv6 );
773     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionType, ndICMP_SOURCE_LINK_LAYER_ADDRESS );
774     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionLength, 1U ); /* times 8 bytes. */
775 }
776 
777 /**
778  * @brief Clear the Neighbour Discovery cache.
779  */
test_FreeRTOS_ClearND(void)780 void test_FreeRTOS_ClearND( void )
781 {
782     NDCacheRow_t xTempNDCache[ ipconfigND_CACHE_ENTRIES ];
783 
784     /* Set xNDCache to non zero entries*/
785     ( void ) memset( xNDCache, 1, sizeof( xNDCache ) );
786     ( void ) memset( xTempNDCache, 0, sizeof( xTempNDCache ) );
787     FreeRTOS_ClearND();
788 
789     TEST_ASSERT_EQUAL_MEMORY( xNDCache, xTempNDCache, sizeof( xNDCache ) );
790 }
791 
792 /**
793  * @brief Toggle happy path.
794  */
test_FreeRTOS_PrintNDCache(void)795 void test_FreeRTOS_PrintNDCache( void )
796 {
797     BaseType_t xUseEntry = 0;
798 
799     ( void ) memset( xNDCache, 0, sizeof( xNDCache ) );
800     /* First Entry added as a valid Cache Entry to be printed */
801     xNDCache[ xUseEntry ].ucValid = 1;
802 
803     FreeRTOS_PrintNDCache();
804 }
805 
806 /**
807  * @brief This function handles the case when vNDSendNeighbourSolicitation
808  *        fails as endpoint is NULL.
809  */
test_vNDSendNeighbourSolicitation_NULL_EP(void)810 void test_vNDSendNeighbourSolicitation_NULL_EP( void )
811 {
812     IPv6_Address_t xIPAddress;
813     NetworkBufferDescriptor_t xNetworkBuffer;
814 
815     xNetworkBuffer.pxEndPoint = NULL;
816 
817     vNDSendNeighbourSolicitation( &xNetworkBuffer, &xIPAddress );
818 }
819 
820 /**
821  * @brief This function handles the case when vNDSendNeighbourSolicitation
822  *        fails as bIPv6 is not set.
823  */
test_vNDSendNeighbourSolicitation_bIPv6_NotSet(void)824 void test_vNDSendNeighbourSolicitation_bIPv6_NotSet( void )
825 {
826     IPv6_Address_t xIPAddress;
827     NetworkEndPoint_t xEndPoint;
828     NetworkBufferDescriptor_t xNetworkBuffer;
829 
830     xEndPoint.bits.bIPv6 = pdFALSE;
831     xNetworkBuffer.pxEndPoint = &xEndPoint;
832 
833 
834     vNDSendNeighbourSolicitation( &xNetworkBuffer, &xIPAddress );
835 }
836 
837 /**
838  * @brief This function Send out an ND request for the IPv6 address contained in pxNetworkBuffer, and
839  *        add an entry into the ND table that indicates that an ND reply is
840  *        outstanding so re-transmissions can be generated.
841  */
test_vNDSendNeighbourSolicitation_HappyPath(void)842 void test_vNDSendNeighbourSolicitation_HappyPath( void )
843 {
844     IPv6_Address_t xIPAddress;
845     NetworkBufferDescriptor_t xNetworkBuffer;
846     ICMPPacket_IPv6_t xICMPPacket, * pxICMPPacket = &xICMPPacket;
847     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = &( pxICMPPacket->xICMPHeaderIPv6 );
848     NetworkEndPoint_t xEndPoint;
849     uint32_t ulPayloadLength = 32U;
850 
851     xEndPoint.bits.bIPv6 = 1;
852     xNetworkBuffer.pxEndPoint = &xEndPoint;
853     xNetworkBuffer.xDataLength = xHeaderSize;
854     xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
855     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
856 
857     usGenerateProtocolChecksum_IgnoreAndReturn( ipCORRECT_CRC );
858     vReturnEthernetFrame_ExpectAnyArgs();
859 
860     vNDSendNeighbourSolicitation( &xNetworkBuffer, &xIPAddress );
861 
862     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucVersionTrafficClass, 0x60 );
863     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.usPayloadLength, FreeRTOS_htons( ulPayloadLength ) );
864     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucNextHeader, ipPROTOCOL_ICMP_IPv6 );
865     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucHopLimit, 255 );
866     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucTypeOfMessage, ipICMP_NEIGHBOR_SOLICITATION_IPv6 );
867     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionType, ndICMP_SOURCE_LINK_LAYER_ADDRESS );
868     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionLength, 1U ); /* times 8 bytes. */
869 }
870 
871 /**
872  * @brief This function handles NULL Endpoint case
873  *        while sending a PING request which means
874  *        No endpoint found for the target IP-address.
875  */
test_SendPingRequestIPv6_NULL_EP(void)876 void test_SendPingRequestIPv6_NULL_EP( void )
877 {
878     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
879     IPv6_Address_t xIPAddress;
880     size_t uxNumberOfBytesToSend = 0;
881     BaseType_t xReturn;
882 
883     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
884 
885     pxEndPoint->bits.bIPv6 = 1;
886     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
887     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
888 
889     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
890     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Unknown );
891     FreeRTOS_NextEndPoint_ExpectAnyArgsAndReturn( NULL );
892 
893 
894     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
895 
896     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
897 }
898 
899 /**
900  * @brief This function handles case when find endpoint for
901  *        pxIPAddress fails and while getting the endpoint for the
902  *        same IP type bIPv6 is not set.
903  */
test_SendPingRequestIPv6_bIPv6_NotSet(void)904 void test_SendPingRequestIPv6_bIPv6_NotSet( void )
905 {
906     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
907     IPv6_Address_t xIPAddress;
908     size_t uxNumberOfBytesToSend = ipconfigNETWORK_MTU;
909     BaseType_t xReturn;
910 
911     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
912 
913     pxEndPoint->bits.bIPv6 = 0;
914     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
915     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
916 
917     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
918     FreeRTOS_NextEndPoint_ExpectAnyArgsAndReturn( NULL );
919 
920     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
921 
922     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
923 }
924 
925 /**
926  * @brief This function handles case when find endpoint for
927  *        pxIPAddress fails and found the endpoint for the
928  *        same IP type but there are no bytes to be send.
929  *        uxNumberOfBytesToSend is set to 0.
930  */
test_SendPingRequestIPv6_bIPv6_NoBytesToSend(void)931 void test_SendPingRequestIPv6_bIPv6_NoBytesToSend( void )
932 {
933     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
934     IPv6_Address_t xIPAddress;
935     size_t uxNumberOfBytesToSend = 0;
936     BaseType_t xReturn;
937 
938     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
939 
940     pxEndPoint->bits.bIPv6 = 1;
941     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
942     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
943 
944     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
945     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
946     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 4U );
947 
948     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
949 
950     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
951 }
952 
953 /**
954  * @brief This function handles case when uxNumberOfBytesToSend
955  *        is set to proper but there is not enough space.
956  */
test_SendPingRequestIPv6_bIPv6_NotEnoughSpace(void)957 void test_SendPingRequestIPv6_bIPv6_NotEnoughSpace( void )
958 {
959     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
960     IPv6_Address_t xIPAddress;
961     size_t uxNumberOfBytesToSend = ipconfigNETWORK_MTU;
962     BaseType_t xReturn;
963 
964     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
965 
966     pxEndPoint->bits.bIPv6 = 1;
967     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
968     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
969 
970     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
971     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
972     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 4U );
973 
974     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
975 
976     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
977 }
978 
979 /**
980  * @brief This function handles case when we do not
981  *        have enough space for the Number of bytes to be send.
982  */
test_SendPingRequestIPv6_IncorectBytesSend(void)983 void test_SendPingRequestIPv6_IncorectBytesSend( void )
984 {
985     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
986     IPv6_Address_t xIPAddress;
987     size_t uxNumberOfBytesToSend = ipconfigNETWORK_MTU;
988     BaseType_t xReturn;
989 
990     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
991 
992     pxEndPoint->bits.bIPv6 = 1;
993     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( pxEndPoint );
994 
995     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 0U );
996 
997     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
998 
999     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
1000 }
1001 
1002 /**
1003  * @brief This function handles failure case when network
1004  *        buffer returned is NULL.
1005  */
test_SendPingRequestIPv6_NULL_Buffer(void)1006 void test_SendPingRequestIPv6_NULL_Buffer( void )
1007 {
1008     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
1009     IPv6_Address_t xIPAddress;
1010     size_t uxNumberOfBytesToSend = 100;
1011     BaseType_t xReturn;
1012 
1013     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1014 
1015     pxEndPoint->bits.bIPv6 = 1;
1016     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
1017     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1018 
1019     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
1020     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1021 
1022 
1023     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 4U );
1024     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
1025 
1026 
1027     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
1028 
1029     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
1030 }
1031 
1032 /**
1033  * @brief This function handles sending and IPv6 ping request
1034  *        assert as pxEndPoint->bits.bIPv6 is not set.
1035  */
test_SendPingRequestIPv6_Assert(void)1036 void test_SendPingRequestIPv6_Assert( void )
1037 {
1038     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
1039     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1040     IPv6_Address_t xIPAddress;
1041     size_t uxNumberOfBytesToSend = 100;
1042     BaseType_t xReturn;
1043     uint16_t usSequenceNumber = 1;
1044 
1045     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1046 
1047     pxEndPoint->bits.bIPv6 = 1;
1048     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
1049     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1050 
1051     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
1052     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1053 
1054 
1055     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 4U );
1056     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( pxNetworkBuffer );
1057     xSendEventStructToIPTask_IgnoreAndReturn( pdPASS );
1058 
1059     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
1060 
1061     /*Returns ping sequence number */
1062     TEST_ASSERT_EQUAL( xReturn, usSequenceNumber );
1063 }
1064 
1065 /**
1066  * @brief This function handles sending and IPv6 ping request
1067  *        and returning the sequence number in case of success.
1068  */
test_SendPingRequestIPv6_SendToIP_Pass(void)1069 void test_SendPingRequestIPv6_SendToIP_Pass( void )
1070 {
1071     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
1072     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1073     IPv6_Address_t xIPAddress;
1074     size_t uxNumberOfBytesToSend = 100;
1075     BaseType_t xReturn;
1076     uint16_t usSequenceNumber = 1;
1077 
1078     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1079 
1080     pxEndPoint->bits.bIPv6 = 1;
1081     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
1082     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1083 
1084     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
1085     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1086 
1087 
1088     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 4U );
1089     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( pxNetworkBuffer );
1090     xSendEventStructToIPTask_IgnoreAndReturn( pdPASS );
1091 
1092     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
1093 
1094     /*Returns ping sequence number */
1095     TEST_ASSERT_EQUAL( xReturn, usSequenceNumber );
1096 }
1097 
1098 /**
1099  * @brief This function handles failure case while sending
1100  *        IPv6 ping request when sending an event to IP task fails.
1101  */
test_SendPingRequestIPv6_SendToIP_Fail(void)1102 void test_SendPingRequestIPv6_SendToIP_Fail( void )
1103 {
1104     NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
1105     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1106     IPv6_Address_t xIPAddress;
1107     size_t uxNumberOfBytesToSend = 100;
1108     BaseType_t xReturn;
1109     uint16_t usSequenceNumber = 1;
1110 
1111     ( void ) memcpy( xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1112 
1113     pxEndPoint->bits.bIPv6 = 1;
1114     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
1115     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1116 
1117     FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
1118     xIPv6_GetIPType_ExpectAnyArgsAndReturn( eIPv6_Global );
1119 
1120 
1121     uxGetNumberOfFreeNetworkBuffers_ExpectAndReturn( 4U );
1122     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( pxNetworkBuffer );
1123     xSendEventStructToIPTask_IgnoreAndReturn( pdFAIL );
1124     vReleaseNetworkBufferAndDescriptor_Ignore();
1125 
1126     xReturn = FreeRTOS_SendPingRequestIPv6( &xIPAddress, uxNumberOfBytesToSend, 0 );
1127 
1128     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
1129 }
1130 
1131 /**
1132  * @brief This function process ICMP message when endpoint is NULL.
1133  */
test_prvProcessICMPMessage_IPv6_NULL_EP(void)1134 void test_prvProcessICMPMessage_IPv6_NULL_EP( void )
1135 {
1136     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1137     ICMPPacket_IPv6_t xICMPPacket;
1138     eFrameProcessingResult_t eReturn;
1139 
1140     pxNetworkBuffer->pxEndPoint = NULL;
1141     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1142 
1143     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1144 
1145     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1146 }
1147 
1148 /**
1149  * @brief This function process ICMP message when endpoint is valid
1150  *        but the bIPv6 bit is false indicating IPv4 message.
1151  */
test_prvProcessICMPMessage_IPv6_EP(void)1152 void test_prvProcessICMPMessage_IPv6_EP( void )
1153 {
1154     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1155     ICMPPacket_IPv6_t xICMPPacket;
1156     eFrameProcessingResult_t eReturn;
1157     NetworkEndPoint_t xEndPoint;
1158 
1159     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1160     xEndPoint.bits.bIPv6 = pdFALSE_UNSIGNED;
1161     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1162 
1163     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1164 
1165     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1166 }
1167 
1168 /**
1169  * @brief This function process ICMP message when message type is
1170  *        ipICMP_DEST_UNREACHABLE_IPv6.
1171  */
test_prvProcessICMPMessage_IPv6_ipICMP_DEST_UNREACHABLE_IPv6(void)1172 void test_prvProcessICMPMessage_IPv6_ipICMP_DEST_UNREACHABLE_IPv6( void )
1173 {
1174     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1175     ICMPPacket_IPv6_t xICMPPacket;
1176     NetworkEndPoint_t xEndPoint;
1177     eFrameProcessingResult_t eReturn;
1178 
1179     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1180     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_DEST_UNREACHABLE_IPv6;
1181     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1182     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1183 
1184     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1185 
1186     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1187 }
1188 
1189 /**
1190  * @brief This function process ICMP message when message type is
1191  *        ipICMP_PACKET_TOO_BIG_IPv6.
1192  */
test_prvProcessICMPMessage_IPv6_ipICMP_PACKET_TOO_BIG_IPv6(void)1193 void test_prvProcessICMPMessage_IPv6_ipICMP_PACKET_TOO_BIG_IPv6( void )
1194 {
1195     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1196     ICMPPacket_IPv6_t xICMPPacket;
1197     NetworkEndPoint_t xEndPoint;
1198     eFrameProcessingResult_t eReturn;
1199 
1200     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1201     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PACKET_TOO_BIG_IPv6;
1202     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1203     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1204 
1205     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1206 
1207     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1208 }
1209 
1210 /**
1211  * @brief This function process ICMP message when message type is
1212  *        ipICMP_TIME_EXEEDED_IPv6.
1213  */
test_prvProcessICMPMessage_IPv6_ipICMP_TIME_EXEEDED_IPv6(void)1214 void test_prvProcessICMPMessage_IPv6_ipICMP_TIME_EXEEDED_IPv6( void )
1215 {
1216     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1217     ICMPPacket_IPv6_t xICMPPacket;
1218     NetworkEndPoint_t xEndPoint;
1219     eFrameProcessingResult_t eReturn;
1220 
1221     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1222     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_TIME_EXEEDED_IPv6;
1223     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1224     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1225 
1226     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1227 
1228     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1229 }
1230 
1231 /**
1232  * @brief This function process ICMP message when message type is
1233  *        ipICMP_PARAMETER_PROBLEM_IPv6.
1234  */
test_prvProcessICMPMessage_IPv6_ipICMP_PARAMETER_PROBLEM_IPv6(void)1235 void test_prvProcessICMPMessage_IPv6_ipICMP_PARAMETER_PROBLEM_IPv6( void )
1236 {
1237     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1238     ICMPPacket_IPv6_t xICMPPacket;
1239     NetworkEndPoint_t xEndPoint;
1240     eFrameProcessingResult_t eReturn;
1241 
1242     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1243     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PARAMETER_PROBLEM_IPv6;
1244     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1245     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1246 
1247     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1248 
1249     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1250 }
1251 
1252 /**
1253  * @brief This function process ICMP message when message type is
1254  *        ipICMP_ROUTER_SOLICITATION_IPv6.
1255  */
test_prvProcessICMPMessage_IPv6_ipICMP_ROUTER_SOLICITATION_IPv6(void)1256 void test_prvProcessICMPMessage_IPv6_ipICMP_ROUTER_SOLICITATION_IPv6( void )
1257 {
1258     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1259     ICMPPacket_IPv6_t xICMPPacket;
1260     NetworkEndPoint_t xEndPoint;
1261     eFrameProcessingResult_t eReturn;
1262 
1263     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1264     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_ROUTER_SOLICITATION_IPv6;
1265     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1266     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1267 
1268     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1269 
1270     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1271 }
1272 
1273 /**
1274  * @brief This function process ICMP message when message type is
1275  *        ipICMP_ROUTER_ADVERTISEMENT_IPv6.
1276  */
test_prvProcessICMPMessage_IPv6_ipICMP_ROUTER_ADVERTISEMENT_IPv6(void)1277 void test_prvProcessICMPMessage_IPv6_ipICMP_ROUTER_ADVERTISEMENT_IPv6( void )
1278 {
1279     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1280     ICMPPacket_IPv6_t xICMPPacket;
1281     NetworkEndPoint_t xEndPoint;
1282     eFrameProcessingResult_t eReturn;
1283 
1284     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1285     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_ROUTER_ADVERTISEMENT_IPv6;
1286     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1287     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1288 
1289     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1290 
1291     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1292 }
1293 
1294 /**
1295  * @brief This function process ICMP message when message type is
1296  *        ipICMP_PING_REQUEST_IPv6 but the data size is incorrect.
1297  */
test_prvProcessICMPMessage_IPv6_ipICMP_PING_REQUEST_IPv6_IncorrectSize(void)1298 void test_prvProcessICMPMessage_IPv6_ipICMP_PING_REQUEST_IPv6_IncorrectSize( void )
1299 {
1300     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1301     ICMPPacket_IPv6_t xICMPPacket;
1302     NetworkEndPoint_t xEndPoint;
1303     eFrameProcessingResult_t eReturn;
1304     size_t uxICMPSize, uxNeededSize;
1305     uint16_t usICMPSize;
1306 
1307     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1308     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PING_REQUEST_IPv6;
1309     xICMPPacket.xIPHeader.usPayloadLength = 100;
1310     usICMPSize = FreeRTOS_ntohs( xICMPPacket.xIPHeader.usPayloadLength );
1311     uxICMPSize = ( size_t ) usICMPSize;
1312     uxNeededSize = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxICMPSize );
1313     /* Assign less size than expected */
1314     pxNetworkBuffer->xDataLength = uxICMPSize;
1315     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1316     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1317 
1318     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1319 
1320     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1321 }
1322 
1323 /**
1324  * @brief This function process ICMP message when message type is
1325  *        ipICMP_PING_REQUEST_IPv6.
1326  */
test_prvProcessICMPMessage_IPv6_ipICMP_PING_REQUEST_IPv6_CorrectSizeAssert1(void)1327 void test_prvProcessICMPMessage_IPv6_ipICMP_PING_REQUEST_IPv6_CorrectSizeAssert1( void )
1328 {
1329     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1330     ICMPPacket_IPv6_t xICMPPacket;
1331     NetworkEndPoint_t xEndPoint;
1332     eFrameProcessingResult_t eReturn;
1333     size_t uxICMPSize, uxNeededSize;
1334     uint16_t usICMPSize;
1335 
1336     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1337     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PING_REQUEST_IPv6;
1338     xICMPPacket.xIPHeader.usPayloadLength = 100;
1339     usICMPSize = FreeRTOS_ntohs( xICMPPacket.xIPHeader.usPayloadLength );
1340     uxICMPSize = ( size_t ) usICMPSize;
1341     uxNeededSize = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxICMPSize );
1342     /* Assign less size than expected */
1343     pxNetworkBuffer->xDataLength = uxNeededSize + 1;
1344     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1345     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1346 
1347     usGenerateProtocolChecksum_IgnoreAndReturn( ipCORRECT_CRC );
1348     vReturnEthernetFrame_ExpectAnyArgs();
1349 
1350     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1351 
1352     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1353 }
1354 
1355 /**
1356  * @brief This function process ICMP message when message type is
1357  *        ipICMP_PING_REQUEST_IPv6.
1358  */
test_prvProcessICMPMessage_IPv6_ipICMP_PING_REQUEST_IPv6_CorrectSize(void)1359 void test_prvProcessICMPMessage_IPv6_ipICMP_PING_REQUEST_IPv6_CorrectSize( void )
1360 {
1361     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1362     ICMPPacket_IPv6_t xICMPPacket;
1363     NetworkEndPoint_t xEndPoint;
1364     eFrameProcessingResult_t eReturn;
1365     size_t uxICMPSize, uxNeededSize;
1366     uint16_t usICMPSize;
1367 
1368     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1369     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PING_REQUEST_IPv6;
1370     xICMPPacket.xIPHeader.usPayloadLength = 100;
1371     usICMPSize = FreeRTOS_ntohs( xICMPPacket.xIPHeader.usPayloadLength );
1372     uxICMPSize = ( size_t ) usICMPSize;
1373     uxNeededSize = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxICMPSize );
1374     /* Assign less size than expected */
1375     pxNetworkBuffer->xDataLength = uxNeededSize + 1;
1376     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1377     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1378 
1379     usGenerateProtocolChecksum_IgnoreAndReturn( ipCORRECT_CRC );
1380     vReturnEthernetFrame_ExpectAnyArgs();
1381 
1382     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1383 
1384     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1385 }
1386 
1387 /**
1388  * @brief This function process ICMP message when message type is
1389  *        ipICMP_PING_REPLY_IPv6.
1390  *        It handles case where A reply was received to an outgoing
1391  *        ping but the payload of the reply was not correct.
1392  */
test_prvProcessICMPMessage_IPv6_ipICMP_PING_REPLY_IPv6_eInvalidData(void)1393 void test_prvProcessICMPMessage_IPv6_ipICMP_PING_REPLY_IPv6_eInvalidData( void )
1394 {
1395     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1396     ICMPPacket_IPv6_t xICMPPacket;
1397     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1398     ICMPEcho_IPv6_t * pxICMPEchoHeader = ( ( ICMPEcho_IPv6_t * ) pxICMPHeader_IPv6 );
1399     NetworkEndPoint_t xEndPoint;
1400     eFrameProcessingResult_t eReturn;
1401     size_t uxICMPSize, uxNeededSize;
1402     uint16_t usICMPSize;
1403 
1404     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1405     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PING_REPLY_IPv6;
1406     xICMPPacket.xIPHeader.usPayloadLength = 100;
1407     usICMPSize = FreeRTOS_ntohs( xICMPPacket.xIPHeader.usPayloadLength );
1408     uxICMPSize = ( size_t ) usICMPSize;
1409     uxNeededSize = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxICMPSize );
1410     /* Assign less size than expected */
1411     pxNetworkBuffer->xDataLength = uxICMPSize;
1412     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1413     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1414 
1415     vApplicationPingReplyHook_Expect( eInvalidData, pxICMPEchoHeader->usIdentifier );
1416 
1417     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1418 
1419     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1420 }
1421 
1422 /**
1423  * @brief This function process ICMP message when message type is
1424  *        ipICMP_PING_REPLY_IPv6.
1425  *        It handles case where A reply was received to an outgoing
1426  *        ping but the payload of the reply was not correct.
1427  */
test_prvProcessICMPMessage_IPv6_ipICMP_PING_REPLY_IPv6_eSuccess(void)1428 void test_prvProcessICMPMessage_IPv6_ipICMP_PING_REPLY_IPv6_eSuccess( void )
1429 {
1430     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1431     ICMPPacket_IPv6_t * pxICMPPacket;
1432     ICMPHeader_IPv6_t * pxICMPHeader_IPv6;
1433     ICMPEcho_IPv6_t * pxICMPEchoHeader;
1434     uint8_t ucBuffer[ sizeof( ICMPPacket_IPv6_t ) + ipBUFFER_PADDING ], * pucByte;
1435     NetworkEndPoint_t xEndPoint;
1436     size_t uxDataLength;
1437     eFrameProcessingResult_t eReturn;
1438 
1439     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1440     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &ucBuffer;
1441     pxICMPPacket = ( ( ICMPPacket_IPv6_t * ) pxNetworkBuffer->pucEthernetBuffer );
1442     pxICMPPacket->xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_PING_REPLY_IPv6;
1443     pxICMPPacket->xIPHeader.usPayloadLength = FreeRTOS_ntohs( ipBUFFER_PADDING );
1444     pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( pxICMPPacket->xICMPHeaderIPv6 ) );
1445     pxICMPEchoHeader = ( ( ICMPEcho_IPv6_t * ) pxICMPHeader_IPv6 );
1446     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1447 
1448     uxDataLength = ipNUMERIC_CAST( size_t, FreeRTOS_ntohs( pxICMPPacket->xIPHeader.usPayloadLength ) );
1449     uxDataLength = uxDataLength - sizeof( ICMPEcho_IPv6_t );
1450 
1451     pucByte = ( ucBuffer + sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) + sizeof( ICMPEcho_IPv6_t ) );
1452 
1453     ( void ) memset( pucByte, ipECHO_DATA_FILL_BYTE, uxDataLength );
1454 
1455     vApplicationPingReplyHook_Expect( eSuccess, pxICMPEchoHeader->usIdentifier );
1456 
1457     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1458 
1459     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1460 }
1461 
1462 /**
1463  * @brief This function process ICMP message when message type is
1464  *        ipICMP_NEIGHBOR_SOLICITATION_IPv6.
1465  *        It handles case where endpoint was not found on the network.
1466  */
test_prvProcessICMPMessage_IPv6_NeighborSolicitationNullEP(void)1467 void test_prvProcessICMPMessage_IPv6_NeighborSolicitationNullEP( void )
1468 {
1469     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1470     ICMPPacket_IPv6_t xICMPPacket;
1471     NetworkEndPoint_t xEndPoint;
1472     eFrameProcessingResult_t eReturn;
1473 
1474     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1475     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_SOLICITATION_IPv6;
1476     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1477     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1478 
1479     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( NULL );
1480 
1481     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1482 
1483     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1484 }
1485 
1486 /**
1487  * @brief This function process ICMP message when message type is
1488  *        ipICMP_NEIGHBOR_SOLICITATION_IPv6.
1489  *        It handles case where when data length is less than
1490  *        expected.
1491  */
test_prvProcessICMPMessage_IPv6_NeighborSolicitationInorrectLen(void)1492 void test_prvProcessICMPMessage_IPv6_NeighborSolicitationInorrectLen( void )
1493 {
1494     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1495     ICMPPacket_IPv6_t xICMPPacket;
1496     NetworkEndPoint_t xEndPoint;
1497     eFrameProcessingResult_t eReturn;
1498 
1499     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1500     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_SOLICITATION_IPv6;
1501     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1502     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1503     pxNetworkBuffer->xDataLength = 0;
1504 
1505     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( &xEndPoint );
1506 
1507     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1508 
1509     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1510 }
1511 
1512 
1513 /**
1514  * @brief This function process ICMP message when message type is
1515  *        ipICMP_NEIGHBOR_SOLICITATION_IPv6.
1516  *        It handles case where the ICMP header address does not
1517  *        match which means the message is not for us,
1518  *        ignore it.
1519  */
test_prvProcessICMPMessage_IPv6_NeighborSolicitationCorrectLen(void)1520 void test_prvProcessICMPMessage_IPv6_NeighborSolicitationCorrectLen( void )
1521 {
1522     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1523     ICMPPacket_IPv6_t xICMPPacket;
1524     NetworkEndPoint_t xEndPoint;
1525     eFrameProcessingResult_t eReturn;
1526 
1527     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1528     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_SOLICITATION_IPv6;
1529     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1530     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1531     pxNetworkBuffer->xDataLength = xHeaderSize + ipBUFFER_PADDING;
1532 
1533     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( &xEndPoint );
1534 
1535     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1536 
1537     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1538 }
1539 
1540 /**
1541  * @brief This function process ICMP message when message type is
1542  *        ipICMP_NEIGHBOR_SOLICITATION_IPv6.
1543  */
test_prvProcessICMPMessage_IPv6_NeighborSolicitation(void)1544 void test_prvProcessICMPMessage_IPv6_NeighborSolicitation( void )
1545 {
1546     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1547     ICMPPacket_IPv6_t xICMPPacket;
1548     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1549     NetworkEndPoint_t xEndPoint;
1550     eFrameProcessingResult_t eReturn;
1551 
1552     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1553     pxICMPHeader_IPv6->ucTypeOfMessage = ipICMP_NEIGHBOR_SOLICITATION_IPv6;
1554     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1555     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1556     pxNetworkBuffer->xDataLength = xHeaderSize + ipBUFFER_PADDING;
1557     ( void ) memcpy( pxICMPHeader_IPv6->xIPv6Address.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1558     ( void ) memcpy( xEndPoint.ipv6_settings.xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1559     ( void ) memcpy( xEndPoint.xMACAddress.ucBytes, xDefaultMACAddress.ucBytes, sizeof( MACAddress_t ) );
1560 
1561     FreeRTOS_FindEndPointOnIP_IPv6_ExpectAnyArgsAndReturn( &xEndPoint );
1562 
1563     usGenerateProtocolChecksum_IgnoreAndReturn( ipCORRECT_CRC );
1564     vReturnEthernetFrame_ExpectAnyArgs();
1565 
1566     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1567 
1568     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1569     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucTypeOfMessage, ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6 );
1570     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucTypeOfService, 0U );
1571     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionType, ndICMP_TARGET_LINK_LAYER_ADDRESS );
1572     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionLength, 1U );
1573     TEST_ASSERT_EQUAL_MEMORY( pxICMPHeader_IPv6->ucOptionBytes, xEndPoint.xMACAddress.ucBytes, sizeof( MACAddress_t ) );
1574     TEST_ASSERT_EQUAL( xICMPPacket.xIPHeader.ucHopLimit, 255U );
1575 }
1576 
1577 /**
1578  * @brief This function process ICMP message when message type is
1579  *        ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6.
1580  *        It handles case when pxARPWaitingNetworkBuffer is NULL.
1581  */
test_prvProcessICMPMessage_IPv6_NeighborAdvertisement1(void)1582 void test_prvProcessICMPMessage_IPv6_NeighborAdvertisement1( void )
1583 {
1584     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1585     ICMPPacket_IPv6_t xICMPPacket;
1586     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1587     NetworkEndPoint_t xEndPoint;
1588     eFrameProcessingResult_t eReturn;
1589 
1590     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1591     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1592     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1593     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6;
1594     pxARPWaitingNetworkBuffer = NULL;
1595 
1596 
1597     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1598 
1599     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1600 }
1601 
1602 /**
1603  * @brief This function process ICMP message when message type is
1604  *        ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6.
1605  *        It handles case header is of ipSIZE_OF_IPv4_HEADER type.
1606  */
test_prvProcessICMPMessage_IPv6_NeighborAdvertisement2(void)1607 void test_prvProcessICMPMessage_IPv6_NeighborAdvertisement2( void )
1608 {
1609     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1610     ICMPPacket_IPv6_t xICMPPacket;
1611     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1612     NetworkEndPoint_t xEndPoint;
1613     eFrameProcessingResult_t eReturn;
1614     NetworkBufferDescriptor_t xARPWaitingNetworkBuffer;
1615 
1616     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1617     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1618     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1619     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6;
1620 
1621     pxARPWaitingNetworkBuffer = &xARPWaitingNetworkBuffer;
1622     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
1623 
1624     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1625 
1626     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1627 }
1628 
1629 /**
1630  * @brief This function process ICMP message when message type is
1631  *        ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6.
1632  *        This verifies a case 'pxARPWaitingNetworkBuffer' was
1633  *        not waiting for this new address look-up.
1634  */
test_prvProcessICMPMessage_IPv6_NeighborAdvertisement3(void)1635 void test_prvProcessICMPMessage_IPv6_NeighborAdvertisement3( void )
1636 {
1637     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1638     ICMPPacket_IPv6_t xICMPPacket;
1639     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1640     NetworkEndPoint_t xEndPoint;
1641     eFrameProcessingResult_t eReturn;
1642     NetworkBufferDescriptor_t xARPWaitingNetworkBuffer;
1643     IPPacket_IPv6_t xIPPacket;
1644     IPHeader_IPv6_t * pxIPHeader = &( xIPPacket.xIPHeader );
1645 
1646     pxARPWaitingNetworkBuffer = &xARPWaitingNetworkBuffer;
1647     pxARPWaitingNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xIPPacket;
1648     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1649     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1650     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1651     ( void ) memcpy( pxICMPHeader_IPv6->xIPv6Address.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1652     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6;
1653 
1654     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv6_HEADER );
1655 
1656     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1657 
1658     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1659 }
1660 
1661 /**
1662  * @brief This function process ICMP message when message type is
1663  *        ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6.
1664  *        This verifies a case where a packet is handled as a new
1665  *        incoming IP packet when a neighbour advertisement has been received,
1666  *        and 'pxARPWaitingNetworkBuffer' was waiting for this new address look-up.
1667  */
test_prvProcessICMPMessage_IPv6_NeighborAdvertisement4(void)1668 void test_prvProcessICMPMessage_IPv6_NeighborAdvertisement4( void )
1669 {
1670     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1671     ICMPPacket_IPv6_t xICMPPacket;
1672     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1673     NetworkEndPoint_t xEndPoint;
1674     eFrameProcessingResult_t eReturn;
1675     NetworkBufferDescriptor_t xARPWaitingNetworkBuffer;
1676     IPPacket_IPv6_t xIPPacket;
1677     IPHeader_IPv6_t * pxIPHeader = &( xIPPacket.xIPHeader );
1678 
1679     pxARPWaitingNetworkBuffer = &xARPWaitingNetworkBuffer;
1680     pxARPWaitingNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xIPPacket;
1681 
1682     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1683     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1684     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1685     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6;
1686     ( void ) memcpy( pxICMPHeader_IPv6->xIPv6Address.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1687     ( void ) memcpy( pxIPHeader->xSourceAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1688 
1689 
1690     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv6_HEADER );
1691     xSendEventStructToIPTask_IgnoreAndReturn( pdFAIL );
1692     vReleaseNetworkBufferAndDescriptor_Ignore();
1693     vIPSetARPResolutionTimerEnableState_ExpectAnyArgs();
1694 
1695     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1696 
1697     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1698     TEST_ASSERT_EQUAL( pxARPWaitingNetworkBuffer, NULL );
1699 }
1700 
1701 /**
1702  * @brief This function process ICMP message when message type is
1703  *        ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6.
1704  *        This verifies a case where a packet is handled as a new
1705  *        incoming IP packet when a neighbour advertisement has been received,
1706  *        and 'pxARPWaitingNetworkBuffer' was waiting for this new address look-up.
1707  */
test_prvProcessICMPMessage_IPv6_NeighborAdvertisement5(void)1708 void test_prvProcessICMPMessage_IPv6_NeighborAdvertisement5( void )
1709 {
1710     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1711     ICMPPacket_IPv6_t xICMPPacket;
1712     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( xICMPPacket.xICMPHeaderIPv6 ) );
1713     NetworkEndPoint_t xEndPoint;
1714     eFrameProcessingResult_t eReturn;
1715     NetworkBufferDescriptor_t xARPWaitingNetworkBuffer;
1716     IPPacket_IPv6_t xIPPacket;
1717     IPHeader_IPv6_t * pxIPHeader = &( xIPPacket.xIPHeader );
1718 
1719     pxARPWaitingNetworkBuffer = &xARPWaitingNetworkBuffer;
1720     pxARPWaitingNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xIPPacket;
1721 
1722     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1723     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1724     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1725     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6;
1726     ( void ) memcpy( pxICMPHeader_IPv6->xIPv6Address.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1727     ( void ) memcpy( pxIPHeader->xSourceAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1728 
1729 
1730     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv6_HEADER );
1731     xSendEventStructToIPTask_IgnoreAndReturn( pdPASS );
1732     vIPSetARPResolutionTimerEnableState_ExpectAnyArgs();
1733 
1734     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1735 
1736     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1737     TEST_ASSERT_EQUAL( pxARPWaitingNetworkBuffer, NULL );
1738 }
1739 
1740 /**
1741  * @brief This function process ICMP message when message type is incorrect.
1742  */
test_prvProcessICMPMessage_IPv6_Default(void)1743 void test_prvProcessICMPMessage_IPv6_Default( void )
1744 {
1745     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1746     ICMPPacket_IPv6_t xICMPPacket;
1747     NetworkEndPoint_t xEndPoint;
1748     eFrameProcessingResult_t eReturn;
1749 
1750     xEndPoint.bits.bIPv6 = pdTRUE_UNSIGNED;
1751     xICMPPacket.xICMPHeaderIPv6.ucTypeOfMessage = 0;
1752     pxNetworkBuffer->pxEndPoint = &xEndPoint;
1753     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1754 
1755     eReturn = prvProcessICMPMessage_IPv6( pxNetworkBuffer );
1756 
1757     TEST_ASSERT_EQUAL( eReturn, eReleaseBuffer );
1758 }
1759 
1760 /**
1761  * @brief This case validates failure in sending
1762  *        Neighbour Advertisement message because of
1763  *        failure in getting network buffer.
1764  */
test_FreeRTOS_OutputAdvertiseIPv6_Default(void)1765 void test_FreeRTOS_OutputAdvertiseIPv6_Default( void )
1766 {
1767     NetworkEndPoint_t xEndPoint;
1768 
1769     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
1770 
1771     FreeRTOS_OutputAdvertiseIPv6( &xEndPoint );
1772 }
1773 
1774 /**
1775  * @brief This case validates failure in sending
1776  *        Neighbour Advertisement message because of
1777  *        interface being NULL.
1778  */
test_FreeRTOS_OutputAdvertiseIPv6_Assert(void)1779 void test_FreeRTOS_OutputAdvertiseIPv6_Assert( void )
1780 {
1781     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1782     NetworkEndPoint_t xEndPoint;
1783 
1784     xEndPoint.pxNetworkInterface = NULL;
1785 
1786     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( pxNetworkBuffer );
1787 
1788     catch_assert( FreeRTOS_OutputAdvertiseIPv6( &xEndPoint ) );
1789 }
1790 
1791 /**
1792  * @brief This case validates sending out
1793  *        Neighbour Advertisement message.
1794  */
test_FreeRTOS_OutputAdvertiseIPv6_HappyPath(void)1795 void test_FreeRTOS_OutputAdvertiseIPv6_HappyPath( void )
1796 {
1797     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer = &xNetworkBuffer;
1798     ICMPPacket_IPv6_t xICMPPacket, * pxICMPPacket = &xICMPPacket;
1799     ICMPHeader_IPv6_t * pxICMPHeader_IPv6 = ( ( ICMPHeader_IPv6_t * ) &( pxICMPPacket->xICMPHeaderIPv6 ) );
1800     NetworkEndPoint_t xEndPoint;
1801     NetworkInterface_t xInterface;
1802 
1803     pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
1804     xEndPoint.pxNetworkInterface = &xInterface;
1805     ( void ) memcpy( xEndPoint.ipv6_settings.xIPAddress.ucBytes, xDefaultIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1806 
1807     xEndPoint.pxNetworkInterface->pfOutput = &NetworkInterfaceOutputFunction_Stub;
1808 
1809     pxICMPHeader_IPv6->usChecksum = 0U;
1810 
1811     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( pxNetworkBuffer );
1812     usGenerateProtocolChecksum_IgnoreAndReturn( ipCORRECT_CRC );
1813 
1814     FreeRTOS_OutputAdvertiseIPv6( &xEndPoint );
1815 
1816     TEST_ASSERT_EQUAL( pxICMPPacket->xEthernetHeader.usFrameType, ipIPv6_FRAME_TYPE );
1817     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.ucVersionTrafficClass, 0x60 );
1818     TEST_ASSERT_EQUAL( pxICMPPacket->xIPHeader.usPayloadLength, FreeRTOS_htons( sizeof( ICMPHeader_IPv6_t ) ) );
1819     TEST_ASSERT_EQUAL_MEMORY( pxICMPPacket->xIPHeader.xSourceAddress.ucBytes, xEndPoint.ipv6_settings.xIPAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
1820 
1821     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucTypeOfMessage, ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6 );
1822     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionType, ndICMP_TARGET_LINK_LAYER_ADDRESS );
1823     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->ucOptionLength, 1 );
1824     TEST_ASSERT_EQUAL_MEMORY( pxICMPHeader_IPv6->xIPv6Address.ucBytes, xEndPoint.ipv6_settings.xIPAddress.ucBytes, sizeof( pxICMPHeader_IPv6->xIPv6Address.ucBytes ) );
1825     TEST_ASSERT_EQUAL( pxICMPHeader_IPv6->usChecksum, 0 );
1826 }
1827 
1828 /**
1829  * @brief Create an IPv6 address, based on a prefix.
1830  *        with the bits after the prefix having random value.
1831  *        But fails to get the random number.
1832  */
test_FreeRTOS_CreateIPv6Address_RandomFail(void)1833 void test_FreeRTOS_CreateIPv6Address_RandomFail( void )
1834 {
1835     IPv6_Address_t * pxIPAddress, * pxPrefix;
1836     size_t uxPrefixLength;
1837     BaseType_t xDoRandom = pdTRUE, xReturn;
1838 
1839     xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdFALSE );
1840 
1841     xReturn = FreeRTOS_CreateIPv6Address( pxIPAddress, pxPrefix, uxPrefixLength, xDoRandom );
1842 
1843     TEST_ASSERT_EQUAL( xReturn, pdFAIL );
1844 }
1845 
1846 /**
1847  * @brief Create an IPv6 address, based on a prefix.
1848  *        with the bits after the prefix having random value
1849  *        but incorrect prefix length.
1850  */
test_FreeRTOS_CreateIPv6Address_Assert1(void)1851 void test_FreeRTOS_CreateIPv6Address_Assert1( void )
1852 {
1853     IPv6_Address_t * pxIPAddress, * pxPrefix;
1854     size_t uxPrefixLength = 0;
1855     BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;
1856 
1857     for( xIndex = 0; xIndex < 4; xIndex++ )
1858     {
1859         xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
1860     }
1861 
1862     catch_assert( FreeRTOS_CreateIPv6Address( pxIPAddress, pxPrefix, uxPrefixLength, xDoRandom ) );
1863 }
1864 
1865 /**
1866  * @brief Create an IPv6 address, based on a prefix.
1867  *        with the bits after the prefix having random value
1868  *        but incorrect prefix length and xDoRandom is 0.
1869  */
test_FreeRTOS_CreateIPv6Address_Assert2(void)1870 void test_FreeRTOS_CreateIPv6Address_Assert2( void )
1871 {
1872     IPv6_Address_t xIPAddress, xPrefix;
1873     size_t uxPrefixLength = 8U * ipSIZE_OF_IPv6_ADDRESS;
1874     BaseType_t xDoRandom = pdFALSE, xReturn, xIndex;
1875 
1876     catch_assert( FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom ) );
1877 }
1878 
1879 /**
1880  * @brief Create an IPv6 address, based on a prefix.
1881  *        with the bits after the prefix having random value.
1882  */
test_FreeRTOS_CreateIPv6Address_Pass1(void)1883 void test_FreeRTOS_CreateIPv6Address_Pass1( void )
1884 {
1885     IPv6_Address_t xIPAddress, xPrefix;
1886     size_t uxPrefixLength = 8U;
1887     BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;
1888 
1889     for( xIndex = 0; xIndex < 4; xIndex++ )
1890     {
1891         xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
1892     }
1893 
1894     xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom );
1895 
1896     TEST_ASSERT_EQUAL( xReturn, pdPASS );
1897 }
1898 
1899 /**
1900  * @brief Create an IPv6 address, based on a prefix.
1901  *        with the bits after the prefix having random value
1902  *        and uxPrefixLength is not a multiple of 8.
1903  */
test_FreeRTOS_CreateIPv6Address_Pass2(void)1904 void test_FreeRTOS_CreateIPv6Address_Pass2( void )
1905 {
1906     IPv6_Address_t xIPAddress, xPrefix;
1907     size_t uxPrefixLength = 7;
1908     BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;
1909 
1910     for( xIndex = 0; xIndex < 4; xIndex++ )
1911     {
1912         xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
1913     }
1914 
1915     xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom );
1916 
1917     TEST_ASSERT_EQUAL( xReturn, pdPASS );
1918 }
1919 
test_FreeRTOS_CreateIPv6Address_Pass3(void)1920 void test_FreeRTOS_CreateIPv6Address_Pass3( void ) /*CHECK if needed */
1921 {
1922     IPv6_Address_t xIPAddress, xPrefix;
1923     size_t uxPrefixLength = 127;
1924     BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;
1925 
1926     for( xIndex = 0; xIndex < 4; xIndex++ )
1927     {
1928         xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
1929     }
1930 
1931     xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom );
1932 
1933     TEST_ASSERT_EQUAL( xReturn, pdPASS );
1934 }
1935 
1936 /**
1937  * @brief Cover all the pcMessageType print
1938  *        scenario.
1939  */
test_pcMessageType_All(void)1940 void test_pcMessageType_All( void )
1941 {
1942     BaseType_t xType;
1943 
1944     xType = ipICMP_DEST_UNREACHABLE_IPv6;
1945     ( void ) pcMessageType( xType );
1946 
1947     xType = ipICMP_PACKET_TOO_BIG_IPv6;
1948     ( void ) pcMessageType( xType );
1949 
1950     xType = ipICMP_TIME_EXEEDED_IPv6;
1951     ( void ) pcMessageType( xType );
1952 
1953     xType = ipICMP_PARAMETER_PROBLEM_IPv6;
1954     ( void ) pcMessageType( xType );
1955 
1956     xType = ipICMP_PING_REQUEST_IPv6;
1957     ( void ) pcMessageType( xType );
1958 
1959     xType = ipICMP_PING_REPLY_IPv6;
1960     ( void ) pcMessageType( xType );
1961 
1962     xType = ipICMP_ROUTER_SOLICITATION_IPv6;
1963     ( void ) pcMessageType( xType );
1964 
1965     xType = ipICMP_ROUTER_ADVERTISEMENT_IPv6;
1966     ( void ) pcMessageType( xType );
1967 
1968     xType = ipICMP_NEIGHBOR_SOLICITATION_IPv6;
1969     ( void ) pcMessageType( xType );
1970 
1971     xType = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6;
1972     ( void ) pcMessageType( xType );
1973 
1974     xType = ipICMP_NEIGHBOR_ADVERTISEMENT_IPv6 + 1;
1975     ( void ) pcMessageType( xType );
1976 }
1977