Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions source/FreeRTOS_ARP.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetw
const IPPacket_t * pxIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
const IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );

if( ( pxIPHeader->ulSourceIPAddress & xNetworkAddressing.ulNetMask ) == ( *ipLOCAL_IP_ADDRESS_POINTER & xNetworkAddressing.ulNetMask ) )
if( ( ( pxIPHeader->ulSourceIPAddress & xNetworkAddressing.ulNetMask ) == ( *ipLOCAL_IP_ADDRESS_POINTER & xNetworkAddressing.ulNetMask ) ) &&
( ( pxIPHeader->ulDestinationIPAddress & ipLOOPBACK_NETMASK ) != ( ipLOOPBACK_ADDRESS & ipLOOPBACK_NETMASK ) ) )
{
/* If the IP is on the same subnet and we do not have an ARP entry already,
* then we should send out ARP for finding the MAC address. */
Expand Down Expand Up @@ -726,7 +727,8 @@ eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress,
* can be done. */
eReturn = eCantSendPacket;
}
else if( *ipLOCAL_IP_ADDRESS_POINTER == *pulIPAddress )
else if( ( *ipLOCAL_IP_ADDRESS_POINTER == *pulIPAddress ) ||
( ( *pulIPAddress & ipLOOPBACK_NETMASK ) == ( ipLOOPBACK_ADDRESS & ipLOOPBACK_NETMASK ) ) )
{
/* The address of this device. May be useful for the loopback device. */
eReturn = eARPCacheHit;
Expand Down
2 changes: 2 additions & 0 deletions source/FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,8 @@ static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPP
else if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
/* Is it the global broadcast address 255.255.255.255 ? */
( ulDestinationIPAddress != ipBROADCAST_IP_ADDRESS ) &&
/* Is it a loopback address ? */
( ( ulDestinationIPAddress & ipLOOPBACK_NETMASK ) != ( ipLOOPBACK_ADDRESS & ipLOOPBACK_NETMASK ) ) &&
/* Is it a specific broadcast address 192.168.1.255 ? */
( ulDestinationIPAddress != xNetworkAddressing.ulBroadcastAddress ) &&
#if ( ipconfigUSE_LLMNR == 1 )
Expand Down
4 changes: 4 additions & 0 deletions source/include/FreeRTOS_IP_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ extern const BaseType_t xBufferAllocFixedSize;
* rather than duplicated in its own variable. */
#define ipLOCAL_MAC_ADDRESS ( xDefaultPartUDPPacketHeader.ucBytes )

/* The loopback address block is defined as part of rfc5735 */
#define ipLOOPBACK_ADDRESS ( FreeRTOS_inet_addr_quick( 127, 0, 0, 0 ) )
#define ipLOOPBACK_NETMASK ( FreeRTOS_inet_addr_quick( 255, 0, 0, 0 ) )

/* ICMP packets are sent using the same function as UDP packets. The port
* number is used to distinguish between the two, as 0 is an invalid UDP port. */
#define ipPACKET_CONTAINS_ICMP_DATA ( 0 )
Expand Down
40 changes: 40 additions & 0 deletions test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,29 @@ void test_xCheckRequiresARPResolution_OnLocalNetwork_InCache( void )
TEST_ASSERT_EQUAL( pdFALSE, xResult );
}

void test_xCheckRequiresARPResolution_OnLocalNetwork_Loopback( void )
{
NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer;
uint8_t ucEthernetBuffer[ ipconfigNETWORK_MTU ];
BaseType_t xResult;

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer;

IPPacket_t * pxIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );

*ipLOCAL_IP_ADDRESS_POINTER = ipLOOPBACK_ADDRESS;

/* Make sure there is a match on source IP and loopback address */
pxIPHeader->ulDestinationIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER & xNetworkAddressing.ulNetMask;

xResult = xCheckRequiresARPResolution( pxNetworkBuffer );

TEST_ASSERT_EQUAL( pdFALSE, xResult );
}


void test_ulARPRemoveCacheEntryByMac_NoMatch( void )
{
Expand Down Expand Up @@ -1322,6 +1345,23 @@ void test_eARPGetCacheEntry_IPMatchesOtherBroadcastAddr( void )
/* =================================================== */
}

void test_eARPGetCacheEntry_IPMatchesLoopbackAddr( void )
{
uint32_t ulIPAddress;
MACAddress_t xMACAddress;
eARPLookupResult_t eResult;
uint32_t ulSavedGatewayAddress;

/* =================================================== */
ulIPAddress = ipLOOPBACK_ADDRESS;
/* Not worried about what these functions do. */
xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL );
eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
TEST_ASSERT_EQUAL_MESSAGE( eARPCacheHit, eResult, "Test 3" );
TEST_ASSERT_EQUAL_MEMORY_MESSAGE( &ipLOCAL_MAC_ADDRESS, &xMACAddress, sizeof( xMACAddress ), "Test 3" );
/* =================================================== */
}

void test_eARPGetCacheEntry_LocalIPIsZero( void )
{
uint32_t ulIPAddress;
Expand Down
35 changes: 35 additions & 0 deletions test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -2249,6 +2249,41 @@ void test_prvAllowIPPacket_IncorrectProtocolChecksum( void )
TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}

void test_prvAllowIPPacket_LoopbackDest( void )
{
eFrameProcessingResult_t eResult;
IPPacket_t * pxIPPacket;
NetworkBufferDescriptor_t * pxNetworkBuffer, xNetworkBuffer;
UBaseType_t uxHeaderLength = 0;
uint8_t ucEthBuffer[ ipconfigTCP_MSS ];
IPHeader_t * pxIPHeader;

memset( ucEthBuffer, 0, ipconfigTCP_MSS );

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer;
pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
pxIPHeader = &( pxIPPacket->xIPHeader );

*ipLOCAL_IP_ADDRESS_POINTER = 0xFFFFFFFF;

pxIPHeader->ucVersionHeaderLength = 0x45;

pxIPHeader->ulDestinationIPAddress = ipLOOPBACK_ADDRESS;

memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, &ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );

pxIPHeader->ulSourceIPAddress = 0xC0C00101;

usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC );

usGenerateProtocolChecksum_ExpectAndReturn( ( uint8_t * ) ( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE, ipCORRECT_CRC );

eResult = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eProcessBuffer, eResult );
}

void test_prvAllowIPPacket_HappyPath( void )
{
eFrameProcessingResult_t eResult;
Expand Down