1 /* Include Unity header */
2 #include "unity.h"
3 
4 /* Include standard libraries */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdint.h>
8 
9 #include "mock_FreeRTOS_IP.h"
10 #include "mock_FreeRTOS_IP_Timers.h"
11 #include "mock_FreeRTOS_IP_Private.h"
12 #include "mock_task.h"
13 #include "mock_NetworkBufferManagement.h"
14 
15 #include "FreeRTOS_ARP.h"
16 
17 #include "FreeRTOS_ARP_stubs.c"
18 #include "catch_assert.h"
19 
20 #include "FreeRTOSIPConfig.h"
21 
22 extern ARPCacheRow_t xARPCache[ ipconfigARP_CACHE_ENTRIES ];
23 
24 extern NetworkBufferDescriptor_t * pxARPWaitingNetworkBuffer;
25 
26 extern BaseType_t xARPHadIPClash;
27 
28 /* Helper function to reset the uxARPClashCounter variable before a test is run. It
29  * cannot be directly reset since it is declared as static. */
vResetARPClashCounter(void)30 static void vResetARPClashCounter( void )
31 {
32     ARPPacket_t xARPFrame;
33     eFrameProcessingResult_t eResult;
34 
35     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
36 
37     /* =================================================== */
38     /* Add settings required for ARP header to pass checks */
39     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
40     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
41     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
42     /* Different protocol length. */
43     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES + 1;
44 
45     /* Regardless of whether this is called or not, the test should not fail. */
46     xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
47 
48     eResult = eARPProcessPacket( &xARPFrame );
49 
50     /* Stop ignoring after the helper function is called. */
51     xTaskCheckForTimeOut_StopIgnore();
52 }
53 
test_xCheckLoopback_IncorrectFrameType(void)54 void test_xCheckLoopback_IncorrectFrameType( void )
55 {
56     NetworkBufferDescriptor_t xNetworkBuffer;
57     NetworkBufferDescriptor_t * const pxNetworkBuffer = &xNetworkBuffer;
58     uint8_t ucBuffer[ sizeof( IPPacket_t ) + ipBUFFER_PADDING ];
59     BaseType_t xResult;
60 
61     pxNetworkBuffer->pucEthernetBuffer = ucBuffer;
62     pxNetworkBuffer->xDataLength = sizeof( IPPacket_t );
63 
64     IPPacket_t * pxIPPacket = ( IPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
65 
66     /* =================================================== */
67     /* Let the frame-type be anything else than IPv4. */
68     pxIPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE + 1;
69     /* bReleaseAfterSend parameter doesn't matter here. */
70     xResult = xCheckLoopback( pxNetworkBuffer, pdFALSE );
71     TEST_ASSERT_EQUAL( pdFALSE, xResult );
72     /* =================================================== */
73 }
74 
test_xCheckLoopback_IncorrectMACAddress(void)75 void test_xCheckLoopback_IncorrectMACAddress( void )
76 {
77     NetworkBufferDescriptor_t xNetworkBuffer;
78     NetworkBufferDescriptor_t * const pxNetworkBuffer = &xNetworkBuffer;
79     uint8_t ucBuffer[ sizeof( IPPacket_t ) + ipBUFFER_PADDING ];
80     BaseType_t xResult;
81 
82     pxNetworkBuffer->pucEthernetBuffer = ucBuffer;
83     pxNetworkBuffer->xDataLength = sizeof( IPPacket_t );
84 
85     IPPacket_t * pxIPPacket = ( IPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
86 
87     /* =================================================== */
88     /* Let the frame-type be IPv4. */
89     pxIPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
90     /* But let the MAC address be different. */
91     memset( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, 0xAA, ipMAC_ADDRESS_LENGTH_BYTES );
92     /* bReleaseAfterSend parameter doesn't matter here. */
93     xResult = xCheckLoopback( pxNetworkBuffer, pdFALSE );
94     TEST_ASSERT_EQUAL( pdFALSE, xResult );
95     /* =================================================== */
96 }
97 
test_xCheckLoopback_HappyCase(void)98 void test_xCheckLoopback_HappyCase( void )
99 {
100     NetworkBufferDescriptor_t xNetworkBuffer;
101     NetworkBufferDescriptor_t * const pxNetworkBuffer = &xNetworkBuffer;
102     uint8_t ucBuffer[ sizeof( IPPacket_t ) + ipBUFFER_PADDING ];
103     BaseType_t xResult;
104 
105     pxNetworkBuffer->pucEthernetBuffer = ucBuffer;
106     pxNetworkBuffer->xDataLength = sizeof( IPPacket_t );
107 
108     IPPacket_t * pxIPPacket = ( IPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
109 
110     /* =================================================== */
111     /* Let the frame-type be IPv4. */
112     pxIPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
113     /* Make the MAC address same. */
114     memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ipLOCAL_MAC_ADDRESS, ipMAC_ADDRESS_LENGTH_BYTES );
115     pxDuplicateNetworkBufferWithDescriptor_ExpectAndReturn( pxNetworkBuffer, pxNetworkBuffer->xDataLength, pxNetworkBuffer );
116     xSendEventStructToIPTask_IgnoreAndReturn( pdTRUE );
117 
118     xResult = xCheckLoopback( pxNetworkBuffer, pdFALSE );
119     TEST_ASSERT_EQUAL( pdTRUE, xResult );
120     /* =================================================== */
121 }
122 
test_xCheckLoopback_DuplicationFails(void)123 void test_xCheckLoopback_DuplicationFails( void )
124 {
125     NetworkBufferDescriptor_t xNetworkBuffer;
126     NetworkBufferDescriptor_t * const pxNetworkBuffer = &xNetworkBuffer;
127     uint8_t ucBuffer[ sizeof( IPPacket_t ) + ipBUFFER_PADDING ];
128     BaseType_t xResult;
129 
130     pxNetworkBuffer->pucEthernetBuffer = ucBuffer;
131     pxNetworkBuffer->xDataLength = sizeof( IPPacket_t );
132 
133     IPPacket_t * pxIPPacket = ( IPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
134 
135     /* =================================================== */
136     /* Let the frame-type be IPv4. */
137     pxIPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
138     /* Make the MAC address same. */
139     memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ipLOCAL_MAC_ADDRESS, ipMAC_ADDRESS_LENGTH_BYTES );
140     /* Make buffer duplication fail. */
141     pxDuplicateNetworkBufferWithDescriptor_ExpectAndReturn( pxNetworkBuffer, pxNetworkBuffer->xDataLength, NULL );
142     xResult = xCheckLoopback( pxNetworkBuffer, pdFALSE );
143     TEST_ASSERT_EQUAL( pdTRUE, xResult );
144     /* =================================================== */
145 }
146 
147 
test_xCheckLoopback_SendEventToIPTaskFails(void)148 void test_xCheckLoopback_SendEventToIPTaskFails( void )
149 {
150     NetworkBufferDescriptor_t xNetworkBuffer;
151     NetworkBufferDescriptor_t * const pxNetworkBuffer = &xNetworkBuffer;
152     uint8_t ucBuffer[ sizeof( IPPacket_t ) + ipBUFFER_PADDING ];
153     BaseType_t xResult;
154 
155     pxNetworkBuffer->pucEthernetBuffer = ucBuffer;
156     pxNetworkBuffer->xDataLength = sizeof( IPPacket_t );
157 
158     IPPacket_t * pxIPPacket = ( IPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
159 
160 
161     /* =================================================== */
162     /* Let the frame-type be IPv4. */
163     pxIPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
164     /* Make the MAC address same. */
165     memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ipLOCAL_MAC_ADDRESS, ipMAC_ADDRESS_LENGTH_BYTES );
166 
167     xSendEventStructToIPTask_IgnoreAndReturn( pdFALSE );
168     vReleaseNetworkBufferAndDescriptor_Expect( pxNetworkBuffer );
169 
170     xResult = xCheckLoopback( pxNetworkBuffer, pdTRUE );
171     TEST_ASSERT_EQUAL( pdTRUE, xResult );
172     /* =================================================== */
173 }
174 
test_eARPProcessPacket_DifferentHardwareAddress(void)175 void test_eARPProcessPacket_DifferentHardwareAddress( void )
176 {
177     ARPPacket_t xARPFrame;
178     eFrameProcessingResult_t eResult;
179 
180     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
181 
182     /* =================================================== */
183     /* Different Hardware address. */
184     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET + 1;
185 
186     /* When the local IP address is 0, we should not process any ARP Packets. */
187     *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
188     eResult = eARPProcessPacket( &xARPFrame );
189     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
190     /* =================================================== */
191 }
192 
test_eARPProcessPacket_DifferentProtocolType(void)193 void test_eARPProcessPacket_DifferentProtocolType( void )
194 {
195     ARPPacket_t xARPFrame;
196     eFrameProcessingResult_t eResult;
197 
198     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
199 
200     /* =================================================== */
201     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
202     /* Different protocol type */
203     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE + 1;
204 
205     /* When the local IP address is 0, we should not process any ARP Packets. */
206     *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
207     eResult = eARPProcessPacket( &xARPFrame );
208     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
209     /* =================================================== */
210 }
211 
test_eARPProcessPacket_DifferentHardwareLength(void)212 void test_eARPProcessPacket_DifferentHardwareLength( void )
213 {
214     ARPPacket_t xARPFrame;
215     eFrameProcessingResult_t eResult;
216 
217     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
218 
219     /* =================================================== */
220     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
221     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
222     /* Different MAC address length. */
223     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES + 1;
224 
225     /* When the local IP address is 0, we should not process any ARP Packets. */
226     *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
227     eResult = eARPProcessPacket( &xARPFrame );
228     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
229     /* =================================================== */
230 }
231 
test_eARPProcessPacket_DifferentProtocolLength(void)232 void test_eARPProcessPacket_DifferentProtocolLength( void )
233 {
234     ARPPacket_t xARPFrame;
235     eFrameProcessingResult_t eResult;
236 
237     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
238 
239     /* =================================================== */
240     /* Add settings required for ARP header to pass checks */
241     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
242     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
243     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
244     /* Different protocol length. */
245     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES + 1;
246 
247     /* When the local IP address is 0, we should not process any ARP Packets. */
248     *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
249     eResult = eARPProcessPacket( &xARPFrame );
250     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
251     /* =================================================== */
252 }
253 
test_eARPProcessPacket_SourceMACIsBroadcast(void)254 void test_eARPProcessPacket_SourceMACIsBroadcast( void )
255 {
256     ARPPacket_t xARPFrame;
257     eFrameProcessingResult_t eResult;
258 
259     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
260 
261     /* =================================================== */
262     /* Add settings required for ARP header to pass checks */
263     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
264     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
265     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
266     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
267 
268     /* Copy the broadcast MAC address into the sender hardware address. */
269     memcpy( &( xARPFrame.xARPHeader.xSenderHardwareAddress ), &xBroadcastMACAddress, sizeof( MACAddress_t ) );
270 
271     eResult = eARPProcessPacket( &xARPFrame );
272     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
273     /* =================================================== */
274 }
275 
test_eARPProcessPacket_SourceMACIsMulticast(void)276 void test_eARPProcessPacket_SourceMACIsMulticast( void )
277 {
278     ARPPacket_t xARPFrame;
279     eFrameProcessingResult_t eResult;
280 
281     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
282 
283     /* =================================================== */
284     /* Add settings required for ARP header to pass checks */
285     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
286     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
287     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
288     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
289 
290     xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes[ 0 ] = 0x01;
291 
292     eResult = eARPProcessPacket( &xARPFrame );
293     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
294     /* =================================================== */
295 }
296 
test_eARPProcessPacket_IPIsLocalLoopBack(void)297 void test_eARPProcessPacket_IPIsLocalLoopBack( void )
298 {
299     ARPPacket_t xARPFrame;
300     eFrameProcessingResult_t eResult;
301 
302     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
303 
304     /* =================================================== */
305     /* Add settings required for ARP header to pass checks */
306     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
307     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
308     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
309     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
310 
311     uint32_t ulSenderProtocolAddress = FreeRTOS_htonl( ipFIRST_LOOPBACK_IPv4 + 10 );
312     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress,
313             &ulSenderProtocolAddress,
314             sizeof( ulSenderProtocolAddress ) );
315 
316     eResult = eARPProcessPacket( &xARPFrame );
317     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
318     /* =================================================== */
319 }
320 
test_eARPProcessPacket_SenderIPLessThanLoopBack(void)321 void test_eARPProcessPacket_SenderIPLessThanLoopBack( void )
322 {
323     ARPPacket_t xARPFrame;
324     eFrameProcessingResult_t eResult;
325 
326     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
327 
328     /* =================================================== */
329     /* Add settings required for ARP header to pass checks */
330     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
331     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
332     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
333     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
334 
335     uint32_t ulSenderProtocolAddress = FreeRTOS_htonl( ipFIRST_LOOPBACK_IPv4 - 10 );
336     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress,
337             &ulSenderProtocolAddress,
338             sizeof( ulSenderProtocolAddress ) );
339 
340     eResult = eARPProcessPacket( &xARPFrame );
341     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
342     /* =================================================== */
343 }
344 
test_eARPProcessPacket_LocalIPisZero(void)345 void test_eARPProcessPacket_LocalIPisZero( void )
346 {
347     ARPPacket_t xARPFrame;
348     eFrameProcessingResult_t eResult;
349 
350     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
351 
352     /* =================================================== */
353     /* Add settings required for ARP header to pass checks */
354     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
355     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
356     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
357     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
358 
359     /* When the local IP address is 0, we should not process any ARP Packets. */
360     *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
361     eResult = eARPProcessPacket( &xARPFrame );
362     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
363     /* =================================================== */
364 }
365 
test_eARPProcessPacket_InvalidOperation(void)366 void test_eARPProcessPacket_InvalidOperation( void )
367 {
368     ARPPacket_t xARPFrame;
369     eFrameProcessingResult_t eResult;
370 
371     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
372 
373     /* =================================================== */
374     /* Add settings required for ARP header to pass checks */
375     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
376     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
377     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
378     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
379 
380     /* What is some invalid option is sent in the ARP Packet? */
381     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
382     /* Add invalid operation */
383     xARPFrame.xARPHeader.usOperation = ipARP_REQUEST | ipARP_REPLY;
384     eResult = eARPProcessPacket( &xARPFrame );
385     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
386 }
387 
test_eARPProcessPacket_Request_DifferentIP(void)388 void test_eARPProcessPacket_Request_DifferentIP( void )
389 {
390     ARPPacket_t xARPFrame;
391     eFrameProcessingResult_t eResult;
392 
393     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
394 
395     /* Process an ARP request, but not meant for this node. */
396     /* Add settings required for ARP header to pass checks */
397     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
398     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
399     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
400     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
401 
402     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
403     /* Fill in the request option. */
404     xARPFrame.xARPHeader.usOperation = ipARP_REQUEST;
405     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER + 0x11;
406     eResult = eARPProcessPacket( &xARPFrame );
407     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
408     /* =================================================== */
409 }
410 
test_eARPProcessPacket_Request_SenderMACSameAsLocalMAC(void)411 void test_eARPProcessPacket_Request_SenderMACSameAsLocalMAC( void )
412 {
413     ARPPacket_t xARPFrame;
414     eFrameProcessingResult_t eResult;
415 
416     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
417 
418     /* Process an ARP request, but not meant for this node. */
419     /* Add settings required for ARP header to pass checks */
420     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
421     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
422     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
423     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
424 
425     memset( ipLOCAL_MAC_ADDRESS, 0x22, sizeof( MACAddress_t ) );
426     memcpy( &( xARPFrame.xARPHeader.xSenderHardwareAddress ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
427 
428     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
429     /* Fill in the request option. */
430     xARPFrame.xARPHeader.usOperation = ipARP_REQUEST;
431     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER;
432 
433     eResult = eARPProcessPacket( &xARPFrame );
434     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
435     /* =================================================== */
436 }
437 
test_eARPProcessPacket_Request_SenderAndTargetDifferent(void)438 void test_eARPProcessPacket_Request_SenderAndTargetDifferent( void )
439 {
440     ARPPacket_t xARPFrame;
441     eFrameProcessingResult_t eResult;
442 
443     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
444 
445     /* =================================================== */
446     /* Add settings required for ARP header to pass checks */
447     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
448     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
449     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
450     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
451 
452     /* Process an ARP request - meant for this node with target and source different. */
453     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
454     /* Fill in the request option. */
455     xARPFrame.xARPHeader.usOperation = ipARP_REQUEST;
456     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER;
457     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
458     /* Make sure the the destination and source IP addresses are different. */
459     xARPFrame.xARPHeader.ucSenderProtocolAddress[ 0 ]++;
460     eResult = eARPProcessPacket( &xARPFrame );
461     TEST_ASSERT_EQUAL( eReturnEthernetFrame, eResult );
462     /* =================================================== */
463 }
464 
test_eARPProcessPacket_Request_SenderAndTargetSame(void)465 void test_eARPProcessPacket_Request_SenderAndTargetSame( void )
466 {
467     ARPPacket_t xARPFrame;
468     eFrameProcessingResult_t eResult;
469 
470     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
471 
472     /* =================================================== */
473     /* Add settings required for ARP header to pass checks */
474     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
475     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
476     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
477     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
478 
479     /* Process an ARP request - meant for this node with target and source same. */
480     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
481     /* Fill in the request option. */
482     xARPFrame.xARPHeader.usOperation = ipARP_REQUEST;
483     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER;
484     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
485 
486     /* Reset the private variable uxARPClashCounter. */
487     vResetARPClashCounter();
488 
489     /* For this unit-test, we do not concern ourselves with whether the ARP request
490      * is actually sent or not. Effort is all that matters. */
491     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
492 
493     /* The value returned doesn't matter as this will determine when would the
494      * next timeout for Gratuitous ARP occur. And for this unit-test, that doesn't
495      * matter. */
496     xTaskGetTickCount_ExpectAndReturn( 100 );
497 
498     /* This function will setup the timeout which is used to limit the number of defensive
499      * ARPs. */
500     vTaskSetTimeOutState_ExpectAnyArgs();
501 
502     eResult = eARPProcessPacket( &xARPFrame );
503     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
504     /* =================================================== */
505 }
506 
test_eARPProcessPacket_Reply_TargetIPSameAsLocalIP(void)507 void test_eARPProcessPacket_Reply_TargetIPSameAsLocalIP( void )
508 {
509     ARPPacket_t xARPFrame;
510     eFrameProcessingResult_t eResult;
511 
512     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
513     memset( xARPCache, 0, sizeof( xARPCache ) );
514 
515     /* Process an ARP request, but not meant for this node. */
516     /* Add settings required for ARP header to pass checks */
517     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
518     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
519     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
520     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
521 
522     memset( ipLOCAL_MAC_ADDRESS, 0x22, sizeof( MACAddress_t ) );
523     memcpy( &( xARPFrame.xARPHeader.xSenderHardwareAddress ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
524 
525     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
526     /* Fill in the request option. */
527     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
528     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER;
529 
530     uint32_t ulSenderProtocolAddress = 0xFFAAEEBB;
531     memcpy( &( xARPFrame.xARPHeader.ucSenderProtocolAddress ), &ulSenderProtocolAddress, sizeof( uint32_t ) );
532 
533     /* Reset the private variable uxARPClashCounter. */
534     vResetARPClashCounter();
535 
536     eResult = eARPProcessPacket( &xARPFrame );
537     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
538     TEST_ASSERT_EQUAL( pdTRUE, xIsIPInARPCache( ulSenderProtocolAddress ) );
539     /* =================================================== */
540 }
541 
test_eARPProcessPacket_Reply_TargetIPNotSameAsLocalIP_ButEntryInCache(void)542 void test_eARPProcessPacket_Reply_TargetIPNotSameAsLocalIP_ButEntryInCache( void )
543 {
544     ARPPacket_t xARPFrame;
545     eFrameProcessingResult_t eResult;
546 
547     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
548     memset( xARPCache, 0, sizeof( xARPCache ) );
549 
550     /* Process an ARP request, but not meant for this node. */
551     /* Add settings required for ARP header to pass checks */
552     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
553     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
554     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
555     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
556 
557     memset( ipLOCAL_MAC_ADDRESS, 0x22, sizeof( MACAddress_t ) );
558     memcpy( &( xARPFrame.xARPHeader.xSenderHardwareAddress ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
559 
560     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
561     /* Fill in the request option. */
562     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
563     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER + 1;
564 
565     uint32_t ulSenderProtocolAddress = 0xFFAAEEBB;
566     memcpy( &( xARPFrame.xARPHeader.ucSenderProtocolAddress ), &ulSenderProtocolAddress, sizeof( uint32_t ) );
567 
568     xARPCache[ 0 ].ulIPAddress = ulSenderProtocolAddress;
569     xARPCache[ 0 ].ucAge = 1;
570     xARPCache[ 0 ].ucValid = 1;
571 
572     /* Reset the private variable uxARPClashCounter. */
573     vResetARPClashCounter();
574 
575     eResult = eARPProcessPacket( &xARPFrame );
576     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
577     TEST_ASSERT_EQUAL( pdTRUE, xIsIPInARPCache( ulSenderProtocolAddress ) );
578     TEST_ASSERT_EQUAL( ipconfigMAX_ARP_AGE, xARPCache[ 0 ].ucAge );
579     /* =================================================== */
580 }
581 
582 
test_eARPProcessPacket_Reply_SenderAndTargetSame(void)583 void test_eARPProcessPacket_Reply_SenderAndTargetSame( void )
584 {
585     ARPPacket_t xARPFrame;
586     eFrameProcessingResult_t eResult;
587 
588     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
589 
590     /* =================================================== */
591     /* Add settings required for ARP header to pass checks */
592     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
593     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
594     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
595     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
596 
597     /* Process an ARP reply - meant for this node with target and source same. */
598     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
599     /* Fill in the request option. */
600     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
601     xARPFrame.xARPHeader.ulTargetProtocolAddress = 0xAABBCCDD;
602     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
603 
604     /* Reset the private variable uxARPClashCounter. */
605     vResetARPClashCounter();
606 
607     /* For this unit-test, we do not concern ourselves with whether the ARP request
608      * is actually sent or not. Effort is all that matters. */
609     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
610 
611     /* The value returned doesn't matter as this will determine when would the
612      * next timeout for Gratuitous ARP occur. And for this unit-test, that doesn't
613      * matter. */
614     xTaskGetTickCount_ExpectAndReturn( 100 );
615 
616     /* This function will setup the timeout which is used to limit the number of defensive
617      * ARPs. */
618     vTaskSetTimeOutState_ExpectAnyArgs();
619 
620     /* Reset the flag. */
621     xARPHadIPClash = pdFALSE;
622 
623     eResult = eARPProcessPacket( &xARPFrame );
624     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
625     TEST_ASSERT_EQUAL( pdTRUE, xARPHadIPClash );
626     /* =================================================== */
627 
628     /* Reset the flag. */
629     xARPHadIPClash = pdFALSE;
630     /* Let there be no timeout. */
631     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdFAIL );
632 
633     /* Call it again and do not expect the task functions to be called. */
634     eResult = eARPProcessPacket( &xARPFrame );
635     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
636     TEST_ASSERT_EQUAL( pdTRUE, xARPHadIPClash );
637 }
638 
test_eARPProcessPacket_Reply_DifferentIP(void)639 void test_eARPProcessPacket_Reply_DifferentIP( void )
640 {
641     ARPPacket_t xARPFrame;
642     eFrameProcessingResult_t eResult;
643 
644     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
645 
646     /* =================================================== */
647     /* Add settings required for ARP header to pass checks */
648     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
649     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
650     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
651     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
652 
653     /* Process an ARP reply - not meant for this node. */
654     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
655     /* Fill in the request option. */
656     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
657     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER + 0x11;
658     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
659 
660     /* Reset the private variable uxARPClashCounter. */
661     vResetARPClashCounter();
662 
663     eResult = eARPProcessPacket( &xARPFrame );
664     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
665     /* =================================================== */
666 }
667 
test_eARPProcessPacket_Reply_DifferentIP_WaitingBufferNonNull(void)668 void test_eARPProcessPacket_Reply_DifferentIP_WaitingBufferNonNull( void )
669 {
670     ARPPacket_t xARPFrame;
671     eFrameProcessingResult_t eResult;
672     NetworkBufferDescriptor_t xLocalBuffer;
673     uint8_t pucLocalEthernetBuffer[ 1500 ];
674 
675     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
676 
677     /* Clear the buffer. */
678     memset( pucLocalEthernetBuffer, 0, sizeof( pucLocalEthernetBuffer ) );
679 
680     xLocalBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
681     pxARPWaitingNetworkBuffer = &xLocalBuffer;
682 
683     /* =================================================== */
684     /* Add settings required for ARP header to pass checks */
685     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
686     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
687     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
688     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
689 
690     /* Process an ARP reply - not meant for this node. */
691     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
692     /* Fill in the request option. */
693     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
694     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER + 0x11;
695     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
696 
697     /* Reset the private variable uxARPClashCounter. */
698     vResetARPClashCounter();
699 
700     eResult = eARPProcessPacket( &xARPFrame );
701     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
702     /* =================================================== */
703 }
704 
test_eARPProcessPacket_Reply_WaitingBufferNonNull_MatchingAddress1(void)705 void test_eARPProcessPacket_Reply_WaitingBufferNonNull_MatchingAddress1( void )
706 {
707     ARPPacket_t xARPFrame;
708     eFrameProcessingResult_t eResult;
709     NetworkBufferDescriptor_t xLocalBuffer;
710     uint8_t pucLocalEthernetBuffer[ 1500 ];
711     IPPacket_t * pxARPWaitingIPPacket = ( ( IPPacket_t * ) pucLocalEthernetBuffer );
712     IPHeader_t * pxARPWaitingIPHeader = &( pxARPWaitingIPPacket->xIPHeader );
713 
714     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
715 
716     /* Clear the buffer. */
717     memset( pucLocalEthernetBuffer, 0, sizeof( pucLocalEthernetBuffer ) );
718 
719     xLocalBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
720     pxARPWaitingNetworkBuffer = &xLocalBuffer;
721 
722     /* =================================================== */
723     /* Add settings required for ARP header to pass checks */
724     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
725     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
726     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
727     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
728 
729     /* Process an ARP reply - not meant for this node. */
730     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
731     /* Fill in the request option. */
732     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
733     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER + 0x11;
734     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
735 
736     memcpy( &( pxARPWaitingIPHeader->ulSourceIPAddress ), xARPFrame.xARPHeader.ucSenderProtocolAddress, sizeof( pxARPWaitingIPHeader->ulSourceIPAddress ) );
737 
738     /* Reset the private variable uxARPClashCounter. */
739     vResetARPClashCounter();
740 
741     xSendEventStructToIPTask_IgnoreAndReturn( pdFAIL );
742     vReleaseNetworkBufferAndDescriptor_Ignore();
743     vIPSetARPResolutionTimerEnableState_Expect( pdFALSE );
744 
745     eResult = eARPProcessPacket( &xARPFrame );
746     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
747     TEST_ASSERT_EQUAL( NULL, pxARPWaitingNetworkBuffer );
748     /* =================================================== */
749 }
750 
test_eARPProcessPacket_Reply_WaitingBufferNonNull_MatchingAddress2(void)751 void test_eARPProcessPacket_Reply_WaitingBufferNonNull_MatchingAddress2( void )
752 {
753     ARPPacket_t xARPFrame;
754     eFrameProcessingResult_t eResult;
755     NetworkBufferDescriptor_t xLocalBuffer;
756     uint8_t pucLocalEthernetBuffer[ 1500 ];
757     IPPacket_t * pxARPWaitingIPPacket = ( ( IPPacket_t * ) pucLocalEthernetBuffer );
758     IPHeader_t * pxARPWaitingIPHeader = &( pxARPWaitingIPPacket->xIPHeader );
759 
760     memset( &xARPFrame, 0, sizeof( ARPPacket_t ) );
761 
762     /* Clear the buffer. */
763     memset( pucLocalEthernetBuffer, 0, sizeof( pucLocalEthernetBuffer ) );
764 
765     xLocalBuffer.pucEthernetBuffer = pucLocalEthernetBuffer;
766     pxARPWaitingNetworkBuffer = &xLocalBuffer;
767 
768     /* =================================================== */
769     /* Add settings required for ARP header to pass checks */
770     xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET;
771     xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE;
772     xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES;
773     xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES;
774 
775     /* Process an ARP reply - not meant for this node. */
776     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCDD;
777     /* Fill in the request option. */
778     xARPFrame.xARPHeader.usOperation = ipARP_REPLY;
779     xARPFrame.xARPHeader.ulTargetProtocolAddress = *ipLOCAL_IP_ADDRESS_POINTER + 0x11;
780     memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) );
781 
782     memcpy( &( pxARPWaitingIPHeader->ulSourceIPAddress ), xARPFrame.xARPHeader.ucSenderProtocolAddress, sizeof( pxARPWaitingIPHeader->ulSourceIPAddress ) );
783 
784     /* Reset the private variable uxARPClashCounter. */
785     vResetARPClashCounter();
786 
787     xSendEventStructToIPTask_IgnoreAndReturn( pdPASS );
788     vIPSetARPResolutionTimerEnableState_Expect( pdFALSE );
789 
790     eResult = eARPProcessPacket( &xARPFrame );
791     TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
792     TEST_ASSERT_EQUAL( NULL, pxARPWaitingNetworkBuffer );
793     /* =================================================== */
794 }
795 
test_xIsIPInARPCache_NoMatchingIP(void)796 void test_xIsIPInARPCache_NoMatchingIP( void )
797 {
798     uint32_t ulIPAddress = 0x1234ABCD;
799     BaseType_t xResult;
800 
801     for( uint16_t x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
802     {
803         xARPCache[ x ].ulIPAddress = 0;
804     }
805 
806     xResult = xIsIPInARPCache( ulIPAddress );
807 
808     TEST_ASSERT_EQUAL( pdFALSE, xResult );
809 }
810 
test_xIsIPInARPCache_MatchingIPButEntryInvalid(void)811 void test_xIsIPInARPCache_MatchingIPButEntryInvalid( void )
812 {
813     uint32_t ulIPAddress = 0x1234ABCD;
814     BaseType_t xResult;
815 
816     for( uint16_t x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
817     {
818         xARPCache[ x ].ulIPAddress = 0;
819         xARPCache[ x ].ucValid = ( uint8_t ) pdFALSE;
820     }
821 
822     xARPCache[ 0 ].ulIPAddress = ulIPAddress;
823 
824     xResult = xIsIPInARPCache( ulIPAddress );
825 
826     TEST_ASSERT_EQUAL( pdFALSE, xResult );
827 }
828 
test_xIsIPInARPCache_MatchingIP1(void)829 void test_xIsIPInARPCache_MatchingIP1( void )
830 {
831     uint32_t ulIPAddress = 0x1234ABCD;
832     BaseType_t xResult;
833 
834     for( uint16_t x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
835     {
836         xARPCache[ x ].ulIPAddress = 0;
837         xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
838     }
839 
840     xARPCache[ 0 ].ulIPAddress = ulIPAddress;
841 
842     xResult = xIsIPInARPCache( ulIPAddress );
843 
844     TEST_ASSERT_EQUAL( pdTRUE, xResult );
845 }
846 
test_xIsIPInARPCache_MatchingIP2(void)847 void test_xIsIPInARPCache_MatchingIP2( void )
848 {
849     uint32_t ulIPAddress = 0x1234ABCD;
850     BaseType_t xResult;
851 
852     for( uint16_t x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
853     {
854         xARPCache[ x ].ulIPAddress = 0;
855         xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
856     }
857 
858     xARPCache[ ipconfigARP_CACHE_ENTRIES - 1 ].ulIPAddress = ulIPAddress;
859 
860     xResult = xIsIPInARPCache( ulIPAddress );
861 
862     TEST_ASSERT_EQUAL( pdTRUE, xResult );
863 }
864 
test_xCheckRequiresARPResolution_NotOnLocalNetwork(void)865 void test_xCheckRequiresARPResolution_NotOnLocalNetwork( void )
866 {
867     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer;
868     uint8_t ucEthernetBuffer[ ipconfigNETWORK_MTU ];
869     BaseType_t xResult;
870 
871     pxNetworkBuffer = &xNetworkBuffer;
872     pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer;
873 
874     IPPacket_t * pxIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
875     IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
876 
877     *ipLOCAL_IP_ADDRESS_POINTER = 0xABCD1234;
878 
879     /* Make sure there is no match. */
880     pxIPHeader->ulSourceIPAddress = ~( *ipLOCAL_IP_ADDRESS_POINTER & xNetworkAddressing.ulNetMask );
881 
882     xResult = xCheckRequiresARPResolution( pxNetworkBuffer );
883 
884     TEST_ASSERT_EQUAL( pdFALSE, xResult );
885 }
886 
test_xCheckRequiresARPResolution_OnLocalNetwork_NotInCache(void)887 void test_xCheckRequiresARPResolution_OnLocalNetwork_NotInCache( void )
888 {
889     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer;
890     uint8_t ucEthernetBuffer[ ipconfigNETWORK_MTU ];
891     BaseType_t xResult;
892 
893     pxNetworkBuffer = &xNetworkBuffer;
894     pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer;
895 
896     IPPacket_t * pxIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
897     IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
898 
899     *ipLOCAL_IP_ADDRESS_POINTER = 0xABCD1234;
900 
901     /* Make sure there is a match. */
902     pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER & xNetworkAddressing.ulNetMask;
903 
904     /* And that the IP is not in ARP cache. */
905     for( uint16_t x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
906     {
907         xARPCache[ x ].ulIPAddress = 0;
908     }
909 
910     /* We are not concerned with the ARP request actually being sent.
911      * The effort is what matters. */
912     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
913 
914     xResult = xCheckRequiresARPResolution( pxNetworkBuffer );
915 
916     TEST_ASSERT_EQUAL( pdTRUE, xResult );
917 }
918 
test_xCheckRequiresARPResolution_OnLocalNetwork_InCache(void)919 void test_xCheckRequiresARPResolution_OnLocalNetwork_InCache( void )
920 {
921     NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer;
922     uint8_t ucEthernetBuffer[ ipconfigNETWORK_MTU ];
923     BaseType_t xResult;
924 
925     pxNetworkBuffer = &xNetworkBuffer;
926     pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer;
927 
928     IPPacket_t * pxIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
929     IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
930 
931     *ipLOCAL_IP_ADDRESS_POINTER = 0xABCD1234;
932 
933     /* Make sure there is a match. */
934     pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER & xNetworkAddressing.ulNetMask;
935 
936     /* And that the IP is not in ARP cache. */
937     for( uint16_t x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
938     {
939         xARPCache[ x ].ulIPAddress = pxIPHeader->ulSourceIPAddress;
940         xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
941     }
942 
943     xResult = xCheckRequiresARPResolution( pxNetworkBuffer );
944 
945     TEST_ASSERT_EQUAL( pdFALSE, xResult );
946 }
947 
948 
test_ulARPRemoveCacheEntryByMac_NoMatch(void)949 void test_ulARPRemoveCacheEntryByMac_NoMatch( void )
950 {
951     uint32_t ulResult;
952     const MACAddress_t xMACAddress = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
953     int i;
954     BaseType_t xEntryToCheck;
955     uint8_t ucBuffer[ sizeof( xARPCache[ 0 ] ) ];
956 
957     /* Catch some asserts. */
958     catch_assert( ulARPRemoveCacheEntryByMac( NULL ) );
959 
960     /* =================================================== */
961     /* Make sure no entry matches. */
962     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
963     {
964         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
965         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x11, sizeof( xMACAddress.ucBytes ) );
966     }
967 
968     ulResult = ulARPRemoveCacheEntryByMac( &xMACAddress );
969     TEST_ASSERT_EQUAL( 0, ulResult );
970     /* =================================================== */
971 }
972 
test_ulARPRemoveCacheEntryByMac_OneMatchingEntry(void)973 void test_ulARPRemoveCacheEntryByMac_OneMatchingEntry( void )
974 {
975     uint32_t ulResult;
976     const MACAddress_t xMACAddress = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
977     int i;
978     BaseType_t xEntryToCheck;
979     uint8_t ucBuffer[ sizeof( xARPCache[ 0 ] ) ];
980 
981     /* =================================================== */
982     /* Make sure only one entry matches. */
983     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
984     {
985         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
986         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x11, sizeof( xMACAddress.ucBytes ) );
987     }
988 
989     xEntryToCheck = 1;
990     xARPCache[ xEntryToCheck ].ulIPAddress = 0xAABBCCEE;
991     memset( xARPCache[ xEntryToCheck ].xMACAddress.ucBytes, 0xAA, sizeof( xMACAddress.ucBytes ) );
992     memset( ucBuffer, 0, sizeof( xARPCache[ 0 ] ) );
993     ulResult = ulARPRemoveCacheEntryByMac( &xMACAddress );
994     TEST_ASSERT_EQUAL( 0xAABBCCEE, ulResult );
995     TEST_ASSERT_EQUAL( 0, memcmp( ucBuffer, &xARPCache[ xEntryToCheck ], sizeof( xARPCache[ 0 ] ) ) );
996 }
997 
test_vARPRefreshCacheEntry_NULLMAC_NoMatchingEntry(void)998 void test_vARPRefreshCacheEntry_NULLMAC_NoMatchingEntry( void )
999 {
1000     MACAddress_t xMACAddress;
1001     uint32_t ulIPAddress;
1002     int i;
1003     BaseType_t xUseEntry;
1004 
1005     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1006     {
1007         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1008         xARPCache[ i ].ucAge = 255;
1009         xARPCache[ i ].ucValid = pdTRUE;
1010     }
1011 
1012     ulIPAddress = 0x00;
1013     /* Pass a NULL MAC Address and an IP address which will not match. */
1014     vARPRefreshCacheEntry( NULL, ulIPAddress );
1015 
1016     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1017     TEST_ASSERT_EQUAL( xARPCache[ 0 ].ucAge, ( uint8_t ) ipconfigMAX_ARP_RETRANSMISSIONS );
1018     TEST_ASSERT_EQUAL( xARPCache[ 0 ].ucValid, ( uint8_t ) pdFALSE );
1019     /* =================================================== */
1020 }
1021 
test_vARPRefreshCacheEntry_NULLMAC_MatchingEntry(void)1022 void test_vARPRefreshCacheEntry_NULLMAC_MatchingEntry( void )
1023 {
1024     MACAddress_t xMACAddress;
1025     uint32_t ulIPAddress;
1026     int i;
1027     BaseType_t xUseEntry;
1028 
1029     /* =================================================== */
1030     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1031     {
1032         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1033         xARPCache[ i ].ucAge = 255;
1034         xARPCache[ i ].ucValid = pdTRUE;
1035     }
1036 
1037     xARPCache[ 1 ].ulIPAddress = 0xAABBCCEE;
1038 
1039     ulIPAddress = 0xAABBCCEE;
1040     /* Pass a NULL MAC Address and an IP address which will match. */
1041     vARPRefreshCacheEntry( NULL, ulIPAddress );
1042 
1043     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1044     TEST_ASSERT_EQUAL( xARPCache[ 1 ].ucAge, 255 );
1045     TEST_ASSERT_EQUAL( xARPCache[ 1 ].ucValid, ( uint8_t ) pdTRUE );
1046     /* =================================================== */
1047 }
1048 
test_vARPRefreshCacheEntry_MACWontMatch_IPWillMatch(void)1049 void test_vARPRefreshCacheEntry_MACWontMatch_IPWillMatch( void )
1050 {
1051     MACAddress_t xMACAddress;
1052     uint32_t ulIPAddress;
1053     int i;
1054     BaseType_t xUseEntry;
1055 
1056     /* =================================================== */
1057     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1058     {
1059         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1060         xARPCache[ i ].ucAge = 255;
1061         xARPCache[ i ].ucValid = pdTRUE;
1062         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x34, sizeof( xMACAddress.ucBytes ) );
1063     }
1064 
1065     xUseEntry = 1;
1066     xARPCache[ xUseEntry ].ulIPAddress = 0xAABBCCEE;
1067 
1068     ulIPAddress = 0xAABBCCEE;
1069     memset( xMACAddress.ucBytes, 0x11, ipMAC_ADDRESS_LENGTH_BYTES );
1070     /* Pass a MAC Address which won't match and an IP address which will match. */
1071     vARPRefreshCacheEntry( &xMACAddress, ulIPAddress );
1072 
1073     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1074     TEST_ASSERT_EQUAL_MESSAGE( ipconfigMAX_ARP_AGE, xARPCache[ xUseEntry ].ucAge, "Test 3" );
1075     TEST_ASSERT_EQUAL( ( uint8_t ) pdTRUE, xARPCache[ xUseEntry ].ucValid );
1076     TEST_ASSERT_EQUAL_MEMORY( xMACAddress.ucBytes, xARPCache[ xUseEntry ].xMACAddress.ucBytes, sizeof( xMACAddress.ucBytes ) );
1077     /* =================================================== */
1078 }
1079 
test_vARPRefreshCacheEntry_MACAndIPWillMatch(void)1080 void test_vARPRefreshCacheEntry_MACAndIPWillMatch( void )
1081 {
1082     MACAddress_t xMACAddress;
1083     uint32_t ulIPAddress;
1084     int i;
1085     BaseType_t xUseEntry;
1086 
1087     /* =================================================== */
1088     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1089     {
1090         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1091         xARPCache[ i ].ucAge = 255;
1092         xARPCache[ i ].ucValid = pdFALSE;
1093         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x34, sizeof( xMACAddress.ucBytes ) );
1094     }
1095 
1096     xUseEntry = 1;
1097     xARPCache[ xUseEntry ].ulIPAddress = 0xAABBCCEE;
1098     /* Set a MAC address which will match */
1099     memset( xARPCache[ xUseEntry ].xMACAddress.ucBytes, 0x11, sizeof( xMACAddress.ucBytes ) );
1100 
1101     ulIPAddress = 0xAABBCCEE;
1102     memset( xMACAddress.ucBytes, 0x11, ipMAC_ADDRESS_LENGTH_BYTES );
1103     /* Pass a MAC Address which will match and an IP address which will match too. */
1104     vARPRefreshCacheEntry( &xMACAddress, ulIPAddress );
1105 
1106     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1107     TEST_ASSERT_EQUAL_MESSAGE( ipconfigMAX_ARP_AGE, xARPCache[ xUseEntry ].ucAge, "Test 4" );
1108     TEST_ASSERT_EQUAL( ( uint8_t ) pdTRUE, xARPCache[ xUseEntry ].ucValid );
1109     TEST_ASSERT_EQUAL_MEMORY( xMACAddress.ucBytes, xARPCache[ xUseEntry ].xMACAddress.ucBytes, sizeof( xMACAddress.ucBytes ) );
1110     /* =================================================== */
1111 }
1112 
1113 
test_vARPRefreshCacheEntry_IPOnADifferentSubnet(void)1114 void test_vARPRefreshCacheEntry_IPOnADifferentSubnet( void )
1115 {
1116     MACAddress_t xMACAddress;
1117     uint32_t ulIPAddress;
1118     int i;
1119     BaseType_t xUseEntry;
1120 
1121     /* =================================================== */
1122     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1123     {
1124         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1125         xARPCache[ i ].ucAge = 255;
1126         xARPCache[ i ].ucValid = pdFALSE;
1127         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x34, sizeof( xMACAddress.ucBytes ) );
1128     }
1129 
1130     xUseEntry = 1;
1131     xARPCache[ xUseEntry ].ulIPAddress = 0xAABBCCEE;
1132     /* Set a MAC address which will match */
1133     memset( xARPCache[ xUseEntry ].xMACAddress.ucBytes, 0x11, sizeof( xMACAddress.ucBytes ) );
1134     /* Set a local IP address */
1135     *ipLOCAL_IP_ADDRESS_POINTER = 0xAABBCCEF;
1136 
1137     /* The IP address being passed should not be on the same subnet. */
1138     ulIPAddress = 0x00BBCCEE;
1139     memset( xMACAddress.ucBytes, 0x11, ipMAC_ADDRESS_LENGTH_BYTES );
1140     /* Pass a MAC Address which will match and an IP address which will match too. */
1141     vARPRefreshCacheEntry( &xMACAddress, ulIPAddress );
1142 
1143     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1144     TEST_ASSERT_EQUAL_MESSAGE( ipconfigMAX_ARP_AGE, xARPCache[ 0 ].ucAge, "Test 5" );
1145     TEST_ASSERT_EQUAL( ( uint8_t ) pdTRUE, xARPCache[ 0 ].ucValid );
1146     TEST_ASSERT_EQUAL_MEMORY( xMACAddress.ucBytes, xARPCache[ 0 ].xMACAddress.ucBytes, sizeof( xMACAddress.ucBytes ) );
1147     /* =================================================== */
1148 }
1149 
test_vARPRefreshCacheEntry_IPAndMACInDifferentLocations(void)1150 void test_vARPRefreshCacheEntry_IPAndMACInDifferentLocations( void )
1151 {
1152     MACAddress_t xMACAddress;
1153     uint32_t ulIPAddress;
1154     int i;
1155     BaseType_t xUseEntry;
1156 
1157     /* =================================================== */
1158     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1159     {
1160         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1161         xARPCache[ i ].ucAge = i + 1;
1162         xARPCache[ i ].ucValid = pdFALSE;
1163         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x34, sizeof( xMACAddress.ucBytes ) );
1164     }
1165 
1166     xUseEntry = 0;
1167 
1168     /* Make sure an entry matches. */
1169     xARPCache[ xUseEntry ].ulIPAddress = 0xAABBCCEE;
1170     ulIPAddress = 0xAABBCCEE;
1171 
1172     /* Also make sure that a MAC address matches. But a different one. */
1173     memset( xARPCache[ xUseEntry + 1 ].xMACAddress.ucBytes, 0x22, sizeof( xMACAddress.ucBytes ) );
1174     memset( xMACAddress.ucBytes, 0x22, ipMAC_ADDRESS_LENGTH_BYTES );
1175 
1176     /* Pass a MAC and IP Address which won't match, but age is now a factor. */
1177     vARPRefreshCacheEntry( &xMACAddress, ulIPAddress );
1178 
1179     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1180     TEST_ASSERT_EQUAL( xARPCache[ xUseEntry + 1 ].ulIPAddress, ulIPAddress );
1181     TEST_ASSERT_EQUAL_MESSAGE( ipconfigMAX_ARP_AGE, xARPCache[ xUseEntry + 1 ].ucAge, "Test 9" );
1182     TEST_ASSERT_EQUAL( ( uint8_t ) pdTRUE, xARPCache[ xUseEntry + 1 ].ucValid );
1183 
1184     uint8_t MemoryCompare[ sizeof( ARPCacheRow_t ) ];
1185     memset( MemoryCompare, 0, sizeof( ARPCacheRow_t ) );
1186     TEST_ASSERT_EQUAL_MEMORY( MemoryCompare, &xARPCache[ xUseEntry ], sizeof( ARPCacheRow_t ) );
1187     /* =================================================== */
1188 }
1189 
test_vARPRefreshCacheEntry_IPAndMACInDifferentLocations1(void)1190 void test_vARPRefreshCacheEntry_IPAndMACInDifferentLocations1( void )
1191 {
1192     MACAddress_t xMACAddress;
1193     uint32_t ulIPAddress;
1194     int i;
1195     BaseType_t xUseEntry;
1196 
1197     /* =================================================== */
1198     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1199     {
1200         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1201         xARPCache[ i ].ucAge = i + 1;
1202         xARPCache[ i ].ucValid = pdFALSE;
1203         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x34, sizeof( xMACAddress.ucBytes ) );
1204     }
1205 
1206     xUseEntry = 0;
1207 
1208     /* Make sure an entry matches. */
1209     xARPCache[ xUseEntry ].ulIPAddress = 0xAABBCCEA;
1210     ulIPAddress = 0xAABBCCEE;
1211 
1212     /* Also make sure that a MAC address matches. But a different one. */
1213     memset( xARPCache[ xUseEntry + 1 ].xMACAddress.ucBytes, 0x22, sizeof( xMACAddress.ucBytes ) );
1214     memset( xMACAddress.ucBytes, 0x22, ipMAC_ADDRESS_LENGTH_BYTES );
1215 
1216     /* Pass a MAC and IP Address which won't match, but age is now a factor. */
1217     vARPRefreshCacheEntry( &xMACAddress, ulIPAddress );
1218 
1219     /* Since no matching entry will be found with smallest age (i.e. oldest), 0th entry will be updated to have the below details. */
1220     TEST_ASSERT_EQUAL( xARPCache[ xUseEntry + 1 ].ulIPAddress, ulIPAddress );
1221     TEST_ASSERT_EQUAL_MESSAGE( ipconfigMAX_ARP_AGE, xARPCache[ xUseEntry + 1 ].ucAge, "Test 9" );
1222     TEST_ASSERT_EQUAL( ( uint8_t ) pdTRUE, xARPCache[ xUseEntry + 1 ].ucValid );
1223 }
1224 
test_eARPGetCacheEntryByMac_catchAssert(void)1225 void test_eARPGetCacheEntryByMac_catchAssert( void )
1226 {
1227     uint32_t ulIPAddress = 0x12345678, ulEntryToTest;
1228     eARPLookupResult_t eResult;
1229     MACAddress_t xMACAddress = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
1230     int i;
1231 
1232     /* Hit some asserts */
1233     catch_assert( eARPGetCacheEntryByMac( NULL, &ulIPAddress ) );
1234     catch_assert( eARPGetCacheEntryByMac( &xMACAddress, NULL ) );
1235 }
1236 
test_eARPGetCacheEntryByMac_NoMatchingEntries(void)1237 void test_eARPGetCacheEntryByMac_NoMatchingEntries( void )
1238 {
1239     uint32_t ulIPAddress = 0x12345678, ulEntryToTest;
1240     eARPLookupResult_t eResult;
1241     MACAddress_t xMACAddress = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
1242     int i;
1243 
1244     /* =================================================== */
1245     /* Make sure no entry matches. */
1246     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1247     {
1248         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1249         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x11, sizeof( xMACAddress.ucBytes ) );
1250     }
1251 
1252     eResult = eARPGetCacheEntryByMac( &xMACAddress, &ulIPAddress );
1253     TEST_ASSERT_EQUAL( eARPCacheMiss, eResult );
1254     TEST_ASSERT_EQUAL( 0x12345678, ulIPAddress );
1255     /* =================================================== */
1256 }
1257 
test_eARPGetCacheEntryByMac_OneMatchingEntry(void)1258 void test_eARPGetCacheEntryByMac_OneMatchingEntry( void )
1259 {
1260     uint32_t ulIPAddress = 0x12345678, ulEntryToTest;
1261     eARPLookupResult_t eResult;
1262     MACAddress_t xMACAddress = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
1263     int i;
1264 
1265     /* =================================================== */
1266     /* Make sure one entry matches. */
1267     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1268     {
1269         xARPCache[ i ].ulIPAddress = 0xAABBCCDD;
1270         memset( xARPCache[ i ].xMACAddress.ucBytes, 0x11, sizeof( xMACAddress.ucBytes ) );
1271     }
1272 
1273     ulEntryToTest = 1;
1274     memset( xARPCache[ ulEntryToTest ].xMACAddress.ucBytes, 0x22, sizeof( xMACAddress.ucBytes ) );
1275     xARPCache[ ulEntryToTest ].ulIPAddress = 0xAABBCCEE;
1276     eResult = eARPGetCacheEntryByMac( &xMACAddress, &ulIPAddress );
1277     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
1278     TEST_ASSERT_EQUAL( xARPCache[ ulEntryToTest ].ulIPAddress, ulIPAddress );
1279     /* =================================================== */
1280 }
1281 
test_eARPGetCacheEntry_CatchAssert(void)1282 void test_eARPGetCacheEntry_CatchAssert( void )
1283 {
1284     uint32_t ulIPAddress;
1285     MACAddress_t xMACAddress;
1286 
1287     catch_assert( eARPGetCacheEntry( NULL, &xMACAddress ) );
1288     catch_assert( eARPGetCacheEntry( &ulIPAddress, NULL ) );
1289 }
1290 
test_eARPGetCacheEntry_IPMatchesBroadcastAddr(void)1291 void test_eARPGetCacheEntry_IPMatchesBroadcastAddr( void )
1292 {
1293     uint32_t ulIPAddress;
1294     MACAddress_t xMACAddress;
1295     eARPLookupResult_t eResult;
1296     uint32_t ulSavedGatewayAddress;
1297 
1298     /* =================================================== */
1299     ulIPAddress = xNetworkAddressing.ulBroadcastAddress;
1300     /* Not worried about what these functions do. */
1301     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1302     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1303     TEST_ASSERT_EQUAL_MESSAGE( eARPCacheHit, eResult, "Test 3" );
1304     TEST_ASSERT_EQUAL_MEMORY_MESSAGE( &xBroadcastMACAddress, &xMACAddress, sizeof( xMACAddress ), "Test 3" );
1305     /* =================================================== */
1306 }
1307 
test_eARPGetCacheEntry_IPMatchesOtherBroadcastAddr(void)1308 void test_eARPGetCacheEntry_IPMatchesOtherBroadcastAddr( void )
1309 {
1310     uint32_t ulIPAddress;
1311     MACAddress_t xMACAddress;
1312     eARPLookupResult_t eResult;
1313     uint32_t ulSavedGatewayAddress;
1314 
1315     /* =================================================== */
1316     ulIPAddress = ipBROADCAST_IP_ADDRESS;
1317     /* Not worried about what these functions do. */
1318     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1319     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1320     TEST_ASSERT_EQUAL_MESSAGE( eARPCacheHit, eResult, "Test 3" );
1321     TEST_ASSERT_EQUAL_MEMORY_MESSAGE( &xBroadcastMACAddress, &xMACAddress, sizeof( xMACAddress ), "Test 3" );
1322     /* =================================================== */
1323 }
1324 
test_eARPGetCacheEntry_LocalIPIsZero(void)1325 void test_eARPGetCacheEntry_LocalIPIsZero( void )
1326 {
1327     uint32_t ulIPAddress;
1328     MACAddress_t xMACAddress;
1329     eARPLookupResult_t eResult;
1330     uint32_t ulSavedGatewayAddress;
1331 
1332     /* =================================================== */
1333     *ipLOCAL_IP_ADDRESS_POINTER = 0;
1334     ulIPAddress = 0x1234;
1335     /* Not worried about what these functions do. */
1336     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1337     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1338     TEST_ASSERT_EQUAL_MESSAGE( eCantSendPacket, eResult, "Test 4" );
1339     /* =================================================== */
1340 }
1341 
test_eARPGetCacheEntry_LocalIPMatchesReceivedIP(void)1342 void test_eARPGetCacheEntry_LocalIPMatchesReceivedIP( void )
1343 {
1344     uint32_t ulIPAddress;
1345     MACAddress_t xMACAddress;
1346     eARPLookupResult_t eResult;
1347     uint32_t ulSavedGatewayAddress;
1348 
1349     /* =================================================== */
1350     *ipLOCAL_IP_ADDRESS_POINTER = 0x1234;
1351     ulIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
1352     /* Not worried about what these functions do. */
1353     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1354     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1355     TEST_ASSERT_EQUAL_MESSAGE( eARPCacheHit, eResult, "Test 5" );
1356     /* =================================================== */
1357 }
1358 
test_eARPGetCacheEntry_MatchingInvalidEntry(void)1359 void test_eARPGetCacheEntry_MatchingInvalidEntry( void )
1360 {
1361     uint32_t ulIPAddress;
1362     MACAddress_t xMACAddress;
1363     eARPLookupResult_t eResult;
1364     uint32_t ulSavedGatewayAddress;
1365 
1366     /* =================================================== */
1367     ulIPAddress = 0x4321;
1368     /* Make both values (IP address and local IP pointer) different. */
1369     *ipLOCAL_IP_ADDRESS_POINTER = 0x1234;
1370     /* Add the IP address in the cache so that we'll have a cache hit. */
1371     xARPCache[ 1 ].ulIPAddress = xNetworkAddressing.ulGatewayAddress;
1372     /* But reset the valid bit. */
1373     xARPCache[ 1 ].ucValid = pdFALSE;
1374     /* Not worried about what these functions do. */
1375     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1376     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1377     TEST_ASSERT_EQUAL_MESSAGE( eCantSendPacket, eResult, "Test 6" );
1378     /* =================================================== */
1379 }
1380 
test_eARPGetCacheEntry_MatchingValidEntry(void)1381 void test_eARPGetCacheEntry_MatchingValidEntry( void )
1382 {
1383     uint32_t ulIPAddress;
1384     MACAddress_t xMACAddress;
1385     eARPLookupResult_t eResult;
1386     uint32_t ulSavedGatewayAddress;
1387 
1388     /* =================================================== */
1389     ulIPAddress = 0x4321;
1390     /* Make both values (IP address and local IP pointer) different. */
1391     *ipLOCAL_IP_ADDRESS_POINTER = 0x1234;
1392     /* Add the IP address in the cache so that we'll have a cache hit. */
1393     xARPCache[ 1 ].ulIPAddress = xNetworkAddressing.ulGatewayAddress;
1394     /* Now try with a set valid bit. */
1395     xARPCache[ 1 ].ucValid = pdTRUE;
1396     /* Not worried about what these functions do. */
1397     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1398     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1399     TEST_ASSERT_EQUAL_MESSAGE( eARPCacheHit, eResult, "Test 7" );
1400     TEST_ASSERT_EQUAL_MEMORY_MESSAGE( &xARPCache[ 1 ].xMACAddress, &xMACAddress, sizeof( xMACAddress ), "Test 7" );
1401     /* =================================================== */
1402 }
1403 
test_eARPGetCacheEntry_GatewayAddressZero(void)1404 void test_eARPGetCacheEntry_GatewayAddressZero( void )
1405 {
1406     uint32_t ulIPAddress;
1407     MACAddress_t xMACAddress;
1408     eARPLookupResult_t eResult;
1409     uint32_t ulSavedGatewayAddress;
1410 
1411     /* =================================================== */
1412     for( int i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1413     {
1414         xARPCache[ i ].ucValid = ( uint8_t ) pdFALSE;
1415     }
1416 
1417     ulSavedGatewayAddress = xNetworkAddressing.ulGatewayAddress;
1418     xNetworkAddressing.ulGatewayAddress = 0;
1419     ulIPAddress = 0x4321;
1420     /* Not worried about what these functions do. */
1421     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1422     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1423     xNetworkAddressing.ulGatewayAddress = ulSavedGatewayAddress;
1424     TEST_ASSERT_EQUAL_MESSAGE( eARPCacheMiss, eResult, "Test 9" );
1425     /* =================================================== */
1426 }
1427 
test_eARPGetCacheEntry_AddressNotOnLocalAddress(void)1428 void test_eARPGetCacheEntry_AddressNotOnLocalAddress( void )
1429 {
1430     uint32_t ulIPAddress;
1431     MACAddress_t xMACAddress;
1432     eARPLookupResult_t eResult;
1433     uint32_t ulSavedGatewayAddress;
1434 
1435     /* =================================================== */
1436     ulIPAddress = 0;
1437     /* Make both values (IP address and local IP pointer) different. */
1438     /* Get any address on the same netmask. */
1439     *ipLOCAL_IP_ADDRESS_POINTER = 0x00000034;
1440 
1441     /* Not worried about what these functions do. */
1442     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1443     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1444     TEST_ASSERT_EQUAL_MESSAGE( eCantSendPacket, eResult, "Test 11" );
1445     /* =================================================== */
1446 }
1447 
test_eARPGetCacheEntry_NoCacheHit(void)1448 void test_eARPGetCacheEntry_NoCacheHit( void )
1449 {
1450     uint32_t ulIPAddress;
1451     MACAddress_t xMACAddress;
1452     eARPLookupResult_t eResult;
1453     uint32_t ulSavedGatewayAddress;
1454 
1455     /* =================================================== */
1456     for( int i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1457     {
1458         xARPCache[ i ].ulIPAddress = 0;
1459         xARPCache[ i ].ucValid = ( uint8_t ) pdTRUE;
1460     }
1461 
1462     ulSavedGatewayAddress = xNetworkAddressing.ulGatewayAddress;
1463     xNetworkAddressing.ulGatewayAddress = 0;
1464     /* Make IP address param == 0 */
1465     ulIPAddress = 0;
1466 
1467     /* Make both values (IP address and local IP pointer) different
1468      * and on different net masks. */
1469     *ipLOCAL_IP_ADDRESS_POINTER = 0x1234;
1470     /* Not worried about what these functions do. */
1471     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1472     eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
1473     xNetworkAddressing.ulGatewayAddress = ulSavedGatewayAddress;
1474     TEST_ASSERT_EQUAL( eARPCacheHit, eResult );
1475     /* =================================================== */
1476 }
1477 
test_vARPAgeCache(void)1478 void test_vARPAgeCache( void )
1479 {
1480     /* Invalidate the first cache entry. */
1481     for( int i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1482     {
1483         xARPCache[ i ].ucAge = 0;
1484     }
1485 
1486     uint8_t ucEntryToCheck = 1;
1487 
1488     /* =================================================== */
1489     /* Let the value returned first time be 0 such that the variable is reset. */
1490     xTaskGetTickCount_ExpectAndReturn( 0 );
1491 
1492     /* The function which calls 'pxGetNetworkBufferWithDescriptor' is 'FreeRTOS_OutputARPRequest'.
1493      * It doesn't return anything and will be tested separately. */
1494     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1495 
1496     vARPAgeCache();
1497     /* =================================================== */
1498 
1499     /* =================================================== */
1500     /* Make second entry invalid but with age > 1. */
1501     xARPCache[ ucEntryToCheck ].ucAge = 1;
1502     xARPCache[ ucEntryToCheck ].ucValid = pdFALSE;
1503     /* Set an IP address */
1504     xARPCache[ ucEntryToCheck ].ulIPAddress = 0xAAAAAAAA;
1505 
1506     /* The function which calls 'pxGetNetworkBufferWithDescriptor' is 'FreeRTOS_OutputARPRequest'.
1507      * It doesn't return anything and will be tested separately. */
1508     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1509 
1510     /* Let the value returned first time be 100. */
1511     xTaskGetTickCount_ExpectAndReturn( 100 );
1512 
1513     /* The function which calls 'pxGetNetworkBufferWithDescriptor' is 'FreeRTOS_OutputARPRequest'.
1514      * It doesn't return anything and will be tested separately. */
1515     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1516 
1517     vARPAgeCache();
1518     /* =================================================== */
1519 
1520     /* =================================================== */
1521     /* Make second entry invalid but with age > 1. */
1522     xARPCache[ ucEntryToCheck ].ucAge = 1;
1523     xARPCache[ ucEntryToCheck ].ucValid = pdTRUE;
1524     /* Set an IP address */
1525     xARPCache[ ucEntryToCheck ].ulIPAddress = 0xAAAAAAAA;
1526 
1527     /* The function which calls 'pxGetNetworkBufferWithDescriptor' is 'FreeRTOS_OutputARPRequest'.
1528      * It doesn't return anything and will be tested separately. */
1529     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1530 
1531     /* Let the value returned second time be 100. */
1532     xTaskGetTickCount_ExpectAndReturn( 100 );
1533 
1534     vARPAgeCache();
1535     /* =================================================== */
1536 
1537     /* =================================================== */
1538     /* Make second entry invalid but with age > 1. */
1539     xARPCache[ ucEntryToCheck ].ucAge = 100;
1540     xARPCache[ ucEntryToCheck ].ucValid = pdTRUE;
1541     /* Set an IP address */
1542     xARPCache[ ucEntryToCheck ].ulIPAddress = 0xAAAAAAAA;
1543 
1544     /* This time the pxGetNetworkBuffer will be called. */
1545     /* Let the value returned third time be 100000. */
1546     xTaskGetTickCount_ExpectAndReturn( 100000 );
1547 
1548     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1549     vARPAgeCache();
1550     /* =================================================== */
1551 }
1552 
test_vARPSendGratuitous(void)1553 void test_vARPSendGratuitous( void )
1554 {
1555     /* The output is ignored. But we should check the input though. */
1556     xSendEventToIPTask_ExpectAndReturn( eARPTimerEvent, 0 );
1557     vARPSendGratuitous();
1558 }
1559 
test_FreeRTOS_OutputARPRequest(void)1560 void test_FreeRTOS_OutputARPRequest( void )
1561 {
1562     uint8_t ucBuffer[ sizeof( ARPPacket_t ) + ipBUFFER_PADDING + ipconfigETHERNET_MINIMUM_PACKET_BYTES ];
1563     NetworkBufferDescriptor_t xNetworkBuffer;
1564     uint32_t ulIPAddress = 0xAAAAAAAA;
1565 
1566     xNetworkBuffer.pucEthernetBuffer = ucBuffer;
1567     xNetworkBuffer.xDataLength = sizeof( ARPPacket_t );
1568 
1569     /* =================================================== */
1570     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, &xNetworkBuffer );
1571     xIsCallingFromIPTask_IgnoreAndReturn( pdTRUE );
1572     FreeRTOS_OutputARPRequest( ulIPAddress );
1573     /* =================================================== */
1574 
1575     /* =================================================== */
1576     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, &xNetworkBuffer );
1577     xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE );
1578     xSendEventStructToIPTask_IgnoreAndReturn( pdFALSE );
1579     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
1580     FreeRTOS_OutputARPRequest( ulIPAddress );
1581     /* =================================================== */
1582 
1583     /* =================================================== */
1584     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, &xNetworkBuffer );
1585     xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE );
1586     xSendEventStructToIPTask_IgnoreAndReturn( pdPASS );
1587     FreeRTOS_OutputARPRequest( ulIPAddress );
1588     /* =================================================== */
1589 }
1590 
1591 
vStoreTimeValue(TimeOut_t * const timeout,int32_t callbacks)1592 void vStoreTimeValue( TimeOut_t * const timeout,
1593                       int32_t callbacks )
1594 {
1595     timeout->xOverflowCount = 0;
1596     timeout->xTimeOnEntering = 100;
1597 }
1598 
test_xARPWaitResolution_PrivateFunctionReturnsHit(void)1599 void test_xARPWaitResolution_PrivateFunctionReturnsHit( void )
1600 {
1601     uint32_t ulIPAddress = 0xAAAAAAAA;
1602     BaseType_t xResult;
1603     int i;
1604 
1605     /* Catch the assertion for calling from IP task. */
1606     /* =================================================== */
1607     /* Assertion on calling from IP-task */
1608     xIsCallingFromIPTask_IgnoreAndReturn( pdTRUE );
1609     catch_assert( xARPWaitResolution( ulIPAddress, 0 ) );
1610     /* =================================================== */
1611 
1612 
1613     /* Make the resolution pass without any attempt by making
1614      * eARPGetCacheEntry return eARPCacheHit. */
1615     /* =================================================== */
1616     /* Assertion on calling from IP-task */
1617     xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE );
1618     /* Not worried about what these functions do. */
1619     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 1UL );
1620     vSetMultiCastIPv4MacAddress_Ignore();
1621     xResult = xARPWaitResolution( ulIPAddress, 0 );
1622     TEST_ASSERT_EQUAL( xResult, 0 );
1623     /* =================================================== */
1624 }
1625 
test_xARPWaitResolution_GNWFailsNoTimeout(void)1626 void test_xARPWaitResolution_GNWFailsNoTimeout( void )
1627 {
1628     uint32_t ulIPAddress = 0xAAAAAAAA;
1629     BaseType_t xResult;
1630     int i;
1631 
1632     /* Make the resolution fail with maximum tryouts. */
1633     /* =================================================== */
1634     /* Make sure that no address matches the IP address. */
1635     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1636     {
1637         xARPCache[ i ].ulIPAddress = 0xAAAAAAAA;
1638     }
1639 
1640     ulIPAddress = 0x00000031;
1641     /* Make both values (IP address and local IP pointer) different. */
1642     /* Get any address on the same netmask. */
1643     *ipLOCAL_IP_ADDRESS_POINTER = 0x00000034;
1644 
1645     /* Assertion on calling from IP-task */
1646     xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE );
1647     /* Not worried about what these functions do. */
1648     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1649 
1650     vTaskSetTimeOutState_Stub( vStoreTimeValue );
1651 
1652     /* Make sure that there are enough stubs for all the repetitive calls. */
1653     for( i = 0; i < ipconfigMAX_ARP_RETRANSMISSIONS; i++ )
1654     {
1655         pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1656         vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) );
1657         xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1658         xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
1659     }
1660 
1661     xResult = xARPWaitResolution( ulIPAddress, 0 );
1662     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EADDRNOTAVAIL, xResult );
1663     /* =================================================== */
1664 }
1665 
test_xARPWaitResolution(void)1666 void test_xARPWaitResolution( void )
1667 {
1668     uint32_t ulIPAddress = 0xAAAAAAAA;
1669     BaseType_t xResult;
1670     int i;
1671 
1672     /* Make the resolution fail after some attempts due to timeout. */
1673     /* =================================================== */
1674     /* Make sure that no address matches the IP address. */
1675     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1676     {
1677         xARPCache[ i ].ulIPAddress = 0xAAAAAAAA;
1678     }
1679 
1680     ulIPAddress = 0x00000031;
1681     /* Make both values (IP address and local IP pointer) different. */
1682     /* Get any address on the same netmask. */
1683     *ipLOCAL_IP_ADDRESS_POINTER = 0x00000034;
1684 
1685     /* Assertion on calling from IP-task */
1686     xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE );
1687     /* Make eARPGetCacheEntry return a cache miss. */
1688     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1689 
1690     vTaskSetTimeOutState_Stub( vStoreTimeValue );
1691 
1692     /* Make sure that there are enough stubs for all the repetitive calls. */
1693     for( i = 0; i < ( ipconfigMAX_ARP_RETRANSMISSIONS - 1 ); i++ )
1694     {
1695         pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1696         vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) );
1697         xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1698         xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
1699     }
1700 
1701     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1702     vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) );
1703     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1704     xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
1705 
1706     xResult = xARPWaitResolution( ulIPAddress, 0 );
1707     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EADDRNOTAVAIL, xResult );
1708     /* =================================================== */
1709 
1710     /* Make the resolution pass after some attempts. */
1711     /* =================================================== */
1712     /* Make sure that no address matches the IP address. */
1713     for( i = 0; i < ipconfigARP_CACHE_ENTRIES; i++ )
1714     {
1715         xARPCache[ i ].ulIPAddress = 0xAAAAAAAA;
1716     }
1717 
1718     ulIPAddress = 0x00000031;
1719     /* Make both values (IP address and local IP pointer) different. */
1720     /* Get any address on the same netmask. */
1721     *ipLOCAL_IP_ADDRESS_POINTER = 0x00000034;
1722 
1723     /* Assertion on calling from IP-task */
1724     xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE );
1725     /* Not worried about what these functions do. */
1726     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1727 
1728     vTaskSetTimeOutState_Stub( vStoreTimeValue );
1729 
1730     /* Make sure that there are enough stubs for all the repetitive calls. */
1731     for( i = 0; i < ( ipconfigMAX_ARP_RETRANSMISSIONS - 2 ); i++ )
1732     {
1733         pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1734         vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) );
1735         xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
1736         xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
1737     }
1738 
1739     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL );
1740     vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) );
1741     /* Make eARPGetCacheEntry succeed. That is - make it return eARPCacheHit */
1742     xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 1UL );
1743     vSetMultiCastIPv4MacAddress_Ignore();
1744 
1745     /* Make sure that there is no timeout. */
1746     xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
1747 
1748     xResult = xARPWaitResolution( ulIPAddress, 0 );
1749     TEST_ASSERT_EQUAL( 0, xResult );
1750     /* =================================================== */
1751 }
1752 
test_vARPGenerateRequestPacket(void)1753 void test_vARPGenerateRequestPacket( void )
1754 {
1755     NetworkBufferDescriptor_t xNetworkBuffer;
1756     NetworkBufferDescriptor_t * const pxNetworkBuffer = &xNetworkBuffer;
1757     uint8_t ucBuffer[ sizeof( ARPPacket_t ) + ipBUFFER_PADDING ];
1758 
1759     pxNetworkBuffer->pucEthernetBuffer = ucBuffer;
1760     pxNetworkBuffer->xDataLength = sizeof( ARPPacket_t );
1761 
1762     /* Catch some asserts. */
1763     catch_assert( vARPGenerateRequestPacket( NULL ) );
1764 
1765     pxNetworkBuffer->xDataLength = sizeof( ARPPacket_t ) - 10;
1766     catch_assert( vARPGenerateRequestPacket( pxNetworkBuffer ) );
1767 
1768     pxNetworkBuffer->xDataLength = sizeof( ARPPacket_t );
1769     vARPGenerateRequestPacket( pxNetworkBuffer );
1770 }
1771 
1772 
test_FreeRTOS_ClearARP(void)1773 void test_FreeRTOS_ClearARP( void )
1774 {
1775     uint8_t ucArray[ sizeof( xARPCache ) ];
1776 
1777     memset( ucArray, 0, sizeof( xARPCache ) );
1778 
1779     FreeRTOS_ClearARP();
1780     TEST_ASSERT_EQUAL_MEMORY( ucArray, xARPCache, sizeof( xARPCache ) );
1781 }
1782 
1783 
1784 
test_FreeRTOS_PrintARPCache(void)1785 void test_FreeRTOS_PrintARPCache( void )
1786 {
1787     int x;
1788 
1789     for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
1790     {
1791         /* Anything except 0. */
1792         xARPCache[ x ].ulIPAddress = 0xAA;
1793         /* Anything except 0. */
1794         xARPCache[ x ].ucAge = x;
1795     }
1796 
1797     /* Nothing to actually unit-test here. */
1798     FreeRTOS_PrintARPCache();
1799 
1800     for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
1801     {
1802         /* Anything except 0. */
1803         xARPCache[ x ].ulIPAddress = 0x00;
1804         /* Anything except 0. */
1805         xARPCache[ x ].ucAge = x;
1806     }
1807 
1808     /* Nothing to actually unit-test here. */
1809     FreeRTOS_PrintARPCache();
1810 }
1811