From a194165ce9495814f8ed23f1c75872d5e2b7977a Mon Sep 17 00:00:00 2001 From: Hein Tibosch Date: Fri, 10 Jun 2022 10:46:57 +0800 Subject: [PATCH 01/15] Let the TCP timer becomes expired in stead of active --- source/FreeRTOS_IP.c | 4 ++-- source/FreeRTOS_IP_Timers.c | 7 ++++--- source/include/FreeRTOS_IP_Timers.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/FreeRTOS_IP.c b/source/FreeRTOS_IP.c index fe5ddbf745..1e128ff6c0 100644 --- a/source/FreeRTOS_IP.c +++ b/source/FreeRTOS_IP.c @@ -429,7 +429,7 @@ static void prvProcessIPEventsAndTimers( void ) /* Simply mark the TCP timer as expired so it gets processed * the next time prvCheckNetworkTimers() is called. */ - vIPSetTCPTimerEnableState( pdTRUE ); + vIPSetTCPTimerExpiredState( pdTRUE ); #endif /* ipconfigUSE_TCP */ break; @@ -1100,7 +1100,7 @@ BaseType_t xSendEventStructToIPTask( const IPStackEvent_t * pxEvent, /* TCP timer events are sent to wake the timer task when * xTCPTimer has expired, but there is no point sending them if the * IP task is already awake processing other message. */ - vIPSetTCPTimerEnableState( pdTRUE ); + vIPSetTCPTimerExpiredState( pdTRUE ); if( uxQueueMessagesWaiting( xNetworkEventQueue ) != 0U ) { diff --git a/source/FreeRTOS_IP_Timers.c b/source/FreeRTOS_IP_Timers.c index b660bfa29e..815a8c31e3 100644 --- a/source/FreeRTOS_IP_Timers.c +++ b/source/FreeRTOS_IP_Timers.c @@ -394,15 +394,16 @@ static BaseType_t prvIPTimerCheck( IPTimer_t * pxTimer ) * * @param[in] xEnableState: pdTRUE - enable timer; pdFALSE - disable timer. */ - void vIPSetTCPTimerEnableState( BaseType_t xEnableState ) + void vIPSetTCPTimerExpiredState( BaseType_t xEnableState ) { + xTCPTimer.bActive = pdTRUE_UNSIGNED; if( xEnableState != pdFALSE ) { - xTCPTimer.bActive = pdTRUE_UNSIGNED; + xTCPTimer.bExpired = pdTRUE_UNSIGNED; } else { - xTCPTimer.bActive = pdFALSE_UNSIGNED; + xTCPTimer.bExpired = pdFALSE_UNSIGNED; } } /*-----------------------------------------------------------*/ diff --git a/source/include/FreeRTOS_IP_Timers.h b/source/include/FreeRTOS_IP_Timers.h index 004bb441ea..a2db984031 100644 --- a/source/include/FreeRTOS_IP_Timers.h +++ b/source/include/FreeRTOS_IP_Timers.h @@ -66,7 +66,7 @@ TickType_t xCalculateSleepTime( void ); void vIPTimerStartARPResolution( TickType_t xTime ); -void vIPSetTCPTimerEnableState( BaseType_t xEnableState ); +void vIPSetTCPTimerExpiredState( BaseType_t xEnableState ); void vIPSetARPTimerEnableState( BaseType_t xEnableState ); From 23b726835796944fbceb793cb802162c42e2b5c8 Mon Sep 17 00:00:00 2001 From: Hein Tibosch Date: Fri, 10 Jun 2022 11:13:26 +0800 Subject: [PATCH 02/15] Renamed parameter of function vIPSetTCPTimerExpiredState --- source/FreeRTOS_IP_Timers.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/FreeRTOS_IP_Timers.c b/source/FreeRTOS_IP_Timers.c index 81857514d2..2e2e16b925 100644 --- a/source/FreeRTOS_IP_Timers.c +++ b/source/FreeRTOS_IP_Timers.c @@ -382,18 +382,19 @@ static BaseType_t prvIPTimerCheck( IPTimer_t * pxTimer ) /** * @brief Enable/disable the TCP timer. * - * @param[in] xEnableState: pdTRUE - enable timer; pdFALSE - disable timer. + * @param[in] xExpiredState: pdTRUE - set as expired; pdFALSE - set as non-expired. */ - void vIPSetTCPTimerExpiredState( BaseType_t xEnableState ) + void vIPSetTCPTimerExpiredState( BaseType_t xExpiredState ) { xTCPTimer.bActive = pdTRUE_UNSIGNED; - if( xEnableState != pdFALSE ) + + if( xExpiredState != pdFALSE ) { - xTCPTimer.bExpired = pdTRUE_UNSIGNED; + xTCPTimer.bExpired = pdTRUE_UNSIGNED; } else { - xTCPTimer.bExpired = pdFALSE_UNSIGNED; + xTCPTimer.bExpired = pdFALSE_UNSIGNED; } } /*-----------------------------------------------------------*/ From 407d22dc491bf7cb6eb7ed75fbe3e58c22cc73be Mon Sep 17 00:00:00 2001 From: Hein Tibosch Date: Fri, 10 Jun 2022 11:25:01 +0800 Subject: [PATCH 03/15] Adapt unit tests to use the new name and field --- test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c | 8 ++++---- .../FreeRTOS_IP_Timers_utest.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c b/test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c index fb02c73ae1..43e73317d3 100644 --- a/test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c +++ b/test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c @@ -945,7 +945,7 @@ void test_prvProcessIPEventsAndTimers_eTCPTimerEvent( void ) xQueueReceive_ExpectAnyArgsAndReturn( pdTRUE ); xQueueReceive_ReturnMemThruPtr_pvBuffer( &xReceivedEvent, sizeof( xReceivedEvent ) ); - vIPSetTCPTimerEnableState_Expect( pdTRUE ); + vIPSetTCPTimerExpiredState_Expect( pdTRUE ); prvProcessIPEventsAndTimers(); } @@ -1371,7 +1371,7 @@ void test_xSendEventStructToIPTask_IPTaskInit_eTCPTimerEvent( void ) xIPTaskInitialised = pdTRUE; xEvent.eEventType = eTCPTimerEvent; - vIPSetTCPTimerEnableState_Expect( pdTRUE ); + vIPSetTCPTimerExpiredState_Expect( pdTRUE ); uxQueueMessagesWaiting_ExpectAndReturn( xNetworkEventQueue, 0 ); @@ -1393,7 +1393,7 @@ void test_xSendEventStructToIPTask_IPTaskInit_eTCPTimerEvent1( void ) xIPTaskInitialised = pdTRUE; xEvent.eEventType = eTCPTimerEvent; - vIPSetTCPTimerEnableState_Expect( pdTRUE ); + vIPSetTCPTimerExpiredState_Expect( pdTRUE ); uxQueueMessagesWaiting_ExpectAndReturn( xNetworkEventQueue, 0 ); @@ -1415,7 +1415,7 @@ void test_xSendEventStructToIPTask_IPTaskInit_eTCPTimerEvent2( void ) xIPTaskInitialised = pdTRUE; xEvent.eEventType = eTCPTimerEvent; - vIPSetTCPTimerEnableState_Expect( pdTRUE ); + vIPSetTCPTimerExpiredState_Expect( pdTRUE ); uxQueueMessagesWaiting_ExpectAndReturn( xNetworkEventQueue, 1 ); diff --git a/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c b/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c index b5e64f90be..51b3c59f02 100644 --- a/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c +++ b/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c @@ -531,22 +531,22 @@ void test_prvIPTimerCheck_TimerNotExpired1( void ) TEST_ASSERT_EQUAL( pdFALSE, xTimer.bExpired ); } -void test_vIPSetTCPTimerEnableState_False( void ) +void test_vIPSetTCPTimerExpiredState_False( void ) { - BaseType_t xEnableState = pdFALSE; + BaseType_t xExpiredState = pdFALSE; - vIPSetTCPTimerEnableState( xEnableState ); + vIPSetTCPTimerExpiredState( xExpiredState ); - TEST_ASSERT_EQUAL( xEnableState, xTCPTimer.bActive ); + TEST_ASSERT_EQUAL( xExpiredState, xTCPTimer.bExpired ); } -void test_vIPSetTCPTimerEnableState_True( void ) +void test_vIPSetTCPTimerExpiredState_True( void ) { - BaseType_t xEnableState = pdTRUE; + BaseType_t xExpiredState = pdTRUE; - vIPSetTCPTimerEnableState( xEnableState ); + vIPSetTCPTimerExpiredState( xExpiredState ); - TEST_ASSERT_EQUAL( xEnableState, xTCPTimer.bActive ); + TEST_ASSERT_EQUAL( xExpiredState, xTCPTimer.bActive ); } void test_vIPSetARPTimerEnableState_False( void ) From 8bab49e11e560abd1c0cd2daa7ae17dbdfb83cb0 Mon Sep 17 00:00:00 2001 From: Hein Tibosch Date: Fri, 10 Jun 2022 11:29:35 +0800 Subject: [PATCH 04/15] Change bActive to bExpired --- test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c b/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c index 51b3c59f02..948093707e 100644 --- a/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c +++ b/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c @@ -546,7 +546,7 @@ void test_vIPSetTCPTimerExpiredState_True( void ) vIPSetTCPTimerExpiredState( xExpiredState ); - TEST_ASSERT_EQUAL( xExpiredState, xTCPTimer.bActive ); + TEST_ASSERT_EQUAL( xExpiredState, xTCPTimer.bExpired ); } void test_vIPSetARPTimerEnableState_False( void ) From 5497db5d55f46d83aeff5c5074f5a1aa6652171c Mon Sep 17 00:00:00 2001 From: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Fri, 10 Jun 2022 10:27:16 -0700 Subject: [PATCH 05/15] Empty commit From b1b0d2bcfc17d2dc45a34c990e729ee279f7973a Mon Sep 17 00:00:00 2001 From: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Fri, 10 Jun 2022 13:26:54 -0700 Subject: [PATCH 06/15] Fix spell check --- .github/lexicon.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index d84c8aab1a..c23d181a21 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -1478,6 +1478,7 @@ xeventgroup xeventgroupwaitbits xexpected xexpectedmessagetype +xexpiredstate xflags xfound xfreebufferslist From f1d0b194855a823d17c04a46261382651ea369b1 Mon Sep 17 00:00:00 2001 From: Hein Tibosch Date: Mon, 13 Jun 2022 13:27:18 +0800 Subject: [PATCH 07/15] When a gratuitous ARP is received, use it to update the ARP cache entry --- source/FreeRTOS_ARP.c | 87 +++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index bf97707979..8b9966f8dd 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -251,43 +251,58 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame ) case ipARP_REQUEST: /* The packet contained an ARP request. Was it for the IP - * address of the node running this code? And does the MAC - * address claim that it is coming from this device itself? */ - if( ( ulTargetProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER ) && - ( memcmp( ( void * ) ipLOCAL_MAC_ADDRESS, - ( void * ) ( pxARPHeader->xSenderHardwareAddress.ucBytes ), - ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) ) + * address of the node running this code? */ + if( ulTargetProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER ) { - iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress ); - - /* The request is for the address of this node. Add the - * entry into the ARP cache, or refresh the entry if it - * already exists. */ - vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress ); - - /* Generate a reply payload in the same buffer. */ - pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY; - - ( void ) memcpy( &( pxARPHeader->xTargetHardwareAddress ), - &( pxARPHeader->xSenderHardwareAddress ), - sizeof( MACAddress_t ) ); - - pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress; - - /* - * Use helper variables for memcpy() to remain - * compliant with MISRA Rule 21.15. These should be - * optimized away. - */ - pvCopySource = ipLOCAL_MAC_ADDRESS; - pvCopyDest = pxARPHeader->xSenderHardwareAddress.ucBytes; - ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) ); - - pvCopySource = ipLOCAL_IP_ADDRESS_POINTER; - pvCopyDest = pxARPHeader->ucSenderProtocolAddress; - ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) ); - - eReturn = eReturnEthernetFrame; + /* Does the MAC address claim that it is coming + * from this device itself? */ + if( memcmp( ( void * ) ipLOCAL_MAC_ADDRESS, + ( void * ) ( pxARPHeader->xSenderHardwareAddress.ucBytes ), + ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) + { + iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress ); + + /* The request is for the address of this node. Add the + * entry into the ARP cache, or refresh the entry if it + * already exists. */ + vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress ); + + /* Generate a reply payload in the same buffer. */ + pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY; + + ( void ) memcpy( &( pxARPHeader->xTargetHardwareAddress ), + &( pxARPHeader->xSenderHardwareAddress ), + sizeof( MACAddress_t ) ); + + pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress; + + /* + * Use helper variables for memcpy() to remain + * compliant with MISRA Rule 21.15. These should be + * optimized away. + */ + pvCopySource = ipLOCAL_MAC_ADDRESS; + pvCopyDest = pxARPHeader->xSenderHardwareAddress.ucBytes; + ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) ); + + pvCopySource = ipLOCAL_IP_ADDRESS_POINTER; + pvCopyDest = pxARPHeader->ucSenderProtocolAddress; + ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) ); + + eReturn = eReturnEthernetFrame; + } + } + else if( ulSenderProtocolAddress == ulTargetProtocolAddress ) /* Gratuitous ARP request? */ + { + MACAddress_t xHardwareAddress; + + /* The request is a Gratuitous ARP message. + * Refresh the entry if it already exists. */ + /* Determine the ARP cache status for the requested IP address. */ + if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ) ) == eARPCacheHit ) + { + vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress ); + } } break; From a56e04a2dee267df9cf0b547430b37da743d73f0 Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Wed, 19 Jul 2023 15:00:30 +0530 Subject: [PATCH 08/15] wip --- source/FreeRTOS_ARP.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index 2290728b5a..c8bdeff6ed 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -290,15 +290,35 @@ eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * px { case ipARP_REQUEST: - if( ( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) && - ( memcmp( ( void * ) pxTargetEndPoint->xMACAddress.ucBytes, - ( pxARPHeader->xSenderHardwareAddress.ucBytes ), - ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) ) + if( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) { - vARPProcessPacketRequest( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); - eReturn = eReturnEthernetFrame; + if( memcmp( ( void * ) pxTargetEndPoint->xMACAddress.ucBytes, + ( pxARPHeader->xSenderHardwareAddress.ucBytes ), + ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) + { + vARPProcessPacketRequest( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); + eReturn = eReturnEthernetFrame; + } + } + else if( ulSenderProtocolAddress == ulTargetProtocolAddress ) /* Gratuitous ARP request? */ + { + MACAddress_t xHardwareAddress; + NetworkEndPoint_t * pxCachedEndPoint; + + pxCachedEndPoint = NULL; + /* The request is a Gratuitous ARP message. + * Refresh the entry if it already exists. */ + /* Determine the ARP cache status for the requested IP address. */ + if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ), &( pxCachedEndPoint )) == eARPCacheHit ) + { + if(pxCachedEndPoint == pxTargetEndPoint) + { + vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); + } + } + } break; case ipARP_REPLY: From 3902e00780c202fe9834c00ad9e47459b4710222 Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Thu, 20 Jul 2023 09:57:21 +0530 Subject: [PATCH 09/15] adding comments on matching endpoint for Gratuitous ARP --- source/FreeRTOS_ARP.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index c8bdeff6ed..167f24d1e3 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -312,7 +312,8 @@ eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * px * Refresh the entry if it already exists. */ /* Determine the ARP cache status for the requested IP address. */ if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ), &( pxCachedEndPoint )) == eARPCacheHit ) - { + { + /* Check if the endpoint matches with the one present in the ARP cache */ if(pxCachedEndPoint == pxTargetEndPoint) { vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); From b017dd7641f24f3b5e6c0611308bc8ddcfc3afd0 Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Thu, 20 Jul 2023 09:57:48 +0530 Subject: [PATCH 10/15] adding unit tests for Gratuitous ARP processing, fix formatting --- source/FreeRTOS_ARP.c | 14 +- .../FreeRTOS_ARP/FreeRTOS_ARP_utest.c | 230 ++++++++++++++++++ 2 files changed, 237 insertions(+), 7 deletions(-) mode change 100755 => 100644 test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index 167f24d1e3..25e17f9cea 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -293,13 +293,12 @@ eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * px if( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) { if( memcmp( ( void * ) pxTargetEndPoint->xMACAddress.ucBytes, - ( pxARPHeader->xSenderHardwareAddress.ucBytes ), - ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) + ( pxARPHeader->xSenderHardwareAddress.ucBytes ), + ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) { vARPProcessPacketRequest( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); eReturn = eReturnEthernetFrame; } - } else if( ulSenderProtocolAddress == ulTargetProtocolAddress ) /* Gratuitous ARP request? */ { @@ -309,17 +308,18 @@ eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * px pxCachedEndPoint = NULL; /* The request is a Gratuitous ARP message. - * Refresh the entry if it already exists. */ + * Refresh the entry if it already exists. */ /* Determine the ARP cache status for the requested IP address. */ - if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ), &( pxCachedEndPoint )) == eARPCacheHit ) - { + if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ), &( pxCachedEndPoint ) ) == eARPCacheHit ) + { /* Check if the endpoint matches with the one present in the ARP cache */ - if(pxCachedEndPoint == pxTargetEndPoint) + if( pxCachedEndPoint == pxTargetEndPoint ) { vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); } } } + break; case ipARP_REPLY: diff --git a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c old mode 100755 new mode 100644 index cf1bcaf643..1b20d8c5d1 --- a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c +++ b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c @@ -696,6 +696,236 @@ void test_eARPProcessPacket_Request_SenderAndTargetSame( void ) /* =================================================== */ } +void test_eARPProcessPacket_Request_GratuitousARP( void ) +{ + ARPPacket_t xARPFrame = { 0 }; + eFrameProcessingResult_t eResult; + NetworkInterface_t xInterface; + struct xNetworkEndPoint xEndPoint = { 0 }; + NetworkBufferDescriptor_t xNetworkBuffer = { 0 }; + uint32_t ulTargetIP = 0xAACCDDBB; + + memset( &xARPFrame, 0, sizeof( ARPPacket_t ) ); + memset( xARPCache, 0, sizeof( xARPCache ) ); + + /* =================================================== */ + /* Add settings required for ARP header to pass checks */ + xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET; + xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE; + xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES; + xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES; + + /* Process an ARP request - meant for this node with target and source same. */ + xEndPoint.ipv4_settings.ulIPAddress = 0xAABBCCDD; + /* Fill in the request option. */ + xARPFrame.xARPHeader.usOperation = ipARP_REQUEST; + xARPFrame.xARPHeader.ulTargetProtocolAddress = ulTargetIP; + memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) ); + + memset( &( xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes ), 0x22, sizeof( MACAddress_t ) ); + + xARPCache[ 0 ].ulIPAddress = ulTargetIP; + xARPCache[ 0 ].ucAge = 1; + xARPCache[ 0 ].ucValid = pdTRUE; + memset( xARPCache[ 0 ].xMACAddress.ucBytes, 0x34, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + xARPCache[ 0 ].pxEndPoint = &xEndPoint; + + /* Reset the private variable uxARPClashCounter. */ + vResetARPClashCounter(); + + FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); + xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + + xNetworkBuffer.pucEthernetBuffer = &xARPFrame; + xNetworkBuffer.xDataLength = sizeof( ARPPacket_t ); + xNetworkBuffer.pxEndPoint = &xEndPoint; + xEndPoint.bits.bEndPointUp = pdTRUE_UNSIGNED; + + eResult = eARPProcessPacket( &xNetworkBuffer ); + TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); + TEST_ASSERT_EQUAL( ulTargetIP, xARPCache[ 0 ].ulIPAddress ); + TEST_ASSERT_EQUAL( ipconfigMAX_ARP_AGE, xARPCache[ 0 ].ucAge ); + TEST_ASSERT_EQUAL( pdTRUE, xARPCache[ 0 ].ucValid ); + TEST_ASSERT_EQUAL( &xEndPoint, xARPCache[ 0 ].pxEndPoint ); + TEST_ASSERT_EQUAL_MEMORY( &( xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes ), xARPCache[ 0 ].xMACAddress.ucBytes, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + /* =================================================== */ +} + +void test_eARPProcessPacket_Request_GratuitousARP_MACUnchanged( void ) +{ + ARPPacket_t xARPFrame = { 0 }; + eFrameProcessingResult_t eResult; + NetworkInterface_t xInterface; + struct xNetworkEndPoint xEndPoint = { 0 }; + NetworkBufferDescriptor_t xNetworkBuffer = { 0 }; + uint32_t ulTargetIP = 0xAACCDDBB; + + memset( &xARPFrame, 0, sizeof( ARPPacket_t ) ); + memset( xARPCache, 0, sizeof( xARPCache ) ); + + /* =================================================== */ + /* Add settings required for ARP header to pass checks */ + xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET; + xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE; + xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES; + xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES; + + /* Process an ARP request - meant for this node with target and source same. */ + xEndPoint.ipv4_settings.ulIPAddress = 0xAABBCCDD; + /* Fill in the request option. */ + xARPFrame.xARPHeader.usOperation = ipARP_REQUEST; + xARPFrame.xARPHeader.ulTargetProtocolAddress = ulTargetIP; + memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) ); + + memset( &( xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes ), 0x22, sizeof( MACAddress_t ) ); + + xARPCache[ 0 ].ulIPAddress = ulTargetIP; + xARPCache[ 0 ].ucAge = 1; + xARPCache[ 0 ].ucValid = pdTRUE; + memset( xARPCache[ 0 ].xMACAddress.ucBytes, 0x22, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + xARPCache[ 0 ].pxEndPoint = &xEndPoint; + + /* Reset the private variable uxARPClashCounter. */ + vResetARPClashCounter(); + + FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); + xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + + xNetworkBuffer.pucEthernetBuffer = &xARPFrame; + xNetworkBuffer.xDataLength = sizeof( ARPPacket_t ); + xNetworkBuffer.pxEndPoint = &xEndPoint; + xEndPoint.bits.bEndPointUp = pdTRUE_UNSIGNED; + + eResult = eARPProcessPacket( &xNetworkBuffer ); + TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); + TEST_ASSERT_EQUAL( ulTargetIP, xARPCache[ 0 ].ulIPAddress ); + TEST_ASSERT_EQUAL( ipconfigMAX_ARP_AGE, xARPCache[ 0 ].ucAge ); + TEST_ASSERT_EQUAL( pdTRUE, xARPCache[ 0 ].ucValid ); + TEST_ASSERT_EQUAL( &xEndPoint, xARPCache[ 0 ].pxEndPoint ); + TEST_ASSERT_EQUAL_MEMORY( &( xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes ), xARPCache[ 0 ].xMACAddress.ucBytes, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + /* =================================================== */ +} + +void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingEndpoint( void ) +{ + ARPPacket_t xARPFrame = { 0 }; + eFrameProcessingResult_t eResult; + NetworkInterface_t xInterface; + struct xNetworkEndPoint xEndPoint = { 0 }; + struct xNetworkEndPoint xEndPoint2 = { 0 }; + NetworkBufferDescriptor_t xNetworkBuffer = { 0 }; + uint32_t ulTargetIP = 0xAACCDDBB; + uint8_t ucMAC[ 6 ] = { 0x34, 0x34, 0x34, 0x34, 0x34, 0x34 }; + + memset( &xARPFrame, 0, sizeof( ARPPacket_t ) ); + memset( xARPCache, 0, sizeof( xARPCache ) ); + + /* =================================================== */ + /* Add settings required for ARP header to pass checks */ + xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET; + xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE; + xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES; + xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES; + + /* Process an ARP request - meant for this node with target and source same. */ + xEndPoint.ipv4_settings.ulIPAddress = 0xAABBCCDD; + /* Fill in the request option. */ + xARPFrame.xARPHeader.usOperation = ipARP_REQUEST; + xARPFrame.xARPHeader.ulTargetProtocolAddress = ulTargetIP; + memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) ); + + memset( &( xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes ), 0x22, sizeof( MACAddress_t ) ); + + xARPCache[ 0 ].ulIPAddress = ulTargetIP; + xARPCache[ 0 ].ucAge = 1; + xARPCache[ 0 ].ucValid = pdTRUE; + memset( xARPCache[ 0 ].xMACAddress.ucBytes, 0x34, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + xARPCache[ 0 ].pxEndPoint = &xEndPoint2; + + /* Reset the private variable uxARPClashCounter. */ + vResetARPClashCounter(); + + FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); + xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + + xNetworkBuffer.pucEthernetBuffer = &xARPFrame; + xNetworkBuffer.xDataLength = sizeof( ARPPacket_t ); + xNetworkBuffer.pxEndPoint = &xEndPoint; + xEndPoint.bits.bEndPointUp = pdTRUE_UNSIGNED; + + eResult = eARPProcessPacket( &xNetworkBuffer ); + TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); + TEST_ASSERT_EQUAL( ulTargetIP, xARPCache[ 0 ].ulIPAddress ); + TEST_ASSERT_EQUAL( 1, xARPCache[ 0 ].ucAge ); + TEST_ASSERT_EQUAL( pdTRUE, xARPCache[ 0 ].ucValid ); + TEST_ASSERT_EQUAL( &xEndPoint2, xARPCache[ 0 ].pxEndPoint ); + TEST_ASSERT_EQUAL_MEMORY( ucMAC, xARPCache[ 0 ].xMACAddress.ucBytes, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + /* =================================================== */ +} + +void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingIP( void ) +{ + ARPPacket_t xARPFrame = { 0 }; + eFrameProcessingResult_t eResult; + NetworkInterface_t xInterface; + struct xNetworkEndPoint xEndPoint = { 0 }; + struct xNetworkEndPoint xEndPoint2 = { 0 }; + NetworkBufferDescriptor_t xNetworkBuffer = { 0 }; + uint32_t ulTargetIP = 0xAACCDDBB; + uint8_t ucMAC[ 6 ] = { 0x34, 0x34, 0x34, 0x34, 0x34, 0x34 }; + + memset( &xARPFrame, 0, sizeof( ARPPacket_t ) ); + memset( xARPCache, 0, sizeof( xARPCache ) ); + + /* =================================================== */ + /* Add settings required for ARP header to pass checks */ + xARPFrame.xARPHeader.usHardwareType = ipARP_HARDWARE_TYPE_ETHERNET; + xARPFrame.xARPHeader.usProtocolType = ipARP_PROTOCOL_TYPE; + xARPFrame.xARPHeader.ucHardwareAddressLength = ipMAC_ADDRESS_LENGTH_BYTES; + xARPFrame.xARPHeader.ucProtocolAddressLength = ipIP_ADDRESS_LENGTH_BYTES; + + /* Process an ARP request - meant for this node with target and source same. */ + xEndPoint.ipv4_settings.ulIPAddress = 0xAABBCCDD; + /* Fill in the request option. */ + xARPFrame.xARPHeader.usOperation = ipARP_REQUEST; + xARPFrame.xARPHeader.ulTargetProtocolAddress = ulTargetIP; + memcpy( xARPFrame.xARPHeader.ucSenderProtocolAddress, &( xARPFrame.xARPHeader.ulTargetProtocolAddress ), sizeof( xARPFrame.xARPHeader.ulTargetProtocolAddress ) ); + + memset( &( xARPFrame.xARPHeader.xSenderHardwareAddress.ucBytes ), 0x22, sizeof( MACAddress_t ) ); + + xARPCache[ 0 ].ulIPAddress = 0xAABBCCDF; + xARPCache[ 0 ].ucAge = 1; + xARPCache[ 0 ].ucValid = pdTRUE; + memset( xARPCache[ 0 ].xMACAddress.ucBytes, 0x34, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + xARPCache[ 0 ].pxEndPoint = &xEndPoint2; + + /* Reset the private variable uxARPClashCounter. */ + vResetARPClashCounter(); + + FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); + xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + + xNetworkBuffer.pucEthernetBuffer = &xARPFrame; + xNetworkBuffer.xDataLength = sizeof( ARPPacket_t ); + xNetworkBuffer.pxEndPoint = &xEndPoint; + xEndPoint.bits.bEndPointUp = pdTRUE_UNSIGNED; + + eResult = eARPProcessPacket( &xNetworkBuffer ); + TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); + TEST_ASSERT_EQUAL( 0xAABBCCDF, xARPCache[ 0 ].ulIPAddress ); + TEST_ASSERT_EQUAL( 1, xARPCache[ 0 ].ucAge ); + TEST_ASSERT_EQUAL( pdTRUE, xARPCache[ 0 ].ucValid ); + TEST_ASSERT_EQUAL( &xEndPoint2, xARPCache[ 0 ].pxEndPoint ); + TEST_ASSERT_EQUAL_MEMORY( ucMAC, xARPCache[ 0 ].xMACAddress.ucBytes, sizeof( xARPCache[ 0 ].xMACAddress.ucBytes ) ); + /* =================================================== */ +} + void test_eARPProcessPacket_Reply_TargetIPSameAsLocalIP( void ) { ARPPacket_t xARPFrame = { 0 }; From 8fd3b554c1ed7120b22c76aa271be6eeb8d2ddd0 Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Thu, 20 Jul 2023 11:34:01 +0530 Subject: [PATCH 11/15] fix build --- source/FreeRTOS_ARP.c | 107 +++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index 25e17f9cea..202d1e1b38 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -82,16 +82,18 @@ #define arpIP_CLASH_MAX_RETRIES 1U #endif -static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, - NetworkEndPoint_t * pxTargetEndPoint, - uint32_t ulSenderProtocolAddress ); -static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, - NetworkEndPoint_t * pxTargetEndPoint, - uint32_t ulSenderProtocolAddress ); #if ( ipconfigUSE_IPv4 != 0 ) + static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, + NetworkEndPoint_t * pxTargetEndPoint, + uint32_t ulSenderProtocolAddress ); + + static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, + NetworkEndPoint_t * pxTargetEndPoint, + uint32_t ulSenderProtocolAddress ); + /* * Lookup an MAC address in the ARP cache from the IP address. */ @@ -133,6 +135,8 @@ static TickType_t xLastGratuitousARPTime = 0U; /*-----------------------------------------------------------*/ +#if ( ipconfigUSE_IPv4 != 0 ) + /** * @brief Process the ARP packets. * @@ -342,6 +346,8 @@ eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * px } /*-----------------------------------------------------------*/ + + /** * @brief Process an ARP request packets. * @@ -455,6 +461,8 @@ static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, } /*-----------------------------------------------------------*/ +#endif /* ( ipconfigUSE_IPv4 != 0 ) */ + /** * @brief Check whether an IP address is in the ARP cache. * @@ -899,65 +907,66 @@ static BaseType_t prvFindCacheEntry( const MACAddress_t * pxMACAddress, * addressing needs a gateway but there isn't a gateway defined) then return * eCantSendPacket. */ - eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, - MACAddress_t * const pxMACAddress, - struct xNetworkEndPoint ** ppxEndPoint ) - { - eARPLookupResult_t eReturn; - uint32_t ulAddressToLookup; - NetworkEndPoint_t * pxEndPoint = NULL; +eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, + MACAddress_t * const pxMACAddress, + struct xNetworkEndPoint ** ppxEndPoint ) +{ + eARPLookupResult_t eReturn; + uint32_t ulAddressToLookup; + NetworkEndPoint_t * pxEndPoint = NULL; - configASSERT( pxMACAddress != NULL ); - configASSERT( pulIPAddress != NULL ); - configASSERT( ppxEndPoint != NULL ); + configASSERT( pxMACAddress != NULL ); + configASSERT( pulIPAddress != NULL ); + configASSERT( ppxEndPoint != NULL ); - *( ppxEndPoint ) = NULL; - ulAddressToLookup = *pulIPAddress; - pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulAddressToLookup, 0 ); + *( ppxEndPoint ) = NULL; + ulAddressToLookup = *pulIPAddress; + pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulAddressToLookup, 0 ); - if( xIsIPv4Multicast( ulAddressToLookup ) != 0 ) - { - /* Get the lowest 23 bits of the IP-address. */ - vSetMultiCastIPv4MacAddress( ulAddressToLookup, pxMACAddress ); + if( xIsIPv4Multicast( ulAddressToLookup ) != 0 ) + { + /* Get the lowest 23 bits of the IP-address. */ + vSetMultiCastIPv4MacAddress( ulAddressToLookup, pxMACAddress ); - eReturn = eCantSendPacket; - pxEndPoint = FreeRTOS_FirstEndPoint( NULL ); + eReturn = eCantSendPacket; + pxEndPoint = FreeRTOS_FirstEndPoint( NULL ); - for( ; - pxEndPoint != NULL; - pxEndPoint = FreeRTOS_NextEndPoint( NULL, pxEndPoint ) ) - { - if( pxEndPoint->bits.bIPv6 == 0U ) /*NULL End Point is checked in the for loop, no need for an extra check */ - { - /* For multi-cast, use the first IPv4 end-point. */ - *( ppxEndPoint ) = pxEndPoint; - eReturn = eARPCacheHit; - break; - } - } - } - else if( ( FreeRTOS_htonl( ulAddressToLookup ) & 0xffU ) == 0xffU ) /* Is this a broadcast address like x.x.x.255 ? */ + for( ; + pxEndPoint != NULL; + pxEndPoint = FreeRTOS_NextEndPoint( NULL, pxEndPoint ) ) { - /* This is a broadcast so it uses the broadcast MAC address. */ - ( void ) memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); - pxEndPoint = FreeRTOS_FindEndPointOnNetMask( ulAddressToLookup, 4 ); - - if( pxEndPoint != NULL ) + if( pxEndPoint->bits.bIPv6 == 0U ) /*NULL End Point is checked in the for loop, no need for an extra check */ { + /* For multi-cast, use the first IPv4 end-point. */ *( ppxEndPoint ) = pxEndPoint; + eReturn = eARPCacheHit; + break; } - - eReturn = eARPCacheHit; } - else + } + else if( ( FreeRTOS_htonl( ulAddressToLookup ) & 0xffU ) == 0xffU ) /* Is this a broadcast address like x.x.x.255 ? */ + { + /* This is a broadcast so it uses the broadcast MAC address. */ + ( void ) memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); + pxEndPoint = FreeRTOS_FindEndPointOnNetMask( ulAddressToLookup, 4 ); + + if( pxEndPoint != NULL ) { - eReturn = eARPGetCacheEntryGateWay( pulIPAddress, pxMACAddress, ppxEndPoint ); + *( ppxEndPoint ) = pxEndPoint; } - return eReturn; + eReturn = eARPCacheHit; + } + else + { + eReturn = eARPGetCacheEntryGateWay( pulIPAddress, pxMACAddress, ppxEndPoint ); } + + return eReturn; +} /*-----------------------------------------------------------*/ + /** * @brief The IPv4 address is apparently a web-address. Find a gateway.. * @param[in] pulIPAddress The target IP-address. It may be replaced with the IP From 86d02cafe8ca8bc4845ef4e51e1415f6a7bd197e Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Thu, 20 Jul 2023 11:34:44 +0530 Subject: [PATCH 12/15] fix formatting --- source/FreeRTOS_ARP.c | 576 +++++++++++++++++++++--------------------- 1 file changed, 288 insertions(+), 288 deletions(-) diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index 202d1e1b38..6a6d64ada5 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -91,8 +91,8 @@ uint32_t ulSenderProtocolAddress ); static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, - NetworkEndPoint_t * pxTargetEndPoint, - uint32_t ulSenderProtocolAddress ); + NetworkEndPoint_t * pxTargetEndPoint, + uint32_t ulSenderProtocolAddress ); /* * Lookup an MAC address in the ARP cache from the IP address. @@ -144,206 +144,206 @@ static TickType_t xLastGratuitousARPTime = 0U; * * @return An enum which says whether to return the frame or to release it. */ -eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * pxNetworkBuffer ) -{ - /* MISRA Ref 11.3.1 [Misaligned access] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ - ARPPacket_t * pxARPFrame = ( ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer ); - eFrameProcessingResult_t eReturn = eReleaseBuffer; - const ARPHeader_t * pxARPHeader; - uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress; - - /* memcpy() helper variables for MISRA Rule 21.15 compliance*/ - const void * pvCopySource; - void * pvCopyDest; - NetworkEndPoint_t * pxTargetEndPoint = pxNetworkBuffer->pxEndPoint; - - /* Next defensive request must not be sent for arpIP_CLASH_RESET_TIMEOUT_MS - * period. */ - static TickType_t uxARPClashTimeoutPeriod = pdMS_TO_TICKS( arpIP_CLASH_RESET_TIMEOUT_MS ); - - /* This local variable is used to keep track of number of ARP requests sent and - * also to limit the requests to arpIP_CLASH_MAX_RETRIES per arpIP_CLASH_RESET_TIMEOUT_MS - * period. */ - static UBaseType_t uxARPClashCounter = 0U; - /* The time at which the last ARP clash was sent. */ - static TimeOut_t xARPClashTimeOut; - - pxARPHeader = &( pxARPFrame->xARPHeader ); - - /* Only Ethernet hardware type is supported. - * Only IPv4 address can be present in the ARP packet. - * The hardware length (the MAC address) must be 6 bytes. And, - * The Protocol address length must be 4 bytes as it is IPv4. */ - if( ( pxARPHeader->usHardwareType == ipARP_HARDWARE_TYPE_ETHERNET ) && - ( pxARPHeader->usProtocolType == ipARP_PROTOCOL_TYPE ) && - ( pxARPHeader->ucHardwareAddressLength == ipMAC_ADDRESS_LENGTH_BYTES ) && - ( pxARPHeader->ucProtocolAddressLength == ipIP_ADDRESS_LENGTH_BYTES ) ) + eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * pxNetworkBuffer ) { - /* The field ucSenderProtocolAddress is badly aligned, copy byte-by-byte. */ - - /* - * Use helper variables for memcpy() to remain - * compliant with MISRA Rule 21.15. These should be - * optimized away. - */ - pvCopySource = pxARPHeader->ucSenderProtocolAddress; - pvCopyDest = &ulSenderProtocolAddress; - ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( ulSenderProtocolAddress ) ); - /* The field ulTargetProtocolAddress is well-aligned, a 32-bits copy. */ - ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress; - - if( uxARPClashCounter != 0U ) + /* MISRA Ref 11.3.1 [Misaligned access] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ + ARPPacket_t * pxARPFrame = ( ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer ); + eFrameProcessingResult_t eReturn = eReleaseBuffer; + const ARPHeader_t * pxARPHeader; + uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress; + + /* memcpy() helper variables for MISRA Rule 21.15 compliance*/ + const void * pvCopySource; + void * pvCopyDest; + NetworkEndPoint_t * pxTargetEndPoint = pxNetworkBuffer->pxEndPoint; + + /* Next defensive request must not be sent for arpIP_CLASH_RESET_TIMEOUT_MS + * period. */ + static TickType_t uxARPClashTimeoutPeriod = pdMS_TO_TICKS( arpIP_CLASH_RESET_TIMEOUT_MS ); + + /* This local variable is used to keep track of number of ARP requests sent and + * also to limit the requests to arpIP_CLASH_MAX_RETRIES per arpIP_CLASH_RESET_TIMEOUT_MS + * period. */ + static UBaseType_t uxARPClashCounter = 0U; + /* The time at which the last ARP clash was sent. */ + static TimeOut_t xARPClashTimeOut; + + pxARPHeader = &( pxARPFrame->xARPHeader ); + + /* Only Ethernet hardware type is supported. + * Only IPv4 address can be present in the ARP packet. + * The hardware length (the MAC address) must be 6 bytes. And, + * The Protocol address length must be 4 bytes as it is IPv4. */ + if( ( pxARPHeader->usHardwareType == ipARP_HARDWARE_TYPE_ETHERNET ) && + ( pxARPHeader->usProtocolType == ipARP_PROTOCOL_TYPE ) && + ( pxARPHeader->ucHardwareAddressLength == ipMAC_ADDRESS_LENGTH_BYTES ) && + ( pxARPHeader->ucProtocolAddressLength == ipIP_ADDRESS_LENGTH_BYTES ) ) { - /* Has the timeout been reached? */ - if( xTaskCheckForTimeOut( &xARPClashTimeOut, &uxARPClashTimeoutPeriod ) == pdTRUE ) + /* The field ucSenderProtocolAddress is badly aligned, copy byte-by-byte. */ + + /* + * Use helper variables for memcpy() to remain + * compliant with MISRA Rule 21.15. These should be + * optimized away. + */ + pvCopySource = pxARPHeader->ucSenderProtocolAddress; + pvCopyDest = &ulSenderProtocolAddress; + ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( ulSenderProtocolAddress ) ); + /* The field ulTargetProtocolAddress is well-aligned, a 32-bits copy. */ + ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress; + + if( uxARPClashCounter != 0U ) { - /* We have waited long enough, reset the counter. */ - uxARPClashCounter = 0; + /* Has the timeout been reached? */ + if( xTaskCheckForTimeOut( &xARPClashTimeOut, &uxARPClashTimeoutPeriod ) == pdTRUE ) + { + /* We have waited long enough, reset the counter. */ + uxARPClashCounter = 0; + } } - } - /* Check whether the lowest bit of the highest byte is 1 to check for - * multicast address or even a broadcast address (FF:FF:FF:FF:FF:FF). */ - if( ( pxARPHeader->xSenderHardwareAddress.ucBytes[ 0 ] & 0x01U ) == 0x01U ) - { - /* Senders address is a multicast OR broadcast address which is not - * allowed for an ARP packet. Drop the packet. See RFC 1812 section - * 3.3.2. */ - iptraceDROPPED_INVALID_ARP_PACKET( pxARPHeader ); - } - else if( ( ipFIRST_LOOPBACK_IPv4 <= ( FreeRTOS_ntohl( ulSenderProtocolAddress ) ) ) && - ( ( FreeRTOS_ntohl( ulSenderProtocolAddress ) ) < ipLAST_LOOPBACK_IPv4 ) ) - { - /* The local loopback addresses must never appear outside a host. See RFC 1122 - * section 3.2.1.3. */ - iptraceDROPPED_INVALID_ARP_PACKET( pxARPHeader ); - } - /* Check whether there is a clash with another device for this IP address. */ - else if( ( pxTargetEndPoint != NULL ) && ( ulSenderProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) ) - { - if( uxARPClashCounter < arpIP_CLASH_MAX_RETRIES ) + /* Check whether the lowest bit of the highest byte is 1 to check for + * multicast address or even a broadcast address (FF:FF:FF:FF:FF:FF). */ + if( ( pxARPHeader->xSenderHardwareAddress.ucBytes[ 0 ] & 0x01U ) == 0x01U ) { - /* Increment the counter. */ - uxARPClashCounter++; - - /* Send out a defensive ARP request. */ - FreeRTOS_OutputARPRequest( pxTargetEndPoint->ipv4_settings.ulIPAddress ); + /* Senders address is a multicast OR broadcast address which is not + * allowed for an ARP packet. Drop the packet. See RFC 1812 section + * 3.3.2. */ + iptraceDROPPED_INVALID_ARP_PACKET( pxARPHeader ); + } + else if( ( ipFIRST_LOOPBACK_IPv4 <= ( FreeRTOS_ntohl( ulSenderProtocolAddress ) ) ) && + ( ( FreeRTOS_ntohl( ulSenderProtocolAddress ) ) < ipLAST_LOOPBACK_IPv4 ) ) + { + /* The local loopback addresses must never appear outside a host. See RFC 1122 + * section 3.2.1.3. */ + iptraceDROPPED_INVALID_ARP_PACKET( pxARPHeader ); + } + /* Check whether there is a clash with another device for this IP address. */ + else if( ( pxTargetEndPoint != NULL ) && ( ulSenderProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) ) + { + if( uxARPClashCounter < arpIP_CLASH_MAX_RETRIES ) + { + /* Increment the counter. */ + uxARPClashCounter++; - /* Since an ARP Request for this IP was just sent, do not send a gratuitous - * ARP for arpGRATUITOUS_ARP_PERIOD. */ - xLastGratuitousARPTime = xTaskGetTickCount(); + /* Send out a defensive ARP request. */ + FreeRTOS_OutputARPRequest( pxTargetEndPoint->ipv4_settings.ulIPAddress ); - /* Note the time at which this request was sent. */ - vTaskSetTimeOutState( &xARPClashTimeOut ); + /* Since an ARP Request for this IP was just sent, do not send a gratuitous + * ARP for arpGRATUITOUS_ARP_PERIOD. */ + xLastGratuitousARPTime = xTaskGetTickCount(); - /* Reset the time-out period to the given value. */ - uxARPClashTimeoutPeriod = pdMS_TO_TICKS( arpIP_CLASH_RESET_TIMEOUT_MS ); - } + /* Note the time at which this request was sent. */ + vTaskSetTimeOutState( &xARPClashTimeOut ); - /* Process received ARP frame to see if there is a clash. */ - #if ( ipconfigARP_USE_CLASH_DETECTION != 0 ) - { - NetworkEndPoint_t * pxSourceEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulSenderProtocolAddress, 2 ); + /* Reset the time-out period to the given value. */ + uxARPClashTimeoutPeriod = pdMS_TO_TICKS( arpIP_CLASH_RESET_TIMEOUT_MS ); + } - if( ( pxSourceEndPoint != NULL ) && ( pxSourceEndPoint->ipv4_settings.ulIPAddress == ulSenderProtocolAddress ) ) + /* Process received ARP frame to see if there is a clash. */ + #if ( ipconfigARP_USE_CLASH_DETECTION != 0 ) { - xARPHadIPClash = pdTRUE; - /* Remember the MAC-address of the other device which has the same IP-address. */ - ( void ) memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) ); + NetworkEndPoint_t * pxSourceEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulSenderProtocolAddress, 2 ); + + if( ( pxSourceEndPoint != NULL ) && ( pxSourceEndPoint->ipv4_settings.ulIPAddress == ulSenderProtocolAddress ) ) + { + xARPHadIPClash = pdTRUE; + /* Remember the MAC-address of the other device which has the same IP-address. */ + ( void ) memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) ); + } } - } - #endif /* ipconfigARP_USE_CLASH_DETECTION */ - } - else - { - traceARP_PACKET_RECEIVED(); + #endif /* ipconfigARP_USE_CLASH_DETECTION */ + } + else + { + traceARP_PACKET_RECEIVED(); - /* Some extra logging while still testing. */ - #if ( ipconfigHAS_PRINTF != 0 ) - if( pxARPHeader->usOperation == ( uint16_t ) ipARP_REPLY ) - { - FreeRTOS_printf( ( "ipARP_REPLY from %xip to %xip end-point %xip\n", - ( unsigned ) FreeRTOS_ntohl( ulSenderProtocolAddress ), - ( unsigned ) FreeRTOS_ntohl( ulTargetProtocolAddress ), - ( unsigned ) FreeRTOS_ntohl( ( pxTargetEndPoint != NULL ) ? pxTargetEndPoint->ipv4_settings.ulIPAddress : 0U ) ) ); - } - #endif /* ( ipconfigHAS_DEBUG_PRINTF != 0 ) */ + /* Some extra logging while still testing. */ + #if ( ipconfigHAS_PRINTF != 0 ) + if( pxARPHeader->usOperation == ( uint16_t ) ipARP_REPLY ) + { + FreeRTOS_printf( ( "ipARP_REPLY from %xip to %xip end-point %xip\n", + ( unsigned ) FreeRTOS_ntohl( ulSenderProtocolAddress ), + ( unsigned ) FreeRTOS_ntohl( ulTargetProtocolAddress ), + ( unsigned ) FreeRTOS_ntohl( ( pxTargetEndPoint != NULL ) ? pxTargetEndPoint->ipv4_settings.ulIPAddress : 0U ) ) ); + } + #endif /* ( ipconfigHAS_DEBUG_PRINTF != 0 ) */ - #if ( ipconfigHAS_DEBUG_PRINTF != 0 ) - if( ( pxARPHeader->usOperation == ( uint16_t ) ipARP_REQUEST ) && - ( ulSenderProtocolAddress != ulTargetProtocolAddress ) && - ( pxTargetEndPoint != NULL ) ) - { - FreeRTOS_debug_printf( ( "ipARP_REQUEST from %xip to %xip end-point %xip\n", - ( unsigned ) FreeRTOS_ntohl( ulSenderProtocolAddress ), - ( unsigned ) FreeRTOS_ntohl( ulTargetProtocolAddress ), - ( unsigned ) ( FreeRTOS_ntohl( ( pxTargetEndPoint != NULL ) ? pxTargetEndPoint->ipv4_settings.ulIPAddress : 0U ) ) ) ); - } - #endif /* ( ipconfigHAS_PRINTF != 0 ) */ + #if ( ipconfigHAS_DEBUG_PRINTF != 0 ) + if( ( pxARPHeader->usOperation == ( uint16_t ) ipARP_REQUEST ) && + ( ulSenderProtocolAddress != ulTargetProtocolAddress ) && + ( pxTargetEndPoint != NULL ) ) + { + FreeRTOS_debug_printf( ( "ipARP_REQUEST from %xip to %xip end-point %xip\n", + ( unsigned ) FreeRTOS_ntohl( ulSenderProtocolAddress ), + ( unsigned ) FreeRTOS_ntohl( ulTargetProtocolAddress ), + ( unsigned ) ( FreeRTOS_ntohl( ( pxTargetEndPoint != NULL ) ? pxTargetEndPoint->ipv4_settings.ulIPAddress : 0U ) ) ) ); + } + #endif /* ( ipconfigHAS_PRINTF != 0 ) */ - /* ulTargetProtocolAddress won't be used unless logging is enabled. */ - ( void ) ulTargetProtocolAddress; + /* ulTargetProtocolAddress won't be used unless logging is enabled. */ + ( void ) ulTargetProtocolAddress; - /* Don't do anything if the local IP address is zero because - * that means a DHCP request has not completed. */ - if( ( pxTargetEndPoint != NULL ) && ( pxTargetEndPoint->bits.bEndPointUp != pdFALSE_UNSIGNED ) ) - { - switch( pxARPHeader->usOperation ) + /* Don't do anything if the local IP address is zero because + * that means a DHCP request has not completed. */ + if( ( pxTargetEndPoint != NULL ) && ( pxTargetEndPoint->bits.bEndPointUp != pdFALSE_UNSIGNED ) ) { - case ipARP_REQUEST: + switch( pxARPHeader->usOperation ) + { + case ipARP_REQUEST: - if( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) - { - if( memcmp( ( void * ) pxTargetEndPoint->xMACAddress.ucBytes, - ( pxARPHeader->xSenderHardwareAddress.ucBytes ), - ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) + if( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) { - vARPProcessPacketRequest( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); - eReturn = eReturnEthernetFrame; + if( memcmp( ( void * ) pxTargetEndPoint->xMACAddress.ucBytes, + ( pxARPHeader->xSenderHardwareAddress.ucBytes ), + ipMAC_ADDRESS_LENGTH_BYTES ) != 0 ) + { + vARPProcessPacketRequest( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); + eReturn = eReturnEthernetFrame; + } } - } - else if( ulSenderProtocolAddress == ulTargetProtocolAddress ) /* Gratuitous ARP request? */ - { - MACAddress_t xHardwareAddress; - NetworkEndPoint_t * pxCachedEndPoint; + else if( ulSenderProtocolAddress == ulTargetProtocolAddress ) /* Gratuitous ARP request? */ + { + MACAddress_t xHardwareAddress; + NetworkEndPoint_t * pxCachedEndPoint; - pxCachedEndPoint = NULL; + pxCachedEndPoint = NULL; - /* The request is a Gratuitous ARP message. - * Refresh the entry if it already exists. */ - /* Determine the ARP cache status for the requested IP address. */ - if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ), &( pxCachedEndPoint ) ) == eARPCacheHit ) - { - /* Check if the endpoint matches with the one present in the ARP cache */ - if( pxCachedEndPoint == pxTargetEndPoint ) + /* The request is a Gratuitous ARP message. + * Refresh the entry if it already exists. */ + /* Determine the ARP cache status for the requested IP address. */ + if( eARPGetCacheEntry( &( ulSenderProtocolAddress ), &( xHardwareAddress ), &( pxCachedEndPoint ) ) == eARPCacheHit ) { - vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); + /* Check if the endpoint matches with the one present in the ARP cache */ + if( pxCachedEndPoint == pxTargetEndPoint ) + { + vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); + } } } - } - break; + break; - case ipARP_REPLY: - vARPProcessPacketReply( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); - break; + case ipARP_REPLY: + vARPProcessPacketReply( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress ); + break; - default: - /* Invalid. */ - break; + default: + /* Invalid. */ + break; + } } } } - } - else - { - iptraceDROPPED_INVALID_ARP_PACKET( pxARPHeader ); - } + else + { + iptraceDROPPED_INVALID_ARP_PACKET( pxARPHeader ); + } - return eReturn; -} + return eReturn; + } /*-----------------------------------------------------------*/ @@ -356,53 +356,53 @@ eFrameProcessingResult_t eARPProcessPacket( const NetworkBufferDescriptor_t * px * @param[in] ulSenderProtocolAddress the IP-address of the sender. * */ -static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, - NetworkEndPoint_t * pxTargetEndPoint, - uint32_t ulSenderProtocolAddress ) -{ - ARPHeader_t * pxARPHeader = &( pxARPFrame->xARPHeader ); + static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, + NetworkEndPoint_t * pxTargetEndPoint, + uint32_t ulSenderProtocolAddress ) + { + ARPHeader_t * pxARPHeader = &( pxARPFrame->xARPHeader ); /* memcpy() helper variables for MISRA Rule 21.15 compliance*/ - const void * pvCopySource; - void * pvCopyDest; + const void * pvCopySource; + void * pvCopyDest; - /* The packet contained an ARP request. Was it for the IP - * address of one of the end-points? */ - /* It has been confirmed that pxTargetEndPoint is not NULL. */ - iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress ); + /* The packet contained an ARP request. Was it for the IP + * address of one of the end-points? */ + /* It has been confirmed that pxTargetEndPoint is not NULL. */ + iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress ); - /* The request is for the address of this node. Add the - * entry into the ARP cache, or refresh the entry if it - * already exists. */ - vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); + /* The request is for the address of this node. Add the + * entry into the ARP cache, or refresh the entry if it + * already exists. */ + vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); - /* Generate a reply payload in the same buffer. */ - pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY; + /* Generate a reply payload in the same buffer. */ + pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY; - /* A double IP address cannot be detected here, it is taken care in the Process ARP Packets path */ + /* A double IP address cannot be detected here, it is taken care in the Process ARP Packets path */ - /* - * Use helper variables for memcpy() to remain - * compliant with MISRA Rule 21.15. These should be - * optimized away. - */ - pvCopySource = pxARPHeader->xSenderHardwareAddress.ucBytes; - pvCopyDest = pxARPHeader->xTargetHardwareAddress.ucBytes; - ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) ); - pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress; + /* + * Use helper variables for memcpy() to remain + * compliant with MISRA Rule 21.15. These should be + * optimized away. + */ + pvCopySource = pxARPHeader->xSenderHardwareAddress.ucBytes; + pvCopyDest = pxARPHeader->xTargetHardwareAddress.ucBytes; + ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) ); + pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress; - /* - * Use helper variables for memcpy() to remain - * compliant with MISRA Rule 21.15. These should be - * optimized away. - */ - pvCopySource = pxTargetEndPoint->xMACAddress.ucBytes; - pvCopyDest = pxARPHeader->xSenderHardwareAddress.ucBytes; - ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) ); - pvCopySource = &( pxTargetEndPoint->ipv4_settings.ulIPAddress ); - pvCopyDest = pxARPHeader->ucSenderProtocolAddress; - ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) ); -} + /* + * Use helper variables for memcpy() to remain + * compliant with MISRA Rule 21.15. These should be + * optimized away. + */ + pvCopySource = pxTargetEndPoint->xMACAddress.ucBytes; + pvCopyDest = pxARPHeader->xSenderHardwareAddress.ucBytes; + ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) ); + pvCopySource = &( pxTargetEndPoint->ipv4_settings.ulIPAddress ); + pvCopyDest = pxARPHeader->ucSenderProtocolAddress; + ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) ); + } /*-----------------------------------------------------------*/ /** @@ -411,54 +411,54 @@ static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, * @param[in] pxTargetEndPoint The end-point on which it is received. * @param[in] ulSenderProtocolAddress The IPv4 address involved. */ -static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, - NetworkEndPoint_t * pxTargetEndPoint, - uint32_t ulSenderProtocolAddress ) -{ - const ARPHeader_t * pxARPHeader = &( pxARPFrame->xARPHeader ); - uint32_t ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress; - - /* If the packet is meant for this device or if the entry already exists. */ - if( ( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) || - ( xIsIPInARPCache( ulSenderProtocolAddress ) == pdTRUE ) ) - { - iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress ); - vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); - } - - if( ( pxARPWaitingNetworkBuffer != NULL ) && - ( uxIPHeaderSizePacket( pxARPWaitingNetworkBuffer ) == ipSIZE_OF_IPv4_HEADER ) ) + static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, + NetworkEndPoint_t * pxTargetEndPoint, + uint32_t ulSenderProtocolAddress ) { - /* MISRA Ref 11.3.1 [Misaligned access] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ - const IPPacket_t * pxARPWaitingIPPacket = ( ( IPPacket_t * ) pxARPWaitingNetworkBuffer->pucEthernetBuffer ); - const IPHeader_t * pxARPWaitingIPHeader = &( pxARPWaitingIPPacket->xIPHeader ); + const ARPHeader_t * pxARPHeader = &( pxARPFrame->xARPHeader ); + uint32_t ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress; - if( ulSenderProtocolAddress == pxARPWaitingIPHeader->ulSourceIPAddress ) + /* If the packet is meant for this device or if the entry already exists. */ + if( ( ulTargetProtocolAddress == pxTargetEndPoint->ipv4_settings.ulIPAddress ) || + ( xIsIPInARPCache( ulSenderProtocolAddress ) == pdTRUE ) ) { - IPStackEvent_t xEventMessage; - const TickType_t xDontBlock = ( TickType_t ) 0; + iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress ); + vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint ); + } - xEventMessage.eEventType = eNetworkRxEvent; - xEventMessage.pvData = ( void * ) pxARPWaitingNetworkBuffer; + if( ( pxARPWaitingNetworkBuffer != NULL ) && + ( uxIPHeaderSizePacket( pxARPWaitingNetworkBuffer ) == ipSIZE_OF_IPv4_HEADER ) ) + { + /* MISRA Ref 11.3.1 [Misaligned access] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ + const IPPacket_t * pxARPWaitingIPPacket = ( ( IPPacket_t * ) pxARPWaitingNetworkBuffer->pucEthernetBuffer ); + const IPHeader_t * pxARPWaitingIPHeader = &( pxARPWaitingIPPacket->xIPHeader ); - if( xSendEventStructToIPTask( &xEventMessage, xDontBlock ) != pdPASS ) + if( ulSenderProtocolAddress == pxARPWaitingIPHeader->ulSourceIPAddress ) { - /* Failed to send the message, so release the network buffer. */ - vReleaseNetworkBufferAndDescriptor( pxARPWaitingNetworkBuffer ); - } + IPStackEvent_t xEventMessage; + const TickType_t xDontBlock = ( TickType_t ) 0; - /* Clear the buffer. */ - pxARPWaitingNetworkBuffer = NULL; + xEventMessage.eEventType = eNetworkRxEvent; + xEventMessage.pvData = ( void * ) pxARPWaitingNetworkBuffer; - /* Found an ARP resolution, disable ARP resolution timer. */ - vIPSetARPResolutionTimerEnableState( pdFALSE ); + if( xSendEventStructToIPTask( &xEventMessage, xDontBlock ) != pdPASS ) + { + /* Failed to send the message, so release the network buffer. */ + vReleaseNetworkBufferAndDescriptor( pxARPWaitingNetworkBuffer ); + } + + /* Clear the buffer. */ + pxARPWaitingNetworkBuffer = NULL; - iptrace_DELAYED_ARP_REQUEST_REPLIED(); + /* Found an ARP resolution, disable ARP resolution timer. */ + vIPSetARPResolutionTimerEnableState( pdFALSE ); + + iptrace_DELAYED_ARP_REQUEST_REPLIED(); + } } } -} /*-----------------------------------------------------------*/ #endif /* ( ipconfigUSE_IPv4 != 0 ) */ @@ -907,63 +907,63 @@ static BaseType_t prvFindCacheEntry( const MACAddress_t * pxMACAddress, * addressing needs a gateway but there isn't a gateway defined) then return * eCantSendPacket. */ -eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, - MACAddress_t * const pxMACAddress, - struct xNetworkEndPoint ** ppxEndPoint ) -{ - eARPLookupResult_t eReturn; - uint32_t ulAddressToLookup; - NetworkEndPoint_t * pxEndPoint = NULL; + eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, + MACAddress_t * const pxMACAddress, + struct xNetworkEndPoint ** ppxEndPoint ) + { + eARPLookupResult_t eReturn; + uint32_t ulAddressToLookup; + NetworkEndPoint_t * pxEndPoint = NULL; - configASSERT( pxMACAddress != NULL ); - configASSERT( pulIPAddress != NULL ); - configASSERT( ppxEndPoint != NULL ); + configASSERT( pxMACAddress != NULL ); + configASSERT( pulIPAddress != NULL ); + configASSERT( ppxEndPoint != NULL ); - *( ppxEndPoint ) = NULL; - ulAddressToLookup = *pulIPAddress; - pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulAddressToLookup, 0 ); + *( ppxEndPoint ) = NULL; + ulAddressToLookup = *pulIPAddress; + pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulAddressToLookup, 0 ); - if( xIsIPv4Multicast( ulAddressToLookup ) != 0 ) - { - /* Get the lowest 23 bits of the IP-address. */ - vSetMultiCastIPv4MacAddress( ulAddressToLookup, pxMACAddress ); + if( xIsIPv4Multicast( ulAddressToLookup ) != 0 ) + { + /* Get the lowest 23 bits of the IP-address. */ + vSetMultiCastIPv4MacAddress( ulAddressToLookup, pxMACAddress ); - eReturn = eCantSendPacket; - pxEndPoint = FreeRTOS_FirstEndPoint( NULL ); + eReturn = eCantSendPacket; + pxEndPoint = FreeRTOS_FirstEndPoint( NULL ); - for( ; - pxEndPoint != NULL; - pxEndPoint = FreeRTOS_NextEndPoint( NULL, pxEndPoint ) ) + for( ; + pxEndPoint != NULL; + pxEndPoint = FreeRTOS_NextEndPoint( NULL, pxEndPoint ) ) + { + if( pxEndPoint->bits.bIPv6 == 0U ) /*NULL End Point is checked in the for loop, no need for an extra check */ + { + /* For multi-cast, use the first IPv4 end-point. */ + *( ppxEndPoint ) = pxEndPoint; + eReturn = eARPCacheHit; + break; + } + } + } + else if( ( FreeRTOS_htonl( ulAddressToLookup ) & 0xffU ) == 0xffU ) /* Is this a broadcast address like x.x.x.255 ? */ { - if( pxEndPoint->bits.bIPv6 == 0U ) /*NULL End Point is checked in the for loop, no need for an extra check */ + /* This is a broadcast so it uses the broadcast MAC address. */ + ( void ) memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); + pxEndPoint = FreeRTOS_FindEndPointOnNetMask( ulAddressToLookup, 4 ); + + if( pxEndPoint != NULL ) { - /* For multi-cast, use the first IPv4 end-point. */ *( ppxEndPoint ) = pxEndPoint; - eReturn = eARPCacheHit; - break; } - } - } - else if( ( FreeRTOS_htonl( ulAddressToLookup ) & 0xffU ) == 0xffU ) /* Is this a broadcast address like x.x.x.255 ? */ - { - /* This is a broadcast so it uses the broadcast MAC address. */ - ( void ) memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); - pxEndPoint = FreeRTOS_FindEndPointOnNetMask( ulAddressToLookup, 4 ); - if( pxEndPoint != NULL ) + eReturn = eARPCacheHit; + } + else { - *( ppxEndPoint ) = pxEndPoint; + eReturn = eARPGetCacheEntryGateWay( pulIPAddress, pxMACAddress, ppxEndPoint ); } - eReturn = eARPCacheHit; - } - else - { - eReturn = eARPGetCacheEntryGateWay( pulIPAddress, pxMACAddress, ppxEndPoint ); + return eReturn; } - - return eReturn; -} /*-----------------------------------------------------------*/ From 9db7dc6f3fc4b96b02fbc70f6faaa9aa22e94412 Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Thu, 20 Jul 2023 12:06:36 +0530 Subject: [PATCH 13/15] fix formatting --- source/FreeRTOS_ARP.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index 6a6d64ada5..5ecb3aa8b2 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -82,18 +82,16 @@ #define arpIP_CLASH_MAX_RETRIES 1U #endif - - #if ( ipconfigUSE_IPv4 != 0 ) - static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, - NetworkEndPoint_t * pxTargetEndPoint, - uint32_t ulSenderProtocolAddress ); - static void vARPProcessPacketRequest( ARPPacket_t * pxARPFrame, NetworkEndPoint_t * pxTargetEndPoint, uint32_t ulSenderProtocolAddress ); + static void vARPProcessPacketReply( const ARPPacket_t * pxARPFrame, + NetworkEndPoint_t * pxTargetEndPoint, + uint32_t ulSenderProtocolAddress ); + /* * Lookup an MAC address in the ARP cache from the IP address. */ @@ -346,8 +344,6 @@ static TickType_t xLastGratuitousARPTime = 0U; } /*-----------------------------------------------------------*/ - - /** * @brief Process an ARP request packets. * @@ -966,7 +962,6 @@ static BaseType_t prvFindCacheEntry( const MACAddress_t * pxMACAddress, } /*-----------------------------------------------------------*/ - /** * @brief The IPv4 address is apparently a web-address. Find a gateway.. * @param[in] pulIPAddress The target IP-address. It may be replaced with the IP From 2a6cfd17495ed725b17aaa71f4a8a65d2cbcb7ed Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Thu, 20 Jul 2023 12:34:23 +0530 Subject: [PATCH 14/15] fic CBMC --- .../ARPProcessPacket/ARPProcessPacket_harness.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c b/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c index f3b9326d15..ee315e3f76 100644 --- a/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c +++ b/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c @@ -17,6 +17,21 @@ void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress ) { } +/* This function is proved elsewhere hence stubbing it out */ +eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, + MACAddress_t * const pxMACAddress, + struct xNetworkEndPoint ** ppxEndPoint ) +{ + eARPLookupResult_t eReturn; + + __CPROVER_assert( pulIPAddress != NULL, "pulIPAddress cannot be NULL." ); + __CPROVER_assert( pxMACAddress != NULL, "pxMACAddress cannot be NULL." ); + __CPROVER_assert( ppxEndPoint != NULL, "ppxEndPoint cannot be NULL." ); + + /* Return random value */ + return eReturn; +} + void harness() { NetworkBufferDescriptor_t xLocalBuffer; From d5ed28731d661647499ccc56f30832d951301183 Mon Sep 17 00:00:00 2001 From: tony-josi-aws Date: Mon, 24 Jul 2023 12:02:52 +0530 Subject: [PATCH 15/15] adding review changes --- .../FreeRTOS_ARP/FreeRTOS_ARP_utest.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c index f369c2effc..a18510b3e2 100644 --- a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c +++ b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c @@ -696,6 +696,10 @@ void test_eARPProcessPacket_Request_SenderAndTargetSame( void ) /* =================================================== */ } +/** + * @brief This function verify receiving Gratuitous ARP packet + * and updating the ARP cache with respect to the new ARP request. + */ void test_eARPProcessPacket_Request_GratuitousARP( void ) { ARPPacket_t xARPFrame = { 0 }; @@ -753,6 +757,12 @@ void test_eARPProcessPacket_Request_GratuitousARP( void ) /* =================================================== */ } +/** + * @brief This function verify receiving Gratuitous ARP packet + * and updating the ARP cache with respect to the new ARP request + * where there is no change in the MAC address compared to what is present + * in the ARP cache. + */ void test_eARPProcessPacket_Request_GratuitousARP_MACUnchanged( void ) { ARPPacket_t xARPFrame = { 0 }; @@ -810,6 +820,12 @@ void test_eARPProcessPacket_Request_GratuitousARP_MACUnchanged( void ) /* =================================================== */ } +/** + * @brief This function verify receiving Gratuitous ARP packet + * but the packet is received in a different endpoint compared + * to the entry present in the ARP cache. Hence its supposed to + * be not updated in the ARP cache. + */ void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingEndpoint( void ) { ARPPacket_t xARPFrame = { 0 }; @@ -868,6 +884,11 @@ void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingEndpoint( void ) /* =================================================== */ } +/** + * @brief This function verify receiving Gratuitous ARP packet + * but the ARP cache doesn't have an entry for the IP in the + * ARP request. + */ void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingIP( void ) { ARPPacket_t xARPFrame = { 0 };